summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2013-08-12 10:37:32 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2013-08-12 10:37:32 +0200
commitd63f3c73a767b82ba1e28c30a46a1e88616ed66e (patch)
tree572ab70727626189353b577e0840d60b7fa61c9c /drivers
parent1cf83224ac11e2ea1a0b3546b27ecd9a59fac247 (diff)
apalis/colibri_t30: implement emmc pt offset auto detection
In preparation for the new Apalis T30 SKUs implement eMMC PT offset auto detection. 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. 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. Tested on initial samples of Apalis T30 1GB V1.0A, Apalis T30 2GB V1.0B, Apalis T30 2GB V1.0C and Colibri T30 V1.1C.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/tegra_mmc.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index e05655b261..42ab208135 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;
+}