From 33a2e90bf491f13a4546d09a6105582c0ba7f313 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 2 Jul 2010 13:47:39 +0200 Subject: Replace MMC/SD driver to fit new framework. IR265772: MMC driver does not detect SDHC cards. IR254201: Restructure MMC/SD driver for U8500 board according to the block device framework in mainline U-Boot. Changes to mmc framework: - Multi Block Read support in mmc framework. - Wrap Multi Block Write/Read to be able to adopt for large transaction. - Removed incorrect check in EXT CSD for high capacity MMC. - Corrected check for high capacity SD cards. - Set MMC buswidth to 8, prio of using 4. Known limitations/bugs in mmc framework: - High capacity MMC, will likely not get the correct density. - High speed is set, whether or not the host supports it or not. board/st/u8500/mmc_utils: IMPORTANT FOR DEVELOPERS: - Removed unessary U-Boot commands which is already supported in cmd_fat. - mmc_read_cmd_file: Read command.txt into bootcmd env from FAT FS in SD card. - write_partition_block: Writes the MBR if it is not already written. board/st/u8500/mmc_host[c.h]: - Implements the entire MMC/SD host driver for the PL180 block. - There is still room for optimization: Increase CLK-speed. Use high-speed for SD cards. Is GPIO setup correctly for both cards an eMMC. EarlyDrop support not fully tested. Dynamically turn on voltage/clocks to SD, not always. More... Note: - Increased read/write performance for eMMC, to around 5.4 MB/s for sequential read/write. Earlier measurements was 3.5 MB/s for read and 2.6 MB/s for write. ST-Ericsson ID: ER265772, CR267996, ER267993 Change-Id: I921102edbde761407ff5ad476d1bb99f5dc7a2ef Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/2288 Reviewed-by: Michael BRANDT Tested-by: Michael BRANDT Reviewed-by: Martin LUNDHOLM Tested-by: Martin LUNDHOLM Reviewed-by: Mikael LARSSON Tested-by: Mikael LARSSON --- common/env_emmc.c | 107 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 23 deletions(-) (limited to 'common') diff --git a/common/env_emmc.c b/common/env_emmc.c index c169aa209..221798e19 100755 --- a/common/env_emmc.c +++ b/common/env_emmc.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #if defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_EMMC) #define CMD_SAVEENV @@ -67,6 +67,62 @@ uchar env_get_char_spec (int index) return ( *((uchar *)(gd->env_addr + index)) ); } +static int emmc_init(void) +{ + int i; + struct mmc *boot_dev = NULL; + + for (i = 0;; i++) { + boot_dev = find_mmc_device(i); + if (!boot_dev) + return -1; + if (!strcmp(boot_dev->name, env_name_spec)) + break; + } + + return mmc_init(boot_dev); +} +static int emmc_read_write(u32 byte_offset, void *read_buffer, + u32 size, u32 write) +{ + int i; + u32 xferred_bytes; + struct mmc *boot_dev = NULL; + u32 blkcnt; + + for (i = 0;; i++) { + boot_dev = find_mmc_device(i); + if (!boot_dev) + return -1; + if (!strcmp(boot_dev->name, env_name_spec)) + break; + } + + if (write) { + blkcnt = size/boot_dev->write_bl_len; + if (size && !blkcnt) + blkcnt++; + xferred_bytes = + boot_dev->block_dev.block_write(i, + byte_offset/boot_dev->write_bl_len, + blkcnt, + (u_char *)read_buffer); + xferred_bytes *= boot_dev->write_bl_len; + } else { + blkcnt = size/boot_dev->read_bl_len; + if (size && !blkcnt) + blkcnt++; + xferred_bytes = + boot_dev->block_dev.block_read(i, + byte_offset/boot_dev->read_bl_len, + blkcnt, + (u_char *)read_buffer); + xferred_bytes *= boot_dev->read_bl_len; + } + debug("emmc read write:requested:0x%x,done:0x%x", size, xferred_bytes); + return xferred_bytes; +} + /* this is called before nand_init() * so we can't read Nand to validate env data. @@ -131,21 +187,18 @@ int env_init(void) #ifdef CMD_SAVEENV int saveenv(void) { - ulong total; int ret = 0; - puts ("Erasing eMMC..."); - if (emmc_erase(CONFIG_ENV_OFFSET_START, CONFIG_ENV_OFFSET_END)) - return 1; - puts ("Writing to EMMC... "); - total = CONFIG_ENV_SIZE; - ret = emmc_write(CONFIG_ENV_OFFSET_START, (u32 *) env_ptr, - CONFIG_ENV_SIZE); - //if (ret || total != CONFIG_ENV_SIZE) - //return 1; + env_crc_update(); + ret = emmc_read_write(CONFIG_ENV_OFFSET_START, (void *) env_ptr, + CONFIG_ENV_SIZE, 1); + + if (ret != CONFIG_ENV_SIZE) + puts("error in saving environment\n"); + else + puts("done\n"); - puts ("done\n"); return ret; } #endif /* CMD_SAVEENV */ @@ -162,8 +215,8 @@ void env_relocate_spec (void) tmp_env1 = (env_t *) malloc(CONFIG_ENV_SIZE); tmp_env2 = (env_t *) malloc(CONFIG_ENV_SIZE); - emmc_read(CONFIG_ENV_OFFSET_START,(u32 *) tmp_env1, total); - emmc_read(CONFIG_ENV_OFFSET_START,(u32 *) tmp_env2, total); + emmc_read_write(CONFIG_ENV_OFFSET_START, (void *) tmp_env1, total, 0); + emmc_read_write(CONFIG_ENV_OFFSET_START, (void *) tmp_env2, total, 0); crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); @@ -204,18 +257,26 @@ void env_relocate_spec (void) void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) - ulong total; int ret; - total = CONFIG_ENV_SIZE; - printf("env_relocate_spec start\n"); - emmc_init(4); - ret = emmc_read(CONFIG_ENV_OFFSET_START, (u_char*)env_ptr, total); - if (ret || total != CONFIG_ENV_SIZE) - return set_default_env(); + ret = emmc_init(); - if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) - return set_default_env(); + ret = emmc_read_write(CONFIG_ENV_OFFSET_START, + (void *)env_ptr, CONFIG_ENV_SIZE, 0); + + if (ret != CONFIG_ENV_SIZE) { + printf("env read failed so setting default env\n"); + goto misc; + } + + if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) { + printf("env crc failed so setting default env\n"); + goto misc; + } + return; + +misc: + return set_default_env(); #endif /* ! ENV_IS_EMBEDDED */ } #endif /* CONFIG_ENV_OFFSET_REDUND */ -- cgit v1.2.3