/** * ti_mmchs_reset_controller - * @arg: caller supplied arg * @segs: array of segments (although in our case should only be one) * @nsegs: number of segments (in our case should be 1) * @error: * * * */ static void ti_mmchs_reset_controller(struct ti_mmchs_softc *sc, uint32_t bit) { unsigned long attempts; uint32_t sysctl; ti_mmchs_dbg(sc, "reseting controller - bit 0x%08x\n", bit); sysctl = ti_mmchs_read_4(sc, MMCHS_SYSCTL); ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl | bit); /* * AM335x and OMAP4 >= ES2 have an updated reset logic. * Monitor a 0->1 transition first. */ if ((ti_chip() == CHIP_AM335X) || ((ti_chip() == CHIP_OMAP_4) && (ti_revision() > OMAP4430_REV_ES1_0))) { attempts = 10000; while (!(ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0)) continue; } attempts = 10000; while ((ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0)) continue; if (ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) device_printf(sc->sc_dev, "Error - Timeout waiting on controller reset\n"); }
/** * ti_mmchs_init_dma_channels - initalise the DMA channels * @sc: driver soft context * * Attempts to activate an RX and TX DMA channel for the MMC device. * * LOCKING: * No locking, assumed to be called during tear-down/reset. * * RETURNS: * 0 on success, a negative error code on failure. */ static int ti_mmchs_init_dma_channels(struct ti_mmchs_softc *sc) { int err; int unit; uint32_t rev; int dma_rx_trig = -1; int dma_tx_trig = -1; /* Get the device unit number, needed for getting the DMA trigger number */ unit = device_get_unit(sc->sc_dev); /* Get the current chip revision */ rev = ti_revision(); if ((OMAP_REV_DEVICE(rev) != OMAP4430_DEV) && (unit > 2)) return(-EINVAL); /* Get the DMA MMC triggers */ switch (unit) { case 0: dma_tx_trig = 60; dma_rx_trig = 61; break; case 1: dma_tx_trig = 46; dma_rx_trig = 47; break; case 2: dma_tx_trig = 76; dma_rx_trig = 77; break; /* The following are OMAP4 only */ case 3: dma_tx_trig = 56; dma_rx_trig = 57; break; case 4: dma_tx_trig = 58; dma_rx_trig = 59; break; default: return(-EINVAL); } /* Activate a RX channel from the OMAP DMA driver */ err = ti_sdma_activate_channel(&sc->sc_dmach_rd, ti_mmchs_dma_intr, sc); if (err != 0) return(err); /* Setup the RX channel for MMC data transfers */ ti_sdma_set_xfer_burst(sc->sc_dmach_rd, TI_SDMA_BURST_NONE, TI_SDMA_BURST_64); ti_sdma_set_xfer_data_type(sc->sc_dmach_rd, TI_SDMA_DATA_32BITS_SCALAR); ti_sdma_sync_params(sc->sc_dmach_rd, dma_rx_trig, TI_SDMA_SYNC_PACKET | TI_SDMA_SYNC_TRIG_ON_SRC); ti_sdma_set_addr_mode(sc->sc_dmach_rd, TI_SDMA_ADDR_CONSTANT, TI_SDMA_ADDR_POST_INCREMENT); /* Activate and configure the TX DMA channel */ err = ti_sdma_activate_channel(&sc->sc_dmach_wr, ti_mmchs_dma_intr, sc); if (err != 0) return(err); /* Setup the TX channel for MMC data transfers */ ti_sdma_set_xfer_burst(sc->sc_dmach_wr, TI_SDMA_BURST_64, TI_SDMA_BURST_NONE); ti_sdma_set_xfer_data_type(sc->sc_dmach_wr, TI_SDMA_DATA_32BITS_SCALAR); ti_sdma_sync_params(sc->sc_dmach_wr, dma_tx_trig, TI_SDMA_SYNC_PACKET | TI_SDMA_SYNC_TRIG_ON_DST); ti_sdma_set_addr_mode(sc->sc_dmach_wr, TI_SDMA_ADDR_POST_INCREMENT, TI_SDMA_ADDR_CONSTANT); return(0); }