diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2023-04-19 08:58:58 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2023-04-19 08:58:58 +0200 |
commit | c46996d29b49b9d7fc33aa4ae59ea90596da068f (patch) | |
tree | a6cd5e98fbb2a6e47061cb3071fb4a4b083373f4 /scripts | |
parent | dc4f31b6c0d121402aead43cb7c13121ad9a3d9d (diff) | |
parent | c20cf77b26f230d40aef3f086f305dfc35a01a9e (diff) | |
download | barebox-c46996d29b49b9d7fc33aa4ae59ea90596da068f.tar.gz |
Merge branch 'for-next/imx-image'
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/imx/imx-image.c | 146 | ||||
-rw-r--r-- | scripts/imx/imx.c | 26 |
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, }, }; |