diff options
-rw-r--r-- | board/toradex/common/tegra2_partitions.c | 29 | ||||
-rw-r--r-- | drivers/mmc/tegra_mmc.c | 39 |
2 files changed, 64 insertions, 4 deletions
diff --git a/board/toradex/common/tegra2_partitions.c b/board/toradex/common/tegra2_partitions.c index 7589760fbdc..77308d165d8 100644 --- a/board/toradex/common/tegra2_partitions.c +++ b/board/toradex/common/tegra2_partitions.c @@ -43,6 +43,14 @@ static int block_size; #if (defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_COLIBRI_T20)) || \ defined(CONFIG_COLIBRI_T30) || defined(CONFIG_APALIS_T30) +static u32 __def_get_boot_size_mult(struct mmc *mmc) +{ + /* return default boot size. */ + return 0; +} +u32 get_boot_size_mult(struct mmc *mmc) + __attribute__((weak, alias("__def_get_boot_size_mult"))); + /** * nvtegra_mmc_read - read data from mmc (unaligned) * @param startAddress: data offset in bytes @@ -80,8 +88,7 @@ ulong nvtegra_mmc_read(ulong startAddress, ulong dataCount, void *dst) free(buffer); return 0; } - memcpy(dst, buffer + (startAddress - startBlock * EMMC_BLOCK_SIZE), - dataCount); + memcpy(dst, buffer, dataCount); free(buffer); return dataCount; @@ -172,8 +179,8 @@ int nvtegra_read_partition_table(nvtegra_parttable_t * pt, int boot_media) #endif /* Search PT logical offset - Note: 0x326 for T30 Fastboot, 0xB48 for Eboot resp. Android - Fastboot and 0xEEC for Vibrante Fastboot */ + Note: 0x326 for T30 Fastboot, 0xb48 for Eboot resp. Android + Fastboot and 0xeec for Vibrante Fastboot */ for (i = 0; i < 0x800; i++) { if (readw(bct_start) == 0x40) { /* Either previous or 3rd next word */ @@ -227,6 +234,20 @@ int nvtegra_read_partition_table(nvtegra_parttable_t * pt, int boot_media) } else #endif /* CONFIG_COLIBRI_T20 */ { +#if (defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_COLIBRI_T20)) || \ + defined(CONFIG_COLIBRI_T30) || defined(CONFIG_APALIS_T30) + /* The PT offset has been calculated from the .cfg eMMC + partition configuration file using virtual linearised + addressing across all eMMC regions as expected by nvflash. + Due to the lack of a region control mechanism in nvflash/ + .cfg flashing utility in order to obtain the actual PT + offset from the start of the user region the size of the + boot regions must be subtracted. */ + struct mmc *mmc = find_mmc_device(EMMC_DEV); + if (mmc && !mmc_init(mmc) && (get_boot_size_mult(mmc) == 16)) + pt_logical -= 0x5000; //why? +#endif + /* StartLogicalSector / LogicalBlockSize * PhysicalBlockSize + BootPartitions */ pt_offset = pt_logical / block_size * 512 + 1024 * 1024; diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index e05655b261d..42ab2081350 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -735,3 +735,42 @@ int tegra_mmc_init(const void *blob) #endif return 0; } + +/* An eMMC device is specified to have 0 or 2 boot regions and they must have + the same size ranging from 0 to 2 MiB. The boot region size can be queried + from the device through the BOOT_SIZE_MULT field of the response to the + EXT_CSD command sequence. */ +#define BOOT_SIZE_MULT 226 +u32 get_boot_size_mult(struct mmc *mmc) +{ + u32 ret = 0; + char *ext_csd = memalign(CACHE_LINE_SIZE, 512); + + if (ext_csd) { + int err; + struct mmc_cmd cmd; + struct mmc_data data; + + /* Get the Card Status Register */ + cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 0; + cmd.flags = 0; + + data.dest = ext_csd; + data.blocks = 1; + data.blocksize = 512; + data.flags = MMC_DATA_READ; + + /* + * If EXT_CSD cmd fails, then just return CONFIG_ENV_OFFSET, + * because the eMMC is not supporting boot regions (no boot + * regions). + */ + err = mmc_send_cmd(mmc, &cmd, &data); + if (!err) + ret = (int)ext_csd[BOOT_SIZE_MULT]; + free(ext_csd); + } + return ret; +} |