diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2010-07-02 13:47:39 +0200 |
---|---|---|
committer | Michael BRANDT <michael.brandt@stericsson.com> | 2010-08-11 10:53:36 +0200 |
commit | 33a2e90bf491f13a4546d09a6105582c0ba7f313 (patch) | |
tree | b986e40cefe66056013a73977976b1fa38b334c4 /common | |
parent | 415211fa4c850467b3e45b7cdb2405ac018dec77 (diff) |
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 <michael.brandt@stericsson.com>
Tested-by: Michael BRANDT <michael.brandt@stericsson.com>
Reviewed-by: Martin LUNDHOLM <martin.xa.lundholm@stericsson.com>
Tested-by: Martin LUNDHOLM <martin.xa.lundholm@stericsson.com>
Reviewed-by: Mikael LARSSON <mikael.xt.larsson@stericsson.com>
Tested-by: Mikael LARSSON <mikael.xt.larsson@stericsson.com>
Diffstat (limited to 'common')
-rwxr-xr-x | common/env_emmc.c | 107 |
1 files changed, 84 insertions, 23 deletions
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 <environment.h> #include <linux/stddef.h> #include <malloc.h> -#include <asm/arch/emmc.h> +#include <mmc.h> #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 */ |