diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/omap_hsmmc.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/tegra2_mmc.c | 94 | ||||
| -rw-r--r-- | drivers/mmc/tegra2_mmc.h | 1 | 
3 files changed, 37 insertions, 62 deletions
| diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 5d4cf5110..ebda980fb 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -475,12 +475,16 @@ int omap_mmc_init(int dev_index)  	case 0:  		mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE;  		break; +#ifdef OMAP_HSMMC2_BASE  	case 1:  		mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE;  		break; +#endif +#ifdef OMAP_HSMMC3_BASE  	case 2:  		mmc->priv = (hsmmc_t *)OMAP_HSMMC3_BASE;  		break; +#endif  	default:  		mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE;  		return 1; diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c index 8b6f829e7..9e741f223 100644 --- a/drivers/mmc/tegra2_mmc.c +++ b/drivers/mmc/tegra2_mmc.c @@ -23,36 +23,46 @@  #include <mmc.h>  #include <asm/io.h>  #include <asm/arch/clk_rst.h> +#include <asm/arch/clock.h>  #include "tegra2_mmc.h"  /* support 4 mmc hosts */  struct mmc mmc_dev[4];  struct mmc_host mmc_host[4]; -static inline struct tegra2_mmc *tegra2_get_base_mmc(int dev_index) + +/** + * Get the host address and peripheral ID for a device. Devices are numbered + * from 0 to 3. + * + * @param host		Structure to fill in (base, reg, mmc_id) + * @param dev_index	Device index (0-3) + */ +static void tegra2_get_setup(struct mmc_host *host, int dev_index)  { -	unsigned long offset;  	debug("tegra2_get_base_mmc: dev_index = %d\n", dev_index);  	switch (dev_index) { -	case 0: -		offset = TEGRA2_SDMMC4_BASE; -		break;  	case 1: -		offset = TEGRA2_SDMMC3_BASE; +		host->base = TEGRA2_SDMMC3_BASE; +		host->mmc_id = PERIPH_ID_SDMMC3;  		break;  	case 2: -		offset = TEGRA2_SDMMC2_BASE; +		host->base = TEGRA2_SDMMC2_BASE; +		host->mmc_id = PERIPH_ID_SDMMC2;  		break;  	case 3: -		offset = TEGRA2_SDMMC1_BASE; +		host->base = TEGRA2_SDMMC1_BASE; +		host->mmc_id = PERIPH_ID_SDMMC1;  		break; +	case 0:  	default: -		offset = TEGRA2_SDMMC4_BASE; +		host->base = TEGRA2_SDMMC4_BASE; +		host->mmc_id = PERIPH_ID_SDMMC4;  		break;  	} -	return (struct tegra2_mmc *)(offset); +	host->reg = (struct tegra2_mmc *)host->base;  }  static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data) @@ -274,62 +284,24 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,  static void mmc_change_clock(struct mmc_host *host, uint clock)  { -	int div, hw_div; +	int div;  	unsigned short clk;  	unsigned long timeout; -	unsigned int reg, hostbase; -	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; +  	debug(" mmc_change_clock called\n"); -	/* Change Tegra2 SDMMCx clock divisor here */ -	/* Source is 216MHz, PLLP_OUT0 */ +	/* +	 * Change Tegra2 SDMMCx clock divisor here. Source is 216MHz, +	 * PLLP_OUT0 +	 */  	if (clock == 0)  		goto out; - -	div = 1; -	if (clock <= 400000) { -		hw_div = ((9-1)<<1);		/* Best match is 375KHz */ -		div = 64; -	} else if (clock <= 20000000) -		hw_div = ((11-1)<<1);		/* Best match is 19.6MHz */ -	else if (clock <= 26000000) -		hw_div = ((9-1)<<1);		/* Use 24MHz */ -	else -		hw_div = ((4-1)<<1) + 1;	/* 4.5 divisor for 48MHz */ - -	debug("mmc_change_clock: hw_div = %d, card clock div = %d\n", -		hw_div, div); - -	/* Change SDMMCx divisor */ - -	hostbase = readl(&host->base); -	debug("mmc_change_clock: hostbase = %08X\n", hostbase); - -	if (hostbase == TEGRA2_SDMMC1_BASE) { -		reg = readl(&clkrst->crc_clk_src_sdmmc1); -		reg &= 0xFFFFFF00;	/* divisor (7.1) = 00 */ -		reg |= hw_div;		/* n-1 */ -		writel(reg, &clkrst->crc_clk_src_sdmmc1); -	} else if (hostbase == TEGRA2_SDMMC2_BASE) { -		reg = readl(&clkrst->crc_clk_src_sdmmc2); -		reg &= 0xFFFFFF00;	/* divisor (7.1) = 00 */ -		reg |= hw_div;		/* n-1 */ -		writel(reg, &clkrst->crc_clk_src_sdmmc2); -	} else if (hostbase == TEGRA2_SDMMC3_BASE) { -		reg = readl(&clkrst->crc_clk_src_sdmmc3); -		reg &= 0xFFFFFF00;	/* divisor (7.1) = 00 */ -		reg |= hw_div;		/* n-1 */ -		writel(reg, &clkrst->crc_clk_src_sdmmc3); -	} else { -		reg = readl(&clkrst->crc_clk_src_sdmmc4); -		reg &= 0xFFFFFF00;	/* divisor (7.1) = 00 */ -		reg |= hw_div;		/* n-1 */ -		writel(reg, &clkrst->crc_clk_src_sdmmc4); -	} +	clock_adjust_periph_pll_div(host->mmc_id, CLOCK_ID_PERIPH, clock, +				    &div); +	debug("div = %d\n", div);  	writew(0, &host->reg->clkcon); -	div >>= 1;  	/*  	 * CLKCON  	 * SELFREQ[15:8]	: base clock divided by value @@ -337,6 +309,7 @@ static void mmc_change_clock(struct mmc_host *host, uint clock)  	 * STBLINTCLK[1]	: Internal Clock Stable  	 * ENINTCLK[0]		: Internal Clock Enable  	 */ +	div >>= 1;  	clk = (div << 8) | (1 << 0);  	writew(clk, &host->reg->clkcon); @@ -355,7 +328,6 @@ static void mmc_change_clock(struct mmc_host *host, uint clock)  	writew(clk, &host->reg->clkcon);  	debug("mmc_change_clock: clkcon = %08X\n", clk); -	debug("mmc_change_clock: CLK_SOURCE_SDMMCx = %08X\n", reg);  out:  	host->clock = clock; @@ -370,7 +342,6 @@ static void mmc_set_ios(struct mmc *mmc)  	debug("bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock);  	/* Change clock first */ -  	mmc_change_clock(host, mmc->clock);  	ctrl = readb(&host->reg->hostctl); @@ -481,7 +452,7 @@ static int tegra2_mmc_initialize(int dev_index, int bus_width)  		mmc->host_caps = MMC_MODE_8BIT;  	else  		mmc->host_caps = MMC_MODE_4BIT; -	mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; +	mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;  	/*  	 * min freq is for card identification, and is the highest @@ -495,8 +466,7 @@ static int tegra2_mmc_initialize(int dev_index, int bus_width)  	mmc->f_max = 48000000;  	mmc_host[dev_index].clock = 0; -	mmc_host[dev_index].reg = tegra2_get_base_mmc(dev_index); -	mmc_host[dev_index].base = (unsigned int)mmc_host[dev_index].reg; +	tegra2_get_setup(&mmc_host[dev_index], dev_index);  	mmc_register(mmc);  	return 0; diff --git a/drivers/mmc/tegra2_mmc.h b/drivers/mmc/tegra2_mmc.h index 4b80f9f3b..28698e0fc 100644 --- a/drivers/mmc/tegra2_mmc.h +++ b/drivers/mmc/tegra2_mmc.h @@ -73,6 +73,7 @@ struct mmc_host {  	unsigned int version;	/* SDHCI spec. version */  	unsigned int clock;	/* Current clock (MHz) */  	unsigned int base;	/* Base address, SDMMC1/2/3/4 */ +	enum periph_id mmc_id;	/* Peripheral ID: PERIPH_ID_... */  };  int tegra2_mmc_init(int dev_index, int bus_width); |