summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@stericsson.com>2010-07-02 13:47:39 +0200
committerMichael BRANDT <michael.brandt@stericsson.com>2010-08-11 10:53:36 +0200
commit33a2e90bf491f13a4546d09a6105582c0ba7f313 (patch)
treeb986e40cefe66056013a73977976b1fa38b334c4 /common
parent415211fa4c850467b3e45b7cdb2405ac018dec77 (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-xcommon/env_emmc.c107
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 */