diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/dw_mmc.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/exynos_dw_mmc.c | 17 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 79 | ||||
| -rw-r--r-- | drivers/mmc/zynq_sdhci.c | 3 | 
4 files changed, 46 insertions, 55 deletions
| diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 4cec5aaa6..d45c15cfa 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -237,7 +237,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)  	 * host->bus_hz should be set from user.  	 */  	if (host->get_mmc_clk) -		sclk = host->get_mmc_clk(host->dev_index); +		sclk = host->get_mmc_clk(host);  	else if (host->bus_hz)  		sclk = host->bus_hz;  	else { diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index b3e5c5e5e..de8cdcc42 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -29,9 +29,22 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)  	dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);  } -unsigned int exynos_dwmci_get_clk(int dev_index) +unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)  { -	return get_mmc_clk(dev_index); +	unsigned long sclk; +	int8_t clk_div; + +	/* +	 * Since SDCLKIN is divided inside controller by the DIVRATIO +	 * value set in the CLKSEL register, we need to use the same output +	 * clock value to calculate the CLKDIV value. +	 * as per user manual:cclk_in = SDCLKIN / (DIVRATIO + 1) +	 */ +	clk_div = ((dwmci_readl(host, DWMCI_CLKSEL) >> DWMCI_DIVRATIO_BIT) +			& DWMCI_DIVRATIO_MASK) + 1; +	sclk = get_mmc_clk(host->dev_index); + +	return sclk / clk_div;  }  static void exynos_dwmci_board_init(struct dwmci_host *host) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c6a1c23fb..8ab0bc948 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -430,7 +430,7 @@ int mmc_complete_op_cond(struct mmc *mmc)  	mmc->ocr = cmd.response[0];  	mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); -	mmc->rca = 0; +	mmc->rca = 1;  	return 0;  } @@ -1442,67 +1442,44 @@ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,  }  /* - * This function shall form and send the commands to open / close the - * boot partition specified by user. - * - * Input Parameters: - * ack: 0x0 - No boot acknowledge sent (default) - *	0x1 - Boot acknowledge sent during boot operation - * part_num: User selects boot data that will be sent to master - *	0x0 - Device not boot enabled (default) - *	0x1 - Boot partition 1 enabled for boot - *	0x2 - Boot partition 2 enabled for boot - * access: User selects partitions to access - *	0x0 : No access to boot partition (default) - *	0x1 : R/W boot partition 1 - *	0x2 : R/W boot partition 2 - *	0x3 : R/W Replay Protected Memory Block (RPMB) + * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH + * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH + * and BOOT_MODE.   *   * Returns 0 on success.   */ -int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access) +int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)  {  	int err; -	struct mmc_cmd cmd; -	/* Boot ack enable, boot partition enable , boot partition access */ -	cmd.cmdidx = MMC_CMD_SWITCH; -	cmd.resp_type = MMC_RSP_R1b; - -	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | -			(EXT_CSD_PART_CONF << 16) | -			((EXT_CSD_BOOT_ACK(ack) | -			EXT_CSD_BOOT_PART_NUM(part_num) | -			EXT_CSD_PARTITION_ACCESS(access)) << 8); +	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH, +			 EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) | +			 EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) | +			 EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width)); -	err = mmc_send_cmd(mmc, &cmd, NULL); -	if (err) { -		if (access) { -			debug("mmc boot partition#%d open fail:Error1 = %d\n", -			      part_num, err); -		} else { -			debug("mmc boot partition#%d close fail:Error = %d\n", -			      part_num, err); -		} +	if (err)  		return err; -	} +	return 0; +} -	if (access) { -		/* 4bit transfer mode at booting time. */ -		cmd.cmdidx = MMC_CMD_SWITCH; -		cmd.resp_type = MMC_RSP_R1b; +/* + * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG) + * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and + * PARTITION_ACCESS. + * + * Returns 0 on success. + */ +int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) +{ +	int err; -		cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | -				(EXT_CSD_BOOT_BUS_WIDTH << 16) | -				((1 << 0) << 8); +	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, +			 EXT_CSD_BOOT_ACK(ack) | +			 EXT_CSD_BOOT_PART_NUM(part_num) | +			 EXT_CSD_PARTITION_ACCESS(access)); -		err = mmc_send_cmd(mmc, &cmd, NULL); -		if (err) { -			debug("mmc boot partition#%d open fail:Error2 = %d\n", -			      part_num, err); -			return err; -		} -	} +	if (err) +		return err;  	return 0;  }  #endif diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 610bef5cb..72a272f2b 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -23,7 +23,8 @@ int zynq_sdhci_init(u32 regbase)  	host->name = "zynq_sdhci";  	host->ioaddr = (void *)regbase; -	host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD; +	host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD | +		       SDHCI_QUIRK_BROKEN_R1B;  	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);  	host->host_caps = MMC_MODE_HC; |