summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2023-04-19 08:58:58 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-04-19 08:58:58 +0200
commitc46996d29b49b9d7fc33aa4ae59ea90596da068f (patch)
treea6cd5e98fbb2a6e47061cb3071fb4a4b083373f4 /scripts
parentdc4f31b6c0d121402aead43cb7c13121ad9a3d9d (diff)
parentc20cf77b26f230d40aef3f086f305dfc35a01a9e (diff)
downloadbarebox-c46996d29b49b9d7fc33aa4ae59ea90596da068f.tar.gz
Merge branch 'for-next/imx-image'
Diffstat (limited to 'scripts')
-rw-r--r--scripts/imx/imx-image.c146
-rw-r--r--scripts/imx/imx.c26
2 files changed, 161 insertions, 11 deletions
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index 439912a805..1f96b38390 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -20,6 +20,7 @@
#include "imx.h"
#include <include/filetype.h>
+#include <include/linux/sizes.h>
#define FLASH_HEADER_OFFSET 0x400
#define ARM_HEAD_SIZE_INDEX (ARM_HEAD_SIZE_OFFSET / sizeof(uint32_t))
@@ -34,7 +35,7 @@
static uint32_t dcdtable[MAX_DCD];
static int curdcd;
-static int create_usb_image;
+static bool create_usb_image;
static char *prgname;
/*
@@ -289,17 +290,30 @@ static int write_mem_v1(uint32_t addr, uint32_t val, int width, int set_bits, in
return 0;
}
+static bool flexspi_image(const struct config_data *data)
+{
+ /*
+ * | FlexSPI-FCFB | FlexSPI-IVT
+ * -----------------------------------------
+ * i.MX8MM | 0x0 | 0x1000
+ * i.MX8MN/P | 0x400 | 0x0
+ */
+
+ return data->image_flexspi_ivt_offset || data->image_flexspi_fcfb_offset;
+}
+
/*
* ============================================================================
* i.MX flash header v2 handling. Found on i.MX50, i.MX53 and i.MX6
* ============================================================================
*/
-static size_t add_header_v2(const struct config_data *data, void *buf)
+static size_t
+add_header_v2(const struct config_data *data, void *buf, uint32_t offset,
+ size_t header_len)
{
struct imx_flash_header_v2 *hdr;
int dcdsize = curdcd * sizeof(uint32_t);
- int offset = data->image_ivt_offset;
uint32_t loadaddr = data->image_load_addr;
uint32_t imagesize = data->load_size;
@@ -308,7 +322,7 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
* Restrict the imagesize to the PBL if given.
* Also take the alignment for CSF into account.
*/
- imagesize = roundup(data->pbl_code_size + HEADER_LEN, 0x4);
+ imagesize = roundup(data->pbl_code_size + header_len, 0x4);
if (data->csf)
imagesize = roundup(imagesize, 0x1000);
}
@@ -320,7 +334,7 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
hdr->header.length = htobe16(32);
hdr->header.version = IVT_VERSION;
- hdr->entry = loadaddr + HEADER_LEN;
+ hdr->entry = loadaddr + header_len;
if (dcdsize)
hdr->dcd_ptr = loadaddr + offset + offsetof(struct imx_flash_header_v2, dcd_header);
if (create_usb_image) {
@@ -362,6 +376,114 @@ static size_t add_header_v2(const struct config_data *data, void *buf)
return imagesize;
}
+#define LUT_PAD_1 0
+#define LUT_PAD_2 1
+#define LUT_PAD_4 2
+#define LUT_PAD_8 3
+
+static size_t add_flexspi_fcfb_header(const struct config_data *data, void *buf)
+{
+ uint32_t fcfb_offset = data->image_flexspi_fcfb_offset;
+ const struct imx_fcfb_nor nor_conf = {
+ .memcfg = {
+ .tag = htobe32(FCFB_HEAD_TAG),
+ .version = htole32(FCFB_VERSION),
+ .read_sample = FCFB_SAMLPE_CLK_SRC_INTERNAL,
+ /* flash CS hold time, recommended by RM */
+ .datahold = 0x03,
+ /* flash CS setup time, recommended by RM */
+ .datasetup = 0x03,
+ /* 3 - Hyperflash, 12/13 serial NAND, 0 - other */
+ .coladdrwidth = 0,
+ .devcfgenable = 0,
+ .cmd_enable = 0,
+ .controllermisc = 0,
+ .dev_type = FCFB_DEVTYPE_SERIAL_NOR,
+ .sflash_pad = FCFB_SFLASH_PADS_SINGLE,
+ .serial_clk = FCFB_SERIAL_CLK_FREQ_50MHZ,
+ .sflashA1 = htole32(SZ_256M),
+ .lut.seq[0] = {
+ .instr = {
+ htole16(LUT_DEF(LUT_CMD, LUT_PAD_1, 0x0b)),
+ htole16(LUT_DEF(LUT_ADDR, LUT_PAD_1, 24)),
+ htole16(LUT_DEF(LUT_DUMMY, LUT_PAD_1, 8)),
+ htole16(LUT_DEF(LUT_NXP_READ, LUT_PAD_1, 4)),
+ htole16(LUT_DEF(LUT_STOP, LUT_PAD_1, 0)),
+ },
+ },
+ },
+ };
+
+ buf += fcfb_offset;
+ memcpy(buf, &nor_conf, sizeof(nor_conf));
+
+ return sizeof(nor_conf);
+}
+
+#define FLEXSPI_HEADER_LEN HEADER_LEN
+
+static size_t
+add_flexspi_header(const struct config_data *data, void **_buf, size_t *header_len)
+{
+ uint32_t ivt_offset = data->image_flexspi_ivt_offset;
+ size_t size;
+ size_t len;
+ void *buf;
+
+ if (!flexspi_image(data))
+ return 0;
+
+ if (data->signed_hdmi_firmware_file) {
+ free(*_buf);
+ fprintf(stderr, "Signed HDMI firmware and FlexSPI compatible image is not supported!\n");
+ exit(1);
+ }
+
+ /*
+ * Extend the header to be able to build build one image which can be
+ * used for: USB/SD/eMMC/eMMC-Boot/QSPI/barebox-chainload.
+ */
+ buf = realloc(*_buf, *header_len + FLEXSPI_HEADER_LEN);
+ if (!buf)
+ exit(1);
+
+ *_buf = buf;
+
+ size = add_flexspi_fcfb_header(data, buf);
+
+ /*
+ * The following table list the offsets we need to ensure for
+ * the one image approach.
+ *
+ * | i.MX8MM | i.MX8MN/P |
+ * -----------------------------+---------+-----------+
+ * SD/eMMC primary image offset | 0 | 0/32K |
+ * FlexSPI primary image offset | 0 | 4K |
+ * SD/eMMC-IVT offset | 1K | 0 |
+ * SD/eMMC-IVT image entry | 8K | 8K |
+ * FlexSPI-IVT offset | 4K | 0 |
+ * FlexSPI-IVT image entry | 8K | 4K |
+ *
+ * According the above table the rom-loader for i.MX8MM will
+ * search for the image on the same place (8K). On the other
+ * hand the rom-loader for the i.MX8MN/P will look for it at
+ * 8K for SD/eMMC case or at 4K for FlexSPI case.
+ */
+ len = *header_len;
+ if (data->cpu_type == IMX_CPU_IMX8MM)
+ len += FLEXSPI_HEADER_LEN;
+
+ if (data->cpu_type == IMX_CPU_IMX8MP ||
+ data->cpu_type == IMX_CPU_IMX8MN)
+ buf += SZ_4K;
+
+ size += add_header_v2(data, buf, ivt_offset, len);
+
+ *header_len += FLEXSPI_HEADER_LEN;
+
+ return size;
+}
+
static void usage(const char *prgname)
{
fprintf(stderr, "usage: %s [OPTIONS]\n\n"
@@ -739,9 +861,9 @@ int main(int argc, char *argv[])
void *infile;
struct stat s;
int outfd;
- int dcd_only = 0;
+ bool dcd_only = false;
int now = 0;
- int add_barebox_header = 0;
+ bool add_barebox_header = false;
uint32_t barebox_image_size = 0;
struct config_data data = {
.image_ivt_offset = 0xffffffff,
@@ -771,16 +893,16 @@ int main(int argc, char *argv[])
data.pbl_code_size = strtoul(optarg, NULL, 0);
break;
case 'b':
- add_barebox_header = 1;
+ add_barebox_header = true;
break;
case 'd':
- dcd_only = 1;
+ dcd_only = true;
break;
case 's':
data.sign_image = 1;
break;
case 'u':
- create_usb_image = 1;
+ create_usb_image = true;
break;
case 'e':
data.encrypt_image = 1;
@@ -904,8 +1026,10 @@ int main(int argc, char *argv[])
}
}
+ barebox_image_size += add_flexspi_header(&data, &buf, &header_len);
barebox_image_size += add_header_v2(&data, buf +
- signed_hdmi_firmware_size);
+ signed_hdmi_firmware_size,
+ data.image_ivt_offset, header_len);
break;
default:
fprintf(stderr, "Congratulations! You're welcome to implement header version %d\n",
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index c91dfda214..e3169bace6 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -609,6 +609,26 @@ do_signed_hdmi_firmware(struct config_data *data, int argc, char *argv[])
return 0;
}
+static int do_flexspi_ivtofs(struct config_data *data, int argc, char *argv[])
+{
+ if (argc < 2)
+ return -EINVAL;
+
+ data->image_flexspi_ivt_offset = strtoul(argv[1], NULL, 0);
+
+ return 0;
+}
+
+static int do_flexspi_fcfbofs(struct config_data *data, int argc, char *argv[])
+{
+ if (argc < 2)
+ return -EINVAL;
+
+ data->image_flexspi_fcfb_offset = strtoul(argv[1], NULL, 0);
+
+ return 0;
+}
+
struct command cmds[] = {
{
.name = "wm",
@@ -667,6 +687,12 @@ struct command cmds[] = {
}, {
.name = "signed_hdmi_firmware",
.parse = do_signed_hdmi_firmware,
+ }, {
+ .name = "flexspi_fcfbofs",
+ .parse = do_flexspi_fcfbofs,
+ }, {
+ .name = "flexspi_ivtofs",
+ .parse = do_flexspi_ivtofs,
},
};