diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 47 | ||||
| -rw-r--r-- | drivers/mmc/mxsmmc.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/omap_hsmmc.c | 8 | ||||
| -rw-r--r-- | drivers/mmc/zynq_sdhci.c | 40 | 
5 files changed, 88 insertions, 10 deletions
| diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2b581781d..24648a293 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -47,6 +47,7 @@ COBJS-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o  COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o  COBJS-$(CONFIG_DWMMC) += dw_mmc.o  COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o +COBJS-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o  COBJS	:= $(COBJS-y)  SRCS	:= $(COBJS:.o=.c) diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 70a9f91c8..77ebf174f 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:   * @@ -205,7 +211,10 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)  	/* Wait for the command to complete */  	while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY))); -	if (status & error_flags) { +	if ((status & error_flags) & MMCI_BIT(RTOE)) { +		dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out"); +		return TIMEOUT; +	} else if (status & error_flags) {  		dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");  		return COMM_ERR;  	} @@ -297,7 +306,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 +316,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 +368,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 +384,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 diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index a89660f13..fdaf9c763 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -41,7 +41,7 @@  #include <asm/arch/clock.h>  #include <asm/arch/imx-regs.h>  #include <asm/arch/sys_proto.h> -#include <asm/arch/dma.h> +#include <asm/imx-common/dma.h>  #include <bouncebuf.h>  struct mxsmmc_priv { diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 166744c32..afdfa886e 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -29,7 +29,7 @@  #include <i2c.h>  #include <twl4030.h>  #include <twl6030.h> -#include <twl6035.h> +#include <palmas.h>  #include <asm/gpio.h>  #include <asm/io.h>  #include <asm/arch/mmc_host_def.h> @@ -107,7 +107,7 @@ static void omap4_vmmc_pbias_config(struct mmc *mmc)  }  #endif -#if defined(CONFIG_OMAP54XX) && defined(CONFIG_TWL6035_POWER) +#if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER)  static void omap5_pbias_config(struct mmc *mmc)  {  	u32 value = 0; @@ -117,7 +117,7 @@ static void omap5_pbias_config(struct mmc *mmc)  	value |= SDCARD_BIAS_HIZ_MODE;  	writel(value, (*ctrl)->control_pbias); -	twl6035_mmc1_poweron_ldo(); +	palmas_mmc1_poweron_ldo();  	value = readl((*ctrl)->control_pbias);  	value &= ~SDCARD_BIAS_HIZ_MODE; @@ -178,7 +178,7 @@ unsigned char mmc_board_init(struct mmc *mmc)  	if (mmc->block_dev.dev == 0)  		omap4_vmmc_pbias_config(mmc);  #endif -#if defined(CONFIG_OMAP54XX) && defined(CONFIG_TWL6035_POWER) +#if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER)  	if (mmc->block_dev.dev == 0)  		omap5_pbias_config(mmc);  #endif diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c new file mode 100644 index 000000000..9e37af45f --- /dev/null +++ b/drivers/mmc/zynq_sdhci.c @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2013 Inc. + * + * Xilinx Zynq SD Host Controller Interface + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA  02111-1307  USA + */ + +#include <common.h> +#include <malloc.h> +#include <sdhci.h> +#include <asm/arch/sys_proto.h> + +int zynq_sdhci_init(u32 regbase) +{ +	struct sdhci_host *host = NULL; + +	host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); +	if (!host) { +		printf("zynq_sdhci_init: sdhci_host malloc fail\n"); +		return 1; +	} + +	host->name = "zynq_sdhci"; +	host->ioaddr = (void *)regbase; +	host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD; +	host->version = sdhci_readw(host, SDHCI_HOST_VERSION); + +	host->host_caps = MMC_MODE_HC; + +	add_sdhci(host, 52000000, 52000000 >> 9); +	return 0; +} |