Refactor bcm2835_cpufreq to use bcm2835_mbox_property API
This commit is contained in:
parent
e597fdb889
commit
cd3903c620
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=290667
@ -115,13 +115,6 @@ struct bcm2835_cpufreq_softc {
|
||||
int voltage_sdram_p;
|
||||
int turbo_mode;
|
||||
|
||||
/* mbox buffer (physical address) */
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
bus_size_t dma_size;
|
||||
void *dma_buf;
|
||||
bus_addr_t dma_phys;
|
||||
|
||||
/* initial hook for waiting mbox intr */
|
||||
struct intr_config_hook init_hook;
|
||||
};
|
||||
@ -150,85 +143,11 @@ bcm2835_dump(const void *data, int len)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc)
|
||||
{
|
||||
struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf;
|
||||
struct bcm2835_mbox_tag_hdr *tag, *last;
|
||||
uint8_t *up;
|
||||
device_t mbox;
|
||||
size_t hdr_size;
|
||||
int idx;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* For multiple calls, locking is not here. The caller must have
|
||||
* VC semaphore.
|
||||
*/
|
||||
|
||||
/* get mbox device */
|
||||
mbox = devclass_get_device(devclass_find("mbox"), 0);
|
||||
if (mbox == NULL) {
|
||||
device_printf(sc->dev, "can't find mbox\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* go mailbox property */
|
||||
#ifdef PROP_DEBUG
|
||||
bcm2835_dump(msg, 64);
|
||||
#endif
|
||||
bus_dmamap_sync(sc->dma_tag, sc->dma_map,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)sc->dma_phys);
|
||||
MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &err);
|
||||
bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD);
|
||||
#ifdef PROP_DEBUG
|
||||
bcm2835_dump(msg, 64);
|
||||
#endif
|
||||
|
||||
/* check response code */
|
||||
if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
|
||||
device_printf(sc->dev, "mbox response error\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* tag = first tag */
|
||||
up = (uint8_t *)msg;
|
||||
hdr_size = sizeof(struct bcm2835_mbox_hdr);
|
||||
tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size);
|
||||
/* last = end of buffer specified by header */
|
||||
last = (struct bcm2835_mbox_tag_hdr *)(up + msg->buf_size);
|
||||
|
||||
/* loop unitl end tag (=0x0) */
|
||||
hdr_size = sizeof(struct bcm2835_mbox_tag_hdr);
|
||||
for (idx = 0; tag->tag != 0; idx++) {
|
||||
if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
|
||||
device_printf(sc->dev, "tag%d response error\n", idx);
|
||||
return (-1);
|
||||
}
|
||||
/* clear response bit */
|
||||
tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
|
||||
|
||||
/* get next tag */
|
||||
up = (uint8_t *)tag;
|
||||
tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size +
|
||||
tag->val_buf_size);
|
||||
|
||||
/* check buffer size of header */
|
||||
if (tag > last) {
|
||||
device_printf(sc->dev, "mbox buffer size error\n");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t clock_id)
|
||||
{
|
||||
struct msg_get_clock_rate *msg;
|
||||
struct msg_get_clock_rate msg;
|
||||
int rate;
|
||||
int err;
|
||||
|
||||
@ -246,26 +165,18 @@ bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: rate (in Hz)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_clock_rate *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.clock_id = clock_id;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.clock_id = clock_id;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get clock rate (id=%u)\n",
|
||||
clock_id);
|
||||
@ -273,7 +184,7 @@ bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
}
|
||||
|
||||
/* result (Hz) */
|
||||
rate = (int)msg->body.resp.rate_hz;
|
||||
rate = (int)msg.body.resp.rate_hz;
|
||||
DPRINTF("clock = %d(Hz)\n", rate);
|
||||
return (rate);
|
||||
}
|
||||
@ -282,7 +193,7 @@ static int
|
||||
bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t clock_id)
|
||||
{
|
||||
struct msg_get_max_clock_rate *msg;
|
||||
struct msg_get_max_clock_rate msg;
|
||||
int rate;
|
||||
int err;
|
||||
|
||||
@ -300,26 +211,18 @@ bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: rate (in Hz)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_max_clock_rate *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.clock_id = clock_id;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.clock_id = clock_id;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get max clock rate (id=%u)\n",
|
||||
clock_id);
|
||||
@ -327,7 +230,7 @@ bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
}
|
||||
|
||||
/* result (Hz) */
|
||||
rate = (int)msg->body.resp.rate_hz;
|
||||
rate = (int)msg.body.resp.rate_hz;
|
||||
DPRINTF("clock = %d(Hz)\n", rate);
|
||||
return (rate);
|
||||
}
|
||||
@ -336,7 +239,7 @@ static int
|
||||
bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t clock_id)
|
||||
{
|
||||
struct msg_get_min_clock_rate *msg;
|
||||
struct msg_get_min_clock_rate msg;
|
||||
int rate;
|
||||
int err;
|
||||
|
||||
@ -354,26 +257,18 @@ bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: rate (in Hz)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_min_clock_rate *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.clock_id = clock_id;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.clock_id = clock_id;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get min clock rate (id=%u)\n",
|
||||
clock_id);
|
||||
@ -381,7 +276,7 @@ bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
}
|
||||
|
||||
/* result (Hz) */
|
||||
rate = (int)msg->body.resp.rate_hz;
|
||||
rate = (int)msg.body.resp.rate_hz;
|
||||
DPRINTF("clock = %d(Hz)\n", rate);
|
||||
return (rate);
|
||||
}
|
||||
@ -390,7 +285,7 @@ static int
|
||||
bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t clock_id, uint32_t rate_hz)
|
||||
{
|
||||
struct msg_set_clock_rate *msg;
|
||||
struct msg_set_clock_rate msg;
|
||||
int rate;
|
||||
int err;
|
||||
|
||||
@ -409,27 +304,19 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: rate (in Hz)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_set_clock_rate *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.clock_id = clock_id;
|
||||
msg->body.req.rate_hz = rate_hz;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.clock_id = clock_id;
|
||||
msg.body.req.rate_hz = rate_hz;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't set clock rate (id=%u)\n",
|
||||
clock_id);
|
||||
@ -447,18 +334,18 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
*/
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.clock_id = clock_id;
|
||||
msg->body.req.rate_hz = rate_hz;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.clock_id = clock_id;
|
||||
msg.body.req.rate_hz = rate_hz;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev,
|
||||
"can't set clock rate (id=%u)\n", clock_id);
|
||||
@ -467,7 +354,7 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
}
|
||||
|
||||
/* result (Hz) */
|
||||
rate = (int)msg->body.resp.rate_hz;
|
||||
rate = (int)msg.body.resp.rate_hz;
|
||||
DPRINTF("clock = %d(Hz)\n", rate);
|
||||
return (rate);
|
||||
}
|
||||
@ -475,7 +362,7 @@ bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
|
||||
static int
|
||||
bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
|
||||
{
|
||||
struct msg_get_turbo *msg;
|
||||
struct msg_get_turbo msg;
|
||||
int level;
|
||||
int err;
|
||||
|
||||
@ -493,33 +380,25 @@ bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
|
||||
* u32: level
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_turbo *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.id = 0;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.id = 0;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get turbo\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result 0=non-turbo, 1=turbo */
|
||||
level = (int)msg->body.resp.level;
|
||||
level = (int)msg.body.resp.level;
|
||||
DPRINTF("level = %d\n", level);
|
||||
return (level);
|
||||
}
|
||||
@ -527,7 +406,7 @@ bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
|
||||
static int
|
||||
bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
|
||||
{
|
||||
struct msg_set_turbo *msg;
|
||||
struct msg_set_turbo msg;
|
||||
int value;
|
||||
int err;
|
||||
|
||||
@ -546,38 +425,30 @@ bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
|
||||
* u32: level
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_set_turbo *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* replace unknown value to OFF */
|
||||
if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF)
|
||||
level = BCM2835_MBOX_TURBO_OFF;
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.id = 0;
|
||||
msg->body.req.level = level;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.id = 0;
|
||||
msg.body.req.level = level;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't set turbo\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result 0=non-turbo, 1=turbo */
|
||||
value = (int)msg->body.resp.level;
|
||||
value = (int)msg.body.resp.level;
|
||||
DPRINTF("level = %d\n", value);
|
||||
return (value);
|
||||
}
|
||||
@ -586,7 +457,7 @@ static int
|
||||
bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t voltage_id)
|
||||
{
|
||||
struct msg_get_voltage *msg;
|
||||
struct msg_get_voltage msg;
|
||||
int value;
|
||||
int err;
|
||||
|
||||
@ -604,33 +475,25 @@ bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: value (offset from 1.2V in units of 0.025V)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_voltage *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.voltage_id = voltage_id;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.voltage_id = voltage_id;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get voltage\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result (offset from 1.2V) */
|
||||
value = (int)msg->body.resp.value;
|
||||
value = (int)msg.body.resp.value;
|
||||
DPRINTF("value = %d\n", value);
|
||||
return (value);
|
||||
}
|
||||
@ -639,7 +502,7 @@ static int
|
||||
bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t voltage_id)
|
||||
{
|
||||
struct msg_get_max_voltage *msg;
|
||||
struct msg_get_max_voltage msg;
|
||||
int value;
|
||||
int err;
|
||||
|
||||
@ -657,33 +520,25 @@ bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: value (offset from 1.2V in units of 0.025V)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_max_voltage *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.voltage_id = voltage_id;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.voltage_id = voltage_id;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get max voltage\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result (offset from 1.2V) */
|
||||
value = (int)msg->body.resp.value;
|
||||
value = (int)msg.body.resp.value;
|
||||
DPRINTF("value = %d\n", value);
|
||||
return (value);
|
||||
}
|
||||
@ -691,7 +546,7 @@ static int
|
||||
bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t voltage_id)
|
||||
{
|
||||
struct msg_get_min_voltage *msg;
|
||||
struct msg_get_min_voltage msg;
|
||||
int value;
|
||||
int err;
|
||||
|
||||
@ -709,33 +564,25 @@ bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
* u32: value (offset from 1.2V in units of 0.025V)
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_min_voltage *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.voltage_id = voltage_id;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.voltage_id = voltage_id;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get min voltage\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result (offset from 1.2V) */
|
||||
value = (int)msg->body.resp.value;
|
||||
value = (int)msg.body.resp.value;
|
||||
DPRINTF("value = %d\n", value);
|
||||
return (value);
|
||||
}
|
||||
@ -744,7 +591,7 @@ static int
|
||||
bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
uint32_t voltage_id, int32_t value)
|
||||
{
|
||||
struct msg_set_voltage *msg;
|
||||
struct msg_set_voltage msg;
|
||||
int err;
|
||||
|
||||
/*
|
||||
@ -773,34 +620,26 @@ bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_set_voltage *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.voltage_id = voltage_id;
|
||||
msg->body.req.value = (uint32_t)value;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.voltage_id = voltage_id;
|
||||
msg.body.req.value = (uint32_t)value;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't set voltage\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result (offset from 1.2V) */
|
||||
value = (int)msg->body.resp.value;
|
||||
value = (int)msg.body.resp.value;
|
||||
DPRINTF("value = %d\n", value);
|
||||
return (value);
|
||||
}
|
||||
@ -808,7 +647,7 @@ bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
|
||||
static int
|
||||
bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
|
||||
{
|
||||
struct msg_get_temperature *msg;
|
||||
struct msg_get_temperature msg;
|
||||
int value;
|
||||
int err;
|
||||
|
||||
@ -826,33 +665,25 @@ bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
|
||||
* u32: value
|
||||
*/
|
||||
|
||||
/* using DMA buffer for VC */
|
||||
msg = (struct msg_get_temperature *)sc->dma_buf;
|
||||
if (sizeof(*msg) > sc->dma_size) {
|
||||
device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
|
||||
sizeof(*msg), sc->dma_size);
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* setup single tag buffer */
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
msg->hdr.buf_size = sizeof(*msg);
|
||||
msg->hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
|
||||
msg->tag_hdr.val_buf_size = sizeof(msg->body);
|
||||
msg->tag_hdr.val_len = sizeof(msg->body.req);
|
||||
msg->body.req.temperature_id = 0;
|
||||
msg->end_tag = 0;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.buf_size = sizeof(msg);
|
||||
msg.hdr.code = BCM2835_MBOX_CODE_REQ;
|
||||
msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
|
||||
msg.tag_hdr.val_buf_size = sizeof(msg.body);
|
||||
msg.tag_hdr.val_len = sizeof(msg.body.req);
|
||||
msg.body.req.temperature_id = 0;
|
||||
msg.end_tag = 0;
|
||||
|
||||
/* call mailbox property */
|
||||
err = bcm2835_mbox_call_prop(sc);
|
||||
err = bcm2835_mbox_property(&msg, sizeof(msg));
|
||||
if (err) {
|
||||
device_printf(sc->dev, "can't get temperature\n");
|
||||
return (MSG_ERROR);
|
||||
}
|
||||
|
||||
/* result (temperature of degree C) */
|
||||
value = (int)msg->body.resp.value;
|
||||
value = (int)msg.body.resp.value;
|
||||
DPRINTF("value = %d\n", value);
|
||||
return (value);
|
||||
}
|
||||
@ -1432,23 +1263,11 @@ bcm2835_cpufreq_probe(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
bcm2835_cpufreq_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
|
||||
{
|
||||
bus_addr_t *addr;
|
||||
|
||||
if (err)
|
||||
return;
|
||||
addr = (bus_addr_t *)arg;
|
||||
*addr = PHYS_TO_VCBUS(segs[0].ds_addr);
|
||||
}
|
||||
|
||||
static int
|
||||
bcm2835_cpufreq_attach(device_t dev)
|
||||
{
|
||||
struct bcm2835_cpufreq_softc *sc;
|
||||
struct sysctl_oid *oid;
|
||||
int err;
|
||||
|
||||
/* set self dev */
|
||||
sc = device_get_softc(dev);
|
||||
@ -1464,41 +1283,6 @@ bcm2835_cpufreq_attach(device_t dev)
|
||||
sc->max_voltage_core = 0;
|
||||
sc->min_voltage_core = 0;
|
||||
|
||||
/* create VC mbox buffer */
|
||||
sc->dma_size = PAGE_SIZE;
|
||||
err = bus_dma_tag_create(
|
||||
bus_get_dma_tag(sc->dev),
|
||||
PAGE_SIZE, 0, /* alignment, boundary */
|
||||
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
sc->dma_size, 1, /* maxsize, nsegments */
|
||||
sc->dma_size, 0, /* maxsegsize, flags */
|
||||
NULL, NULL, /* lockfunc, lockarg */
|
||||
&sc->dma_tag);
|
||||
if (err) {
|
||||
device_printf(dev, "can't create DMA tag\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
|
||||
&sc->dma_map);
|
||||
if (err) {
|
||||
bus_dma_tag_destroy(sc->dma_tag);
|
||||
device_printf(dev, "can't allocate dmamem\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
|
||||
sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
|
||||
if (err) {
|
||||
bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
|
||||
bus_dma_tag_destroy(sc->dma_tag);
|
||||
device_printf(dev, "can't load DMA map\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
/* OK, ready to use VC buffer */
|
||||
|
||||
/* setup sysctl at first device */
|
||||
if (device_get_unit(dev) == 0) {
|
||||
sysctl_ctx_init(&bcm2835_sysctl_ctx);
|
||||
@ -1568,9 +1352,6 @@ bcm2835_cpufreq_attach(device_t dev)
|
||||
sc->init_hook.ich_arg = sc;
|
||||
|
||||
if (config_intrhook_establish(&sc->init_hook) != 0) {
|
||||
bus_dmamap_unload(sc->dma_tag, sc->dma_map);
|
||||
bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
|
||||
bus_dma_tag_destroy(sc->dma_tag);
|
||||
device_printf(dev, "config_intrhook_establish failed\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -1590,13 +1371,6 @@ bcm2835_cpufreq_detach(device_t dev)
|
||||
|
||||
sema_destroy(&vc_sema);
|
||||
|
||||
if (sc->dma_phys != 0)
|
||||
bus_dmamap_unload(sc->dma_tag, sc->dma_map);
|
||||
if (sc->dma_buf != NULL)
|
||||
bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
|
||||
if (sc->dma_tag != NULL)
|
||||
bus_dma_tag_destroy(sc->dma_tag);
|
||||
|
||||
return (cpufreq_unregister(dev));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user