diff options
Diffstat (limited to 'drivers/mmc/gen_atmel_mci.c')
| -rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 42 | 
1 files changed, 38 insertions, 4 deletions
| diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 70a9f91c8..fc0a18123 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -50,6 +50,12 @@  static int initialized = 0; +/* Read Atmel MCI IP version */ +static unsigned int atmel_mci_get_version(struct atmel_mci *mci) +{ +	return readl(&mci->version) & 0x00000fff; +} +  /*   * Print command and status:   * @@ -297,7 +303,9 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)  static void mci_set_ios(struct mmc *mmc)  {  	atmel_mci_t *mci = (atmel_mci_t *)mmc->priv; -	int busw = (mmc->bus_width == 4) ? 1 : 0; +	int bus_width = mmc->bus_width; +	unsigned int version = atmel_mci_get_version(mci); +	int busw;  	/* Set the clock speed */  	mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN); @@ -305,9 +313,26 @@ static void mci_set_ios(struct mmc *mmc)  	/*  	 * set the bus width and select slot for this interface  	 * there is no capability for multiple slots on the same interface yet -	 * Bitfield SCDBUS needs to be expanded to 2 bits for 8-bit buses  	 */ -	writel(MMCI_BF(SCDBUS, busw) | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); +	if ((version & 0xf00) >= 0x300) { +		switch (bus_width) { +		case 8: +			busw = 3; +			break; +		case 4: +			busw = 2; +			break; +		default: +			busw = 0; +			break; +		} + +		writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); +	} else { +		busw = (bus_width == 4) ? 1 : 0; + +		writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); +	}  }  /* Entered into mmc structure during driver init */ @@ -340,9 +365,12 @@ static int mci_init(struct mmc *mmc)  int atmel_mci_init(void *regs)  {  	struct mmc *mmc = malloc(sizeof(struct mmc)); +	struct atmel_mci *mci; +	unsigned int version;  	if (!mmc)  		return -1; +  	strcpy(mmc->name, "mci");  	mmc->priv = regs;  	mmc->send_cmd = mci_send_cmd; @@ -353,7 +381,13 @@ int atmel_mci_init(void *regs)  	/* need to be able to pass these in on a board by board basis */  	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; -	mmc->host_caps = MMC_MODE_4BIT; +	mci = (struct atmel_mci *)mmc->priv; +	version = atmel_mci_get_version(mci); +	if ((version & 0xf00) >= 0x300) +		mmc->host_caps = MMC_MODE_8BIT; + +	mmc->host_caps |= MMC_MODE_4BIT; +  	/*  	 * min and max frequencies determined by  	 * max and min of clock divider |