| 217 | } |
| 218 | |
| 219 | static int |
| 220 | bcm_dma_init(device_t dev) |
| 221 | { |
| 222 | struct bcm_dma_softc *sc = device_get_softc(dev); |
| 223 | uint32_t reg; |
| 224 | struct bcm_dma_ch *ch; |
| 225 | void *cb_virt; |
| 226 | vm_paddr_t cb_phys; |
| 227 | int err; |
| 228 | int i; |
| 229 | |
| 230 | /* |
| 231 | * Only channels set in bcm_dma_channel_mask can be controlled by us. |
| 232 | * The others are out of our control as well as the corresponding bits |
| 233 | * in both BCM_DMA_ENABLE and BCM_DMA_INT_STATUS global registers. As |
| 234 | * these registers are RW ones, there is no safe way how to write only |
| 235 | * the bits which can be controlled by us. |
| 236 | * |
| 237 | * Fortunately, after reset, all channels are enabled in BCM_DMA_ENABLE |
| 238 | * register and all statuses are cleared in BCM_DMA_INT_STATUS one. |
| 239 | * Not touching these registers is a trade off between correct |
| 240 | * initialization which does not count on anything and not messing up |
| 241 | * something we have no control over. |
| 242 | */ |
| 243 | reg = bus_read_4(sc->sc_mem, BCM_DMA_ENABLE); |
| 244 | if ((reg & bcm_dma_channel_mask) != bcm_dma_channel_mask) |
| 245 | device_printf(dev, "channels are not enabled\n"); |
| 246 | reg = bus_read_4(sc->sc_mem, BCM_DMA_INT_STATUS); |
| 247 | if ((reg & bcm_dma_channel_mask) != 0) |
| 248 | device_printf(dev, "statuses are not cleared\n"); |
| 249 | |
| 250 | /* |
| 251 | * Allocate DMA chunks control blocks based on p.40 of the peripheral |
| 252 | * spec - control block should be 32-bit aligned. The DMA controller |
| 253 | * has a full 32-bit register dedicated to this address, so we do not |
| 254 | * need to bother with the per-SoC peripheral restrictions. |
| 255 | */ |
| 256 | err = bus_dma_tag_create(bus_get_dma_tag(dev), |
| 257 | 1, 0, BUS_SPACE_MAXADDR_32BIT, |
| 258 | BUS_SPACE_MAXADDR, NULL, NULL, |
| 259 | sizeof(struct bcm_dma_cb), 1, |
| 260 | sizeof(struct bcm_dma_cb), |
| 261 | BUS_DMA_ALLOCNOW, NULL, NULL, |
| 262 | &sc->sc_dma_tag); |
| 263 | |
| 264 | if (err) { |
| 265 | device_printf(dev, "failed allocate DMA tag\n"); |
| 266 | return (err); |
| 267 | } |
| 268 | |
| 269 | /* setup initial settings */ |
| 270 | for (i = 0; i < BCM_DMA_CH_MAX; i++) { |
| 271 | ch = &sc->sc_dma_ch[i]; |
| 272 | |
| 273 | bzero(ch, sizeof(struct bcm_dma_ch)); |
| 274 | ch->ch = i; |
| 275 | ch->flags = BCM_DMA_CH_UNMAP; |
| 276 |
no test coverage detected