summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2015-11-05 03:46:54 +0000
committergonzo <gonzo@FreeBSD.org>2015-11-05 03:46:54 +0000
commit78d6847e56d1422edc231a9f97133ef7f33727e4 (patch)
tree81d2349672dff80657d81c01f912225ebb8d687a /sys/arm
parent8ee41c789469d07bc426a8421b278a48c35ba1a8 (diff)
downloadFreeBSD-src-78d6847e56d1422edc231a9f97133ef7f33727e4.zip
FreeBSD-src-78d6847e56d1422edc231a9f97133ef7f33727e4.tar.gz
Refactor mailbox property API to make it usable for /dev/vcio driver:
- Add bcm2835_mbox_property for generic property request, it accepts pointer to prepared property chan message and its size, forwards it to MBOX and copies result back - Make all bcm2835_mbox_XXX functions that use property channel go through bcm2835_mbox_property path. Do not accept device_t as an argument, it's not required: all DMA operatiosn should go through mbox device, and all API consumers should report errors on their side.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_fbd.c8
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.c278
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h10
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_sdhci.c4
-rw-r--r--sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c6
5 files changed, 123 insertions, 183 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
index 34a7af8..b47c602 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
@@ -81,7 +81,7 @@ bcm_fb_attach(device_t dev)
{
char bootargs[2048], *n, *p, *v;
device_t fbd;
- int fbswap;
+ int fbswap, err;
phandle_t chosen;
struct bcm2835_fb_config fb;
struct bcmsc_softc *sc;
@@ -89,11 +89,13 @@ bcm_fb_attach(device_t dev)
sc = device_get_softc(dev);
memset(&fb, 0, sizeof(fb));
- if (bcm2835_mbox_fb_get_w_h(dev, &fb) != 0)
+ if (bcm2835_mbox_fb_get_w_h(&fb) != 0)
return (ENXIO);
fb.bpp = FB_DEPTH;
- if (bcm2835_mbox_fb_init(dev, &fb) != 0)
+ if ((err = bcm2835_mbox_fb_init(&fb)) != 0) {
+ device_printf(dev, "bcm2835_mbox_fb_init failed, err=%d\n", err);
return (ENXIO);
+ }
info = malloc(sizeof(struct fb_info), M_DEVBUF, M_WAITOK | M_ZERO);
info->fb_name = device_get_nameunit(dev);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
index 78384eb..dd2bb45 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
@@ -360,230 +360,162 @@ bcm2835_mbox_err(device_t dev, bus_addr_t msg_phys, uint32_t resp_phys,
}
int
-bcm2835_mbox_set_power_state(device_t dev, uint32_t device_id, boolean_t on)
+bcm2835_mbox_property(void *msg, size_t msg_size)
{
- struct msg_set_power_state *msg;
+ struct msg_set_power_state *buf;
bus_dma_tag_t msg_tag;
bus_dmamap_t msg_map;
bus_addr_t msg_phys;
uint32_t reg;
device_t mbox;
+ int err;
/* get mbox device */
mbox = devclass_get_device(devclass_find("mbox"), 0);
- if (mbox == NULL) {
- device_printf(dev, "can't find mbox\n");
+ if (mbox == NULL)
return (ENXIO);
- }
/* Allocate memory for the message */
- msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map,
+ buf = bcm2835_mbox_init_dma(mbox, msg_size, &msg_tag, &msg_map,
&msg_phys);
- if (msg == NULL)
+ if (buf == NULL)
return (ENOMEM);
- 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_POWER_STATE;
- msg->tag_hdr.val_buf_size = sizeof(msg->body);
- msg->tag_hdr.val_len = sizeof(msg->body.req);
- msg->body.req.device_id = device_id;
- msg->body.req.state = (on ? BCM2835_MBOX_POWER_ON : 0) |
- BCM2835_MBOX_POWER_WAIT;
- msg->end_tag = 0;
+ memcpy(buf, msg, msg_size);
bus_dmamap_sync(msg_tag, msg_map,
- BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
+ BUS_DMASYNC_PREWRITE);
MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
+ bus_dmamap_sync(msg_tag, msg_map,
+ BUS_DMASYNC_PREREAD);
+
+ memcpy(msg, buf, msg_size);
+
+ err = bcm2835_mbox_err(mbox, msg_phys, reg,
+ (struct bcm2835_mbox_hdr *)msg, msg_size);
+
bus_dmamap_unload(msg_tag, msg_map);
- bus_dmamem_free(msg_tag, msg, msg_map);
+ bus_dmamem_free(msg_tag, buf, msg_map);
bus_dma_tag_destroy(msg_tag);
- return (0);
+ return (err);
}
int
-bcm2835_mbox_get_clock_rate(device_t dev, uint32_t clock_id, uint32_t *hz)
+bcm2835_mbox_set_power_state(uint32_t device_id, boolean_t on)
{
- struct msg_get_clock_rate *msg;
- bus_dma_tag_t msg_tag;
- bus_dmamap_t msg_map;
- bus_addr_t msg_phys;
- uint32_t reg;
- device_t mbox;
-
- /* get mbox device */
- mbox = devclass_get_device(devclass_find("mbox"), 0);
- if (mbox == NULL) {
- device_printf(dev, "can't find mbox\n");
- return (ENXIO);
- }
-
- /* Allocate memory for the message */
- msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map,
- &msg_phys);
- if (msg == NULL)
- return (ENOMEM);
-
- 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;
-
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE);
- MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE);
-
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD);
- MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD);
+ struct msg_set_power_state msg;
+ int err;
- *hz = msg->body.resp.rate_hz;
+ 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_POWER_STATE;
+ msg.tag_hdr.val_buf_size = sizeof(msg.body);
+ msg.tag_hdr.val_len = sizeof(msg.body.req);
+ msg.body.req.device_id = device_id;
+ msg.body.req.state = (on ? BCM2835_MBOX_POWER_ON : 0) |
+ BCM2835_MBOX_POWER_WAIT;
+ msg.end_tag = 0;
- bus_dmamap_unload(msg_tag, msg_map);
- bus_dmamem_free(msg_tag, msg, msg_map);
- bus_dma_tag_destroy(msg_tag);
+ err = bcm2835_mbox_property(&msg, sizeof(msg));
- return (0);
+ return (err);
}
int
-bcm2835_mbox_fb_get_w_h(device_t dev, struct bcm2835_fb_config *fb)
+bcm2835_mbox_get_clock_rate(uint32_t clock_id, uint32_t *hz)
{
- device_t mbox;
+ struct msg_get_clock_rate msg;
int err;
- bus_dma_tag_t msg_tag;
- bus_dmamap_t msg_map;
- bus_addr_t msg_phys;
- struct msg_fb_get_w_h *msg;
- uint32_t reg;
- /* get mbox device */
- mbox = devclass_get_device(devclass_find("mbox"), 0);
- if (mbox == NULL) {
- device_printf(dev, "can't find mbox\n");
- return (ENXIO);
- }
-
- /* Allocate memory for the message */
- msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map,
- &msg_phys);
- if (msg == NULL)
- return (ENOMEM);
+ 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;
- BCM2835_MBOX_INIT_TAG(&msg->physical_w_h, GET_PHYSICAL_W_H);
- msg->physical_w_h.tag_hdr.val_len = 0;
- BCM2835_MBOX_INIT_TAG(&msg->virtual_w_h, GET_VIRTUAL_W_H);
- msg->virtual_w_h.tag_hdr.val_len = 0;
- BCM2835_MBOX_INIT_TAG(&msg->offset, GET_VIRTUAL_OFFSET);
- msg->offset.tag_hdr.val_len = 0;
- msg->end_tag = 0;
-
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE);
- MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE);
+ err = bcm2835_mbox_property(&msg, sizeof(msg));
+ *hz = msg.body.resp.rate_hz;
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD);
- MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD);
+ return (err);
+}
- err = bcm2835_mbox_err(dev, msg_phys, reg, &msg->hdr, sizeof(*msg));
+int
+bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *fb)
+{
+ int err;
+ struct msg_fb_get_w_h msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.hdr.buf_size = sizeof(msg);
+ msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+ BCM2835_MBOX_INIT_TAG(&msg.physical_w_h, GET_PHYSICAL_W_H);
+ msg.physical_w_h.tag_hdr.val_len = 0;
+ BCM2835_MBOX_INIT_TAG(&msg.virtual_w_h, GET_VIRTUAL_W_H);
+ msg.virtual_w_h.tag_hdr.val_len = 0;
+ BCM2835_MBOX_INIT_TAG(&msg.offset, GET_VIRTUAL_OFFSET);
+ msg.offset.tag_hdr.val_len = 0;
+ msg.end_tag = 0;
+
+ err = bcm2835_mbox_property(&msg, sizeof(msg));
if (err == 0) {
- fb->xres = msg->physical_w_h.body.resp.width;
- fb->yres = msg->physical_w_h.body.resp.height;
- fb->vxres = msg->virtual_w_h.body.resp.width;
- fb->vyres = msg->virtual_w_h.body.resp.height;
- fb->xoffset = msg->offset.body.resp.x;
- fb->yoffset = msg->offset.body.resp.y;
+ fb->xres = msg.physical_w_h.body.resp.width;
+ fb->yres = msg.physical_w_h.body.resp.height;
+ fb->vxres = msg.virtual_w_h.body.resp.width;
+ fb->vyres = msg.virtual_w_h.body.resp.height;
+ fb->xoffset = msg.offset.body.resp.x;
+ fb->yoffset = msg.offset.body.resp.y;
}
- bus_dmamap_unload(msg_tag, msg_map);
- bus_dmamem_free(msg_tag, msg, msg_map);
- bus_dma_tag_destroy(msg_tag);
-
return (err);
}
int
-bcm2835_mbox_fb_init(device_t dev, struct bcm2835_fb_config *fb)
+bcm2835_mbox_fb_init(struct bcm2835_fb_config *fb)
{
- device_t mbox;
int err;
- bus_dma_tag_t msg_tag;
- bus_dmamap_t msg_map;
- bus_addr_t msg_phys;
- struct msg_fb_setup *msg;
- uint32_t reg;
-
- /* get mbox device */
- mbox = devclass_get_device(devclass_find("mbox"), 0);
- if (mbox == NULL) {
- device_printf(dev, "can't find mbox\n");
- return (ENXIO);
- }
-
- /* Allocate memory for the message */
- msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map,
- &msg_phys);
- if (msg == NULL)
- return (ENOMEM);
-
- memset(msg, 0, sizeof(*msg));
- msg->hdr.buf_size = sizeof(*msg);
- msg->hdr.code = BCM2835_MBOX_CODE_REQ;
- BCM2835_MBOX_INIT_TAG(&msg->physical_w_h, SET_PHYSICAL_W_H);
- msg->physical_w_h.body.req.width = fb->xres;
- msg->physical_w_h.body.req.height = fb->yres;
- BCM2835_MBOX_INIT_TAG(&msg->virtual_w_h, SET_VIRTUAL_W_H);
- msg->virtual_w_h.body.req.width = fb->vxres;
- msg->virtual_w_h.body.req.height = fb->vyres;
- BCM2835_MBOX_INIT_TAG(&msg->offset, GET_VIRTUAL_OFFSET);
- msg->offset.body.req.x = fb->xoffset;
- msg->offset.body.req.y = fb->yoffset;
- BCM2835_MBOX_INIT_TAG(&msg->depth, SET_DEPTH);
- msg->depth.body.req.bpp = fb->bpp;
- BCM2835_MBOX_INIT_TAG(&msg->alpha, SET_ALPHA_MODE);
- msg->alpha.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
- BCM2835_MBOX_INIT_TAG(&msg->buffer, ALLOCATE_BUFFER);
- msg->buffer.body.req.alignment = PAGE_SIZE;
- BCM2835_MBOX_INIT_TAG(&msg->pitch, GET_PITCH);
- msg->end_tag = 0;
-
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE);
- MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE);
-
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD);
- MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
- bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD);
-
- err = bcm2835_mbox_err(dev, msg_phys, reg, &msg->hdr, sizeof(*msg));
+ struct msg_fb_setup msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.hdr.buf_size = sizeof(msg);
+ msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+ BCM2835_MBOX_INIT_TAG(&msg.physical_w_h, SET_PHYSICAL_W_H);
+ msg.physical_w_h.body.req.width = fb->xres;
+ msg.physical_w_h.body.req.height = fb->yres;
+ BCM2835_MBOX_INIT_TAG(&msg.virtual_w_h, SET_VIRTUAL_W_H);
+ msg.virtual_w_h.body.req.width = fb->vxres;
+ msg.virtual_w_h.body.req.height = fb->vyres;
+ BCM2835_MBOX_INIT_TAG(&msg.offset, GET_VIRTUAL_OFFSET);
+ msg.offset.body.req.x = fb->xoffset;
+ msg.offset.body.req.y = fb->yoffset;
+ BCM2835_MBOX_INIT_TAG(&msg.depth, SET_DEPTH);
+ msg.depth.body.req.bpp = fb->bpp;
+ BCM2835_MBOX_INIT_TAG(&msg.alpha, SET_ALPHA_MODE);
+ msg.alpha.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
+ BCM2835_MBOX_INIT_TAG(&msg.buffer, ALLOCATE_BUFFER);
+ msg.buffer.body.req.alignment = PAGE_SIZE;
+ BCM2835_MBOX_INIT_TAG(&msg.pitch, GET_PITCH);
+ msg.end_tag = 0;
+
+ err = bcm2835_mbox_property(&msg, sizeof(msg));
if (err == 0) {
- fb->xres = msg->physical_w_h.body.resp.width;
- fb->yres = msg->physical_w_h.body.resp.height;
- fb->vxres = msg->virtual_w_h.body.resp.width;
- fb->vyres = msg->virtual_w_h.body.resp.height;
- fb->xoffset = msg->offset.body.resp.x;
- fb->yoffset = msg->offset.body.resp.y;
- fb->pitch = msg->pitch.body.resp.pitch;
- fb->base = VCBUS_TO_PHYS(msg->buffer.body.resp.fb_address);
- fb->size = msg->buffer.body.resp.fb_size;
+ fb->xres = msg.physical_w_h.body.resp.width;
+ fb->yres = msg.physical_w_h.body.resp.height;
+ fb->vxres = msg.virtual_w_h.body.resp.width;
+ fb->vyres = msg.virtual_w_h.body.resp.height;
+ fb->xoffset = msg.offset.body.resp.x;
+ fb->yoffset = msg.offset.body.resp.y;
+ fb->pitch = msg.pitch.body.resp.pitch;
+ fb->base = VCBUS_TO_PHYS(msg.buffer.body.resp.fb_address);
+ fb->size = msg.buffer.body.resp.fb_size;
}
- bus_dmamap_unload(msg_tag, msg_map);
- bus_dmamem_free(msg_tag, msg, msg_map);
- bus_dma_tag_destroy(msg_tag);
-
return (err);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
index 02d434a..68befef 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
@@ -106,7 +106,7 @@ struct msg_set_power_state {
};
/* Sets the power state for a given device */
-int bcm2835_mbox_set_power_state(device_t, uint32_t, boolean_t);
+int bcm2835_mbox_set_power_state(uint32_t, boolean_t);
#define BCM2835_MBOX_CLOCK_ID_EMMC 0x00000001
#define BCM2835_MBOX_CLOCK_ID_UART 0x00000002
@@ -185,7 +185,7 @@ struct msg_get_min_clock_rate {
uint32_t end_tag;
};
-int bcm2835_mbox_get_clock_rate(device_t, uint32_t, uint32_t *);
+int bcm2835_mbox_get_clock_rate(uint32_t, uint32_t *);
#define BCM2835_MBOX_TURBO_ON 1
#define BCM2835_MBOX_TURBO_OFF 0
@@ -474,7 +474,7 @@ struct msg_fb_get_w_h {
uint32_t end_tag;
};
-int bcm2835_mbox_fb_get_w_h(device_t, struct bcm2835_fb_config *);
+int bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *);
struct msg_fb_setup {
struct bcm2835_mbox_hdr hdr;
@@ -488,6 +488,8 @@ struct msg_fb_setup {
uint32_t end_tag;
};
-int bcm2835_mbox_fb_init(device_t, struct bcm2835_fb_config *);
+int bcm2835_mbox_fb_init(struct bcm2835_fb_config *);
+
+int bcm2835_mbox_property(void *, size_t);
#endif /* _BCM2835_MBOX_PROP_H_ */
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
index 33204ba..ace3d74 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
@@ -145,7 +145,7 @@ bcm_sdhci_attach(device_t dev)
sc->sc_dev = dev;
sc->sc_req = NULL;
- err = bcm2835_mbox_set_power_state(dev, BCM2835_MBOX_POWER_ID_EMMC,
+ err = bcm2835_mbox_set_power_state(BCM2835_MBOX_POWER_ID_EMMC,
TRUE);
if (err != 0) {
if (bootverbose)
@@ -154,7 +154,7 @@ bcm_sdhci_attach(device_t dev)
}
default_freq = 0;
- err = bcm2835_mbox_get_clock_rate(dev, BCM2835_MBOX_CLOCK_ID_EMMC,
+ err = bcm2835_mbox_get_clock_rate(BCM2835_MBOX_CLOCK_ID_EMMC,
&default_freq);
if (err == 0) {
/* Convert to MHz */
diff --git a/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c b/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
index a553fce..75b505c 100644
--- a/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
+++ b/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
@@ -72,8 +72,12 @@ bcm283x_dwc_otg_probe(device_t dev)
static int
bcm283x_dwc_otg_attach(device_t dev)
{
+ int err;
+
+ err = bcm2835_mbox_set_power_state(BCM2835_MBOX_POWER_ID_USB_HCD, TRUE);
+ if (err)
+ device_printf(dev, "failed to set power state, err=%d\n", err);
- bcm2835_mbox_set_power_state(dev, BCM2835_MBOX_POWER_ID_USB_HCD, TRUE);
return (dwc_otg_attach(dev));
}
OpenPOWER on IntegriCloud