diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 46 | ||||
| -rw-r--r-- | drivers/mmc/spl_mmc.c | 17 | ||||
| -rw-r--r-- | drivers/mmc/zynq_sdhci.c | 40 | 
4 files changed, 84 insertions, 20 deletions
| diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 1d6faa2a9..7cd428173 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -49,6 +49,7 @@ COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.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/mmc.c b/drivers/mmc/mmc.c index d732581eb..2590f1bcc 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -601,7 +601,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)  	data.dest = (char *)ext_csd;  	data.blocks = 1; -	data.blocksize = 512; +	data.blocksize = MMC_MAX_BLOCK_LEN;  	data.flags = MMC_DATA_READ;  	err = mmc_send_cmd(mmc, &cmd, &data); @@ -634,7 +634,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)  static int mmc_change_freq(struct mmc *mmc)  { -	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); +	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);  	char cardtype;  	int err; @@ -784,6 +784,8 @@ retry_scr:  			break;  		case 2:  			mmc->version = SD_VERSION_2; +			if ((mmc->scr[0] >> 15) & 0x1) +				mmc->version = SD_VERSION_3;  			break;  		default:  			mmc->version = SD_VERSION_1_0; @@ -897,8 +899,8 @@ static int mmc_startup(struct mmc *mmc)  	uint mult, freq;  	u64 cmult, csize, capacity;  	struct mmc_cmd cmd; -	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); -	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512); +	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); +	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);  	int timeout = 1000;  #ifdef CONFIG_MMC_SPI_CRC_ON @@ -1014,11 +1016,11 @@ static int mmc_startup(struct mmc *mmc)  	mmc->capacity = (csize + 1) << (cmult + 2);  	mmc->capacity *= mmc->read_bl_len; -	if (mmc->read_bl_len > 512) -		mmc->read_bl_len = 512; +	if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) +		mmc->read_bl_len = MMC_MAX_BLOCK_LEN; -	if (mmc->write_bl_len > 512) -		mmc->write_bl_len = 512; +	if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) +		mmc->write_bl_len = MMC_MAX_BLOCK_LEN;  	/* Select the card, and put it into Transfer Mode */  	if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ @@ -1049,20 +1051,39 @@ static int mmc_startup(struct mmc *mmc)  					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8  					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16  					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24; -			capacity *= 512; +			capacity *= MMC_MAX_BLOCK_LEN;  			if ((capacity >> 20) > 2 * 1024)  				mmc->capacity = capacity;  		} +		switch (ext_csd[EXT_CSD_REV]) { +		case 1: +			mmc->version = MMC_VERSION_4_1; +			break; +		case 2: +			mmc->version = MMC_VERSION_4_2; +			break; +		case 3: +			mmc->version = MMC_VERSION_4_3; +			break; +		case 5: +			mmc->version = MMC_VERSION_4_41; +			break; +		case 6: +			mmc->version = MMC_VERSION_4_5; +			break; +		} +  		/*  		 * Check whether GROUP_DEF is set, if yes, read out  		 * group size from ext_csd directly, or calculate  		 * the group size from the csd value.  		 */ -		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) +		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {  			mmc->erase_grp_size = -			      ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 512 * 1024; -		else { +				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * +					MMC_MAX_BLOCK_LEN * 1024; +		} else {  			int erase_gsz, erase_gmul;  			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;  			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; @@ -1182,6 +1203,7 @@ static int mmc_startup(struct mmc *mmc)  	mmc->block_dev.lun = 0;  	mmc->block_dev.type = 0;  	mmc->block_dev.blksz = mmc->read_bl_len; +	mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);  	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);  	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",  		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff), diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c index 753c6a014..7efdcb88b 100644 --- a/drivers/mmc/spl_mmc.c +++ b/drivers/mmc/spl_mmc.c @@ -34,8 +34,9 @@ DECLARE_GLOBAL_DATA_PTR;  static void mmc_load_image_raw(struct mmc *mmc)  { -	u32 image_size_sectors, err; -	const struct image_header *header; +	unsigned long err; +	u32 image_size_sectors; +	struct image_header *header;  	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -  						sizeof(struct image_header)); @@ -43,9 +44,9 @@ static void mmc_load_image_raw(struct mmc *mmc)  	/* read image header to find the image size & load address */  	err = mmc->block_dev.block_read(0,  			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, -			(void *)header); +			header); -	if (err <= 0) +	if (err == 0)  		goto end;  	spl_parse_image_header(header); @@ -60,8 +61,8 @@ static void mmc_load_image_raw(struct mmc *mmc)  			image_size_sectors, (void *)spl_image.load_addr);  end: -	if (err <= 0) { -		printf("spl: mmc blk read err - %d\n", err); +	if (err == 0) { +		printf("spl: mmc blk read err - %lu\n", err);  		hang();  	}  } @@ -69,7 +70,7 @@ end:  #ifdef CONFIG_SPL_FAT_SUPPORT  static void mmc_load_image_fat(struct mmc *mmc)  { -	s32 err; +	int err;  	struct image_header *header;  	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - @@ -83,7 +84,7 @@ static void mmc_load_image_fat(struct mmc *mmc)  	}  	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, -				(u8 *)header, sizeof(struct image_header)); +				header, sizeof(struct image_header));  	if (err <= 0)  		goto end; 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; +} |