diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/bfin_sdh.c | 68 | 
1 files changed, 52 insertions, 16 deletions
| diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 81d8e5432..26311741f 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -19,9 +19,7 @@  #include <asm/mach-common/bits/sdh.h>  #include <asm/mach-common/bits/dma.h> -#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) -# define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CONTROL -# define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CONTROL +#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF60x__)  # define bfin_read_SDH_CLK_CTL		bfin_read_RSI_CLK_CONTROL  # define bfin_write_SDH_CLK_CTL		bfin_write_RSI_CLK_CONTROL  # define bfin_write_SDH_ARGUMENT	bfin_write_RSI_ARGUMENT @@ -38,10 +36,21 @@  # define bfin_write_SDH_STATUS_CLR 	bfin_write_RSI_STATUSCL  # define bfin_read_SDH_CFG		bfin_read_RSI_CONFIG  # define bfin_write_SDH_CFG		bfin_write_RSI_CONFIG +# if defined(__ADSPBF60x__) +# define bfin_read_SDH_BLK_SIZE		bfin_read_RSI_BLKSZ +# define bfin_write_SDH_BLK_SIZE	bfin_write_RSI_BLKSZ +# define bfin_write_DMA_START_ADDR	bfin_write_DMA10_START_ADDR +# define bfin_write_DMA_X_COUNT		bfin_write_DMA10_X_COUNT +# define bfin_write_DMA_X_MODIFY	bfin_write_DMA10_X_MODIFY +# define bfin_write_DMA_CONFIG		bfin_write_DMA10_CONFIG +# else +# define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CONTROL +# define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CONTROL  # define bfin_write_DMA_START_ADDR	bfin_write_DMA4_START_ADDR  # define bfin_write_DMA_X_COUNT		bfin_write_DMA4_X_COUNT  # define bfin_write_DMA_X_MODIFY	bfin_write_DMA4_X_MODIFY  # define bfin_write_DMA_CONFIG		bfin_write_DMA4_CONFIG +# endif  # define PORTMUX_PINS \  	{ P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 }  #elif defined(__ADSPBF54x__) @@ -70,6 +79,9 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)  		sdh_cmd |= CMD_RSP;  	if (flags & MMC_RSP_136)  		sdh_cmd |= CMD_L_RSP; +#ifdef RSI_BLKSZ +	sdh_cmd |= CMD_DATA0_BUSY; +#endif  	bfin_write_SDH_ARGUMENT(arg);  	bfin_write_SDH_COMMAND(sdh_cmd); @@ -104,6 +116,12 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)  	bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT |  				CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); +#ifdef RSI_BLKSZ +	/* wait till card ready */ +	while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY)) +		continue; +	bfin_write_RSI_ESTAT(SD_CARD_READY); +#endif  	return ret;  } @@ -113,16 +131,19 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)  {  	u16 data_ctl = 0;  	u16 dma_cfg = 0; -	int ret = 0;  	unsigned long data_size = data->blocksize * data->blocks;  	/* Don't support write yet. */  	if (data->flags & MMC_DATA_WRITE)  		return UNUSABLE_ERR; +#ifndef RSI_BLKSZ  	data_ctl |= ((ffs(data_size) - 1) << 4); +#else +	bfin_write_SDH_BLK_SIZE(data_size); +#endif  	data_ctl |= DTX_DIR;  	bfin_write_SDH_DATA_CTL(data_ctl); -	dma_cfg = WDSIZE_32 | RESTART | WNR | DMAEN; +	dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN;  	bfin_write_SDH_DATA_TIMER(-1); @@ -137,7 +158,7 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data)  	/* kick off transfer */  	bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); -	return ret; +	return 0;  } @@ -147,13 +168,23 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd,  	u32 status;  	int ret = 0; +	if (data) { +		ret = sdh_setup_data(mmc, data); +		if (ret) +			return ret; +	} +  	ret = sdh_send_cmd(mmc, cmd);  	if (ret) { +		bfin_write_SDH_COMMAND(0); +		bfin_write_DMA_CONFIG(0); +		bfin_write_SDH_DATA_CTL(0); +		SSYNC();  		printf("sending CMD%d failed\n", cmd->cmdidx);  		return ret;  	} +  	if (data) { -		ret = sdh_setup_data(mmc, data);  		do {  			udelay(1);  			status = bfin_read_SDH_STATUS(); @@ -208,10 +239,12 @@ static void bfin_sdh_set_ios(struct mmc *mmc)  	if (mmc->bus_width == 4) {  		cfg = bfin_read_SDH_CFG(); -		cfg &= ~0x80; -		cfg |= 0x40; +#ifndef RSI_BLKSZ +		cfg &= ~PD_SDDAT3; +#endif +		cfg |= PUP_SDDAT3;  		bfin_write_SDH_CFG(cfg); -		clk_ctl |= WIDE_BUS; +		clk_ctl |= WIDE_BUS_4;  	}  	bfin_write_SDH_CLK_CTL(clk_ctl);  	sdh_set_clk(mmc->clock); @@ -220,20 +253,23 @@ static void bfin_sdh_set_ios(struct mmc *mmc)  static int bfin_sdh_init(struct mmc *mmc)  {  	const unsigned short pins[] = PORTMUX_PINS; -	u16 pwr_ctl = 0; +	int ret;  	/* Initialize sdh controller */ -	peripheral_request_list(pins, "bfin_sdh"); +	ret = peripheral_request_list(pins, "bfin_sdh"); +	if (ret < 0) +		return ret;  #if defined(__ADSPBF54x__)  	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);  #endif  	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);  	/* Disable card detect pin */  	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60); - -	pwr_ctl |= ROD_CTL; -	pwr_ctl |= PWR_ON; -	bfin_write_SDH_PWR_CTL(pwr_ctl); +#ifndef RSI_BLKSZ +	bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL); +#else +	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON); +#endif  	return 0;  } |