summaryrefslogtreecommitdiffstats
path: root/drivers/mci/imx-esdhc-pbl.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-06-22 10:51:14 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-07-14 20:20:18 +0200
commitd46b337511c808565709a62c62df1379b7f10e81 (patch)
tree35fc3338feb8dc00571d000792d675478d84856f /drivers/mci/imx-esdhc-pbl.c
parent498c197f469c81071e2652f97e0d501b0c629c4d (diff)
downloadbarebox-d46b337511c808565709a62c62df1379b7f10e81.tar.gz
barebox-d46b337511c808565709a62c62df1379b7f10e81.tar.xz
mci: imx-esdhc-pbl: Add imx8mp_esdhc_load_image() for i.MX8MP
The image format of the i.MX8MP is different from i.MX8M, so add its own image loading function for it. Older i.MX SoCs had a IVT Offset (the offset from the start of the image to the actual data) of 1KiB. This was done to leave space for the partition table at the beginning of the device. To support GPT SoCs starting with i.MX8M an additional gap of 32KiB was added, so that the actual image started at offset 33KiB. Now starting with i.MX8MP the now superfluous 1KiB offset was removed do that the actual image now starts at 32KiB. Unfortunately the 1KiB offset is woven into the offsets of the IVT whereas the 32KiB are not, which means that we really have to handle both offsets individually instead of just handling the sum of the offsets. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mci/imx-esdhc-pbl.c')
-rw-r--r--drivers/mci/imx-esdhc-pbl.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index caaf1ac9b5..5c382bbcc2 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -77,7 +77,7 @@ static int esdhc_read_blocks(struct fsl_esdhc_host *host, void *dst, size_t len)
#ifdef CONFIG_ARCH_IMX
static int esdhc_search_header(struct fsl_esdhc_host *host,
struct imx_flash_header_v2 **header_pointer,
- void *buffer, u32 *offset)
+ void *buffer, u32 *offset, u32 ivt_offset)
{
int ret;
int i, header_count = 1;
@@ -86,11 +86,11 @@ static int esdhc_search_header(struct fsl_esdhc_host *host,
for (i = 0; i < header_count; i++) {
ret = esdhc_read_blocks(host, buf,
- *offset + SZ_1K + SECTOR_SIZE);
+ *offset + ivt_offset + SECTOR_SIZE);
if (ret)
return ret;
- hdr = buf + *offset + SZ_1K;
+ hdr = buf + *offset + ivt_offset;
if (!is_imx_flash_header_v2(hdr)) {
pr_debug("IVT header not found on SD card. "
@@ -123,7 +123,7 @@ static int esdhc_search_header(struct fsl_esdhc_host *host,
static int
esdhc_load_image(struct fsl_esdhc_host *host, ptrdiff_t address,
- ptrdiff_t entry, u32 offset, bool start)
+ ptrdiff_t entry, u32 offset, u32 ivt_offset, bool start)
{
void *buf = (void *)address;
@@ -135,7 +135,7 @@ esdhc_load_image(struct fsl_esdhc_host *host, ptrdiff_t address,
len = imx_image_size();
len = ALIGN(len, SECTOR_SIZE);
- ret = esdhc_search_header(host, &hdr, buf, &offset);
+ ret = esdhc_search_header(host, &hdr, buf, &offset, ivt_offset);
if (ret)
return ret;
@@ -262,7 +262,7 @@ int imx6_esdhc_start_image(int instance)
imx_esdhc_init(&host, &data);
- return esdhc_load_image(&host, 0x10000000, 0x10000000, 0, true);
+ return esdhc_load_image(&host, 0x10000000, 0x10000000, 0, SZ_1K, true);
}
/**
@@ -289,7 +289,35 @@ int imx8m_esdhc_load_image(int instance, bool start)
return ret;
return esdhc_load_image(&host, MX8M_DDR_CSD1_BASE_ADDR,
- MX8MQ_ATF_BL33_BASE_ADDR, SZ_32K, start);
+ MX8MQ_ATF_BL33_BASE_ADDR, SZ_32K, SZ_1K,
+ start);
+}
+
+/**
+ * imx8mp_esdhc_load_image - Load and optionally start an image from USDHC controller
+ * @instance: The USDHC controller instance (0..2)
+ * @start: Whether to directly start the loaded image
+ *
+ * This uses esdhc_start_image() to load an image from SD/MMC. It is
+ * assumed that the image is the currently running barebox image (This
+ * information is used to calculate the length of the image). The
+ * image is started afterwards.
+ *
+ * Return: If successful, this function does not return (if directly started)
+ * or 0. A negative error code is returned when this function fails.
+ */
+int imx8mp_esdhc_load_image(int instance, bool start)
+{
+ struct esdhc_soc_data data;
+ struct fsl_esdhc_host host;
+ int ret;
+
+ ret = imx8m_esdhc_init(&host, &data, instance);
+ if (ret)
+ return ret;
+
+ return esdhc_load_image(&host, MX8M_DDR_CSD1_BASE_ADDR,
+ MX8MQ_ATF_BL33_BASE_ADDR, SZ_32K, 0, start);
}
#endif