Beispiel #1
0
/**
 *	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");
}
Beispiel #2
0
/**
 *	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);
}