diff --git a/include/imximage.h b/include/imximage.h index 5a812f5a10..c1ecc0b7cb 100644 --- a/include/imximage.h +++ b/include/imximage.h @@ -201,6 +201,44 @@ struct imx_header { } header; }; +typedef struct { + uint8_t tag[4]; + uint8_t version[4]; + uint8_t reserved_1[4]; + uint8_t read_sample; + uint8_t datahold; + uint8_t datasetup; + uint8_t coladdrwidth; + uint8_t devcfgenable; + uint8_t reserved_2[3]; + uint8_t devmodeseq[4]; + uint8_t devmodearg[4]; + uint8_t cmd_enable; + uint8_t reserved_3[3]; + uint8_t cmd_seq[16] ; + uint8_t cmd_arg[16]; + uint8_t controllermisc[4]; + uint8_t dev_type; + uint8_t sflash_pad; + uint8_t serial_clk; + uint8_t lut_custom ; + uint8_t reserved_4[8]; + uint8_t sflashA1[4]; + uint8_t sflashA2[4]; + uint8_t sflashB1[4]; + uint8_t sflashB2[4]; + uint8_t cspadover[4]; + uint8_t sclkpadover[4]; + uint8_t datapadover[4]; + uint8_t dqspadover[4]; + uint8_t timeout[4]; + uint8_t commandInt[4]; + uint8_t datavalid[4]; + uint8_t busyoffset[2]; + uint8_t busybitpolarity[2]; + uint8_t lut[256]; +} __attribute__((packed)) fspi_conf; + typedef void (*set_dcd_val_t)(struct imx_header *imxhdr, char *name, int lineno, int fld, uint32_t value, diff --git a/tools/Kconfig b/tools/Kconfig index 117c921da3..539708f277 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -98,4 +98,63 @@ config TOOLS_MKEFICAPSULE optionally sign that file. If you want to enable UEFI capsule update feature on your target, you certainly need this. +menuconfig FSPI_CONF_HEADER + bool "FlexSPI Header Configuration" + help + FSPI Header Configuration + +config FSPI_CONF_FILE + string "FlexSPI Header File" + depends on FSPI_CONF_HEADER + help + FlexSPI Header File name + +config READ_CLK_SOURCE + hex "Sampling Clock Source" + default 0x00 + depends on FSPI_CONF_HEADER + help + Sample Clock source for Flash, default is internal loopback clock + +config DEVICE_TYPE + hex "Flash Type" + default 0x01 + depends on FSPI_CONF_HEADER + help + Flash type: Serial NOR (0X01) and Serial NAND (0x02) + +config FLASH_PAD_TYPE + hex "Flash Pad Type" + default 0x01 + depends on FSPI_CONF_HEADER + help + Flash Pad type : + Single Pad 0x01 + Dual Pads 0x02 + Quad Pad 0x04 + Octal Pad 0x08 + +config SERIAL_CLK_FREQUENCY + hex "Serial Clock Frequency" + default 0x02 + depends on FSPI_CONF_HEADER + help + Chip specific frequency: other value 30MHz + 1-30MHz 2-50MHz 3-60MHz 4-75MHz 5-80MHz 6-100MHz 7-133MHz 8-166MHz + +config LUT_CUSTOM_SEQUENCE + hex "Enable Custom Look Up Table(LUT) Sequence" + default 0x00 + depends on FSPI_CONF_HEADER + help + 0 - Use predefined LUT Sequence + 1 - Use LUT Sequence provided + +config LUT_SEQUENCE + string "Look Up Table Sequence" + default "0x0b, 0x04, 0x18, 0x08, 0x08, 0x30, 0x04, 0x24" + depends on FSPI_CONF_HEADER + help + Look Up Table Sequence + endmenu diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c index 52baf4c990..a4699decf9 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -120,7 +120,6 @@ static void parse_cfg_cmd(int32_t cmd, char *token, char *name, int lineno) rom_version = ROM_V1; } break; - } } @@ -412,9 +411,75 @@ static void dump_header_v2(imx_header_v3_t *imx_header, int index) imx_header[index].boot_data.plugin); } +#ifdef CONFIG_FSPI_CONF_HEADER +static int generate_fspi_header (int ifd) +{ + int ret, i = 0; + char *val; + char lut_str[] = CONFIG_LUT_SEQUENCE; + + fspi_conf fspi_conf_data = { + .tag = {0x46, 0x43, 0x46, 0x42}, + .version = {0x00, 0x00, 0x01, 0x56}, + .reserved_1 = {0x00, 0x00, 0x00, 0x00}, + .read_sample = CONFIG_READ_CLK_SOURCE, + .datahold = 0x03, + .datasetup = 0x03, + .coladdrwidth = 0x00, + .devcfgenable = 0x00, + .reserved_2 = {0x00, 0x00, 0x00}, + .devmodeseq = {0x00, 0x00, 0x00, 0x00}, + .devmodearg = {0x00, 0x00, 0x00, 0x00}, + .cmd_enable = 0x00, + .reserved_3 = {0x00}, + .cmd_seq = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .cmd_arg = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .controllermisc = {0x00, 0x00, 0x00, 0x00}, + .dev_type = CONFIG_DEVICE_TYPE, + .sflash_pad = CONFIG_FLASH_PAD_TYPE, + .serial_clk = CONFIG_SERIAL_CLK_FREQUENCY, + .lut_custom = CONFIG_LUT_CUSTOM_SEQUENCE, + .reserved_4 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .sflashA1 = {0x00, 0x00, 0x00, 0x10}, + .sflashA2 = {0x00, 0x00, 0x00, 0x00}, + .sflashB1 = {0x00, 0x00, 0x00, 0x00}, + .sflashB2 = {0x00, 0x00, 0x00, 0x00}, + .cspadover = {0x00, 0x00, 0x00, 0x00}, + .sclkpadover = {0x00, 0x00, 0x00, 0x00}, + .datapadover = {0x00, 0x00, 0x00, 0x00}, + .dqspadover = {0x00, 0x00, 0x00, 0x00}, + .timeout = {0x00, 0x00, 0x00, 0x00}, + .commandInt = {0x00, 0x00, 0x00, 0x00}, + .datavalid = {0x00, 0x00, 0x00, 0x00}, + .busyoffset = {0x00, 0x00}, + .busybitpolarity = {0x00, 0x00}, + }; + + for (val = strtok(lut_str, ","); val; val = strtok(NULL, ",")) { + fspi_conf_data.lut[i++] = strtoul(val, NULL, 16); + } + + ret = lseek(ifd, 0, SEEK_CUR); + if (write(ifd, &fspi_conf_data, sizeof(fspi_conf_data)) == -1) + exit(EXIT_FAILURE); + + ret = lseek(ifd, sizeof(fspi_conf_data), SEEK_CUR); + + return ret; +} +#endif + void build_image(int ofd) { int file_off, header_hdmi_off = 0, header_image_off; + +#ifdef CONFIG_FSPI_CONF_HEADER + int fspi_off, fspi_fd; + char *fspi; +#endif + int hdmi_fd, ap_fd, sld_fd; uint32_t sld_load_addr = 0; uint32_t csf_off, sld_csf_off = 0; @@ -455,6 +520,20 @@ void build_image(int ofd) header_image_off = file_off + ivt_offset; +#ifdef CONFIG_FSPI_CONF_HEADER + fspi = CONFIG_FSPI_CONF_FILE; + fspi_fd = open(fspi, O_RDWR | O_CREAT, S_IRWXU); + if (fspi_fd < 0) { + fprintf(stderr, "Can't open %s: %s\n", + fspi, strerror(errno)); + exit(EXIT_FAILURE); + } + + fspi_off = generate_fspi_header(fspi_fd); + file_off = header_image_off + fspi_off; + close(fspi_fd); + +#endif ap_fd = open(ap_img, O_RDONLY | O_BINARY); if (ap_fd < 0) { fprintf(stderr, "%s: Can't open: %s\n",