diff options
author | gonzo <gonzo@FreeBSD.org> | 2015-11-05 03:46:54 +0000 |
---|---|---|
committer | gonzo <gonzo@FreeBSD.org> | 2015-11-05 03:46:54 +0000 |
commit | 78d6847e56d1422edc231a9f97133ef7f33727e4 (patch) | |
tree | 81d2349672dff80657d81c01f912225ebb8d687a | |
parent | 8ee41c789469d07bc426a8421b278a48c35ba1a8 (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_fbd.c | 8 | ||||
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_mbox.c | 278 | ||||
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h | 10 | ||||
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_sdhci.c | 4 | ||||
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c | 6 |
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, ®); + 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, ®); - 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, ®); - 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, ®); - 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)); } |