[PATCH v3 0/7] Add support for FlexSPI Boot for i.MX8m

This series of patch adds support for generating FlexSPI Header file and booting from QSPI on i.MX8m.
Changes in v2: -Add check for error in case open() for fspi_fd in imx8mkimage.c fails -Remove extra line in commit message -Remove extra line in imx8mm_evk_fspi_defconfig -New patch in series to add an entry for imx8mm_evk_fspi_defconfig in board/freescale/imx8mm_evk/MAINTAINERS -New patch in series to add instructions to build and boot from QSPI Flash
Changes in v3: -Fix Checkpatch ERROR: code indent should use tabs where possible -Fix Checkpatch ERROR for trailing spaces
Mamta Shukla (7): tools: mkimage: Add support to generate FlexSPI Header for i.MX8m dts: imx8mm-uboot: Add support to pack FlexSPI Header using binman configs: Add config for enabling FSPI boot option for i.MX8m board: freescale: Add QSPI Boot support in spl for i.MX8m configs: imx8mm: Define CONFIG_SYS_UBOOT_BASE for i.MX8m board: freescale: Add entry for imx8mm_evk_fspi_defconfig doc: board: nxp: Add instructions to boot from QSPI
arch/arm/dts/imx8mm-u-boot.dtsi | 20 +++ board/freescale/imx8mm_evk/MAINTAINERS | 1 + .../imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg | 9 ++ board/freescale/imx8mm_evk/spl.c | 2 + configs/imx8mm_evk_fspi_defconfig | 115 ++++++++++++++++++ doc/board/nxp/imx8mm_evk.rst | 37 +++++- include/configs/imx8mm_evk.h | 7 +- include/imximage.h | 38 ++++++ tools/Kconfig | 59 +++++++++ tools/imx8mimage.c | 81 +++++++++++- 10 files changed, 362 insertions(+), 7 deletions(-) create mode 100644 board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg create mode 100644 configs/imx8mm_evk_fspi_defconfig

Add struct with Flex SPI Configuration Block and enable generating fspi header using mkimage.
Refer i.MX 8M Mini Application Processor Reference Manual for detailed information about parameters for FlexSPI Configuration block.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -Add check for error in case open() for fspi_fd in imx8mkimage.c fails
v3: -No changes
include/imximage.h | 38 ++++++++++++++++++++++ tools/Kconfig | 59 +++++++++++++++++++++++++++++++++ tools/imx8mimage.c | 81 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 174 insertions(+), 4 deletions(-)
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 4eed683396..facf8887a1 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -12,7 +12,7 @@ #include "compiler.h"
static uint32_t ap_start_addr, sld_start_addr, sld_src_off; -static char *ap_img, *sld_img, *signed_hdmi; +static char *ap_img, *sld_img, *signed_hdmi, *fspi; static imx_header_v3_t imx_header[2]; /* At most there are 3 IVT headers */ static uint32_t rom_image_offset; static uint32_t sector_size = 0x200; @@ -120,7 +120,6 @@ static void parse_cfg_cmd(int32_t cmd, char *token, char *name, int lineno) rom_version = ROM_V1; } break; - } }
@@ -412,10 +411,70 @@ 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; - int hdmi_fd, ap_fd, sld_fd; + int file_off, header_hdmi_off = 0, header_image_off, fspi_off; + int hdmi_fd, ap_fd, sld_fd, fspi_fd; uint32_t sld_load_addr = 0; uint32_t csf_off, sld_csf_off = 0; int ret; @@ -455,6 +514,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",

On Thu, Jun 9, 2022 at 9:55 AM Mamta Shukla mamta.shukla@leica-geosystems.com wrote:
Add struct with Flex SPI Configuration Block and enable generating fspi header using mkimage.
Refer i.MX 8M Mini Application Processor Reference Manual for detailed information about parameters for FlexSPI Configuration block.
I tested this series on the imx8mm-beacon board. I had a small comment, but this looks nice. Thanks for adding this functionality to the platform.
Tested-by: Adam Ford aford173@gmail.com
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com
v2: -Add check for error in case open() for fspi_fd in imx8mkimage.c fails
v3: -No changes
include/imximage.h | 38 ++++++++++++++++++++++ tools/Kconfig | 59 +++++++++++++++++++++++++++++++++ tools/imx8mimage.c | 81 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 174 insertions(+), 4 deletions(-)
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 4eed683396..facf8887a1 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -12,7 +12,7 @@ #include "compiler.h"
static uint32_t ap_start_addr, sld_start_addr, sld_src_off; -static char *ap_img, *sld_img, *signed_hdmi; +static char *ap_img, *sld_img, *signed_hdmi, *fspi; static imx_header_v3_t imx_header[2]; /* At most there are 3 IVT headers */ static uint32_t rom_image_offset; static uint32_t sector_size = 0x200; @@ -120,7 +120,6 @@ static void parse_cfg_cmd(int32_t cmd, char *token, char *name, int lineno) rom_version = ROM_V1; } break;
}
}
@@ -412,10 +411,70 @@ 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;
int hdmi_fd, ap_fd, sld_fd;
int file_off, header_hdmi_off = 0, header_image_off, fspi_off;
int hdmi_fd, ap_fd, sld_fd, fspi_fd; uint32_t sld_load_addr = 0; uint32_t csf_off, sld_csf_off = 0; int ret;
@@ -455,6 +514,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", -- 2.25.1

Add definition for FSPI configuration block and subsequently new offsets for u-boot-spl and u-boot-itb for CONFIG_FSPI_HEADER option.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -No changes
v3: -Fix Checkpatch ERROR: code indent should use tabs where possible
arch/arm/dts/imx8mm-u-boot.dtsi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi index 9f66cdb65a..69363435b4 100644 --- a/arch/arm/dts/imx8mm-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-u-boot.dtsi @@ -150,6 +150,25 @@ filename = "flash.bin"; pad-byte = <0x00>;
+#ifdef CONFIG_FSPI_CONF_HEADER + fspi_conf_block { + filename = CONFIG_FSPI_CONF_FILE; + type = "blob-ext"; + size = <0x1000>; + }; + + spl { + filename = "spl.bin"; + offset = <0x1000>; + type = "blob-ext"; + }; + + binman_uboot: uboot { + filename = "u-boot.itb"; + offset = <0x58C00>; + type = "blob-ext"; + }; +#else spl { filename = "spl.bin"; offset = <0x0>; @@ -161,6 +180,7 @@ offset = <0x57c00>; type = "blob-ext"; }; +#endif }; };

Add imx8mm_evk_fspi_defconfig to build QSPI boot image. This config is based on imx8mm_evk_defconfig with addtional config options for FSPI Header,SPL offset and imx-image config to boot from FSPI.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -Remove extra line in commit message -Remove extra line in imx8mm_evk_fspi_defconfig -New patch in series to add an entry for imx8mm_evk_fspi_defconfig in board/freescale/imx8mm_evk/MAINTAINERS
v3: -No changes
.../imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg | 9 ++ configs/imx8mm_evk_fspi_defconfig | 115 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg create mode 100644 configs/imx8mm_evk_fspi_defconfig
diff --git a/board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg b/board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg new file mode 100644 index 0000000000..ddcbd11eea --- /dev/null +++ b/board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 NXP + */ + +#define __ASSEMBLY__ + +BOOT_FROM fspi +LOADER u-boot-spl-ddr.bin 0x7E2000 diff --git a/configs/imx8mm_evk_fspi_defconfig b/configs/imx8mm_evk_fspi_defconfig new file mode 100644 index 0000000000..50f6e4779b --- /dev/null +++ b/configs/imx8mm_evk_fspi_defconfig @@ -0,0 +1,115 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8M=y +CONFIG_SYS_TEXT_BASE=0x40200000 +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0x400000 +CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="imx8mm-evk" +CONFIG_SPL_TEXT_BASE=0x7E2000 +CONFIG_TARGET_IMX8MM_EVK=y +CONFIG_IMX_CONFIG="board/freescale/imx8mm_evk/imximage-8mm-lpddr4-fspi.cfg" +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL=y +CONFIG_SYS_LOAD_ADDR=0x40480000 +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_FIT_EXTERNAL_OFFSET=0x3000 +CONFIG_SPL_LOAD_FIT=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOARD_EARLY_INIT=y +CONFIG_BOARD_LATE_INIT=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300 +CONFIG_SPL_I2C=y +CONFIG_SPL_POWER=y +CONFIG_SPL_WATCHDOG=y +CONFIG_SYS_PROMPT="u-boot=> " +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_CLK=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SYS_MMC_ENV_DEV=1 +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_USE_ETHPRIME=y +CONFIG_ETHPRIME="FEC" +CONFIG_SPL_DM=y +CONFIG_SPL_CLK_COMPOSITE_CCF=y +CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_SPL_CLK_IMX8MM=y +CONFIG_CLK_IMX8MM=y +CONFIG_MXC_GPIO=y +CONFIG_DM_I2C=y +CONFIG_DM_MMC=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_ES_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_FSL_USDHC=y +CONFIG_PHYLIB=y +CONFIG_PHY_ATHEROS=y +CONFIG_DM_ETH=y +CONFIG_PHY_GIGE=y +CONFIG_FEC_MXC=y +CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_PINCTRL_IMX8M=y +CONFIG_DM_PMIC=y +CONFIG_SPL_DM_PMIC_PCA9450=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_PWM=y +CONFIG_DM_SERIAL=y +CONFIG_PWM_IMX=y +CONFIG_MXC_UART=y +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_SYSRESET_WATCHDOG=y +CONFIG_DM_THERMAL=y +CONFIG_IMX_WATCHDOG=y +CONFIG_NXP_FSPI=y +CONFIG_SPI=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SF_DEFAULT_BUS=0 +CONFIG_SF_DEFAULT_CS=0 +CONFIG_SF_DEFAULT_SPEED=40000000 +CONFIG_SF_DEFAULT_MODE=0 +CONFIG_FSPI_CONF_HEADER=y +CONFIG_FSPI_CONF_FILE="fspi_header.bin" +CONFIG_READ_CLK_SOURCE=0x00 +CONFIG_DEVICE_TYPE=0x01 +CONFIG_FLASH_PAD_TYPE=0x01 +CONFIG_SERIAL_CLK_FREQUENCY=0x02 +CONFIG_LUT_CUSTOM_SEQUENCE=0x00 +CONFIG_LUT_SEQUENCE="0x0b, 0x04, 0x18, 0x08, 0x08, 0x30, 0x04, 0x24"

Add QSPI Boot option in u-boot-spl for i.MX8m EVK.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -No changes
v3: -No changes
board/freescale/imx8mm_evk/spl.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/freescale/imx8mm_evk/spl.c b/board/freescale/imx8mm_evk/spl.c index 4d96324685..e2eb1426c8 100644 --- a/board/freescale/imx8mm_evk/spl.c +++ b/board/freescale/imx8mm_evk/spl.c @@ -39,6 +39,8 @@ int spl_board_boot_device(enum boot_device boot_dev_spl) case SD3_BOOT: case MMC3_BOOT: return BOOT_DEVICE_MMC2; + case QSPI_BOOT: + return BOOT_DEVICE_NOR; default: return BOOT_DEVICE_NONE; }

The macro `CONFIG_SYS_UBOOT_BASE` is used by SPL loaders `"NOR"` and `"XIP"` to determine the base address of u-boot.
For `"NOR"` on i.MX8MM it is the base address of QSPI0 plus the offset of the flattened image tree blob. Although `QSPI0_AMBA_BASE` is used to define CONFIG_SYS_UBOOT_BASE in multiple board header files for i.MX8MM, it is not specified.
Specify offset of flattened image tree blob (needs to be set to same value as specified in 'binman' node), base address of QSPI0 and size of FlexSPI configuration block.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -No changes
v3: -No changes
include/configs/imx8mm_evk.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h index 5e8f19c43f..1b8d6e6b9f 100644 --- a/include/configs/imx8mm_evk.h +++ b/include/configs/imx8mm_evk.h @@ -13,8 +13,13 @@ #define CONFIG_SYS_BOOTM_LEN (64 * SZ_1M) #define CONFIG_SPL_MAX_SIZE (148 * 1024) #define CONFIG_SYS_MONITOR_LEN SZ_512K +#define UBOOT_ITB_OFFSET 0x57C00 +#define QSPI0_AMBA_BASE 0x08000000 +#define FSPI_CONF_BLOCK_SIZE 0x1000 +#define UBOOT_ITB_OFFSET_FSPI \ + (UBOOT_ITB_OFFSET + FSPI_CONF_BLOCK_SIZE) #define CONFIG_SYS_UBOOT_BASE \ - (QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512) + (QSPI0_AMBA_BASE + UBOOT_ITB_OFFSET_FSPI)
#ifdef CONFIG_SPL_BUILD #define CONFIG_SPL_STACK 0x920000

On Thu, Jun 9, 2022 at 9:56 AM Mamta Shukla mamta.shukla@leica-geosystems.com wrote:
The macro `CONFIG_SYS_UBOOT_BASE` is used by SPL loaders `"NOR"` and `"XIP"` to determine the base address of u-boot.
For `"NOR"` on i.MX8MM it is the base address of QSPI0 plus the offset of the flattened image tree blob. Although `QSPI0_AMBA_BASE` is used to define CONFIG_SYS_UBOOT_BASE in multiple board header files for i.MX8MM, it is not specified.
Specify offset of flattened image tree blob (needs to be set to same value as specified in 'binman' node), base address of QSPI0 and size of FlexSPI configuration block.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com
v2: -No changes
v3: -No changes
include/configs/imx8mm_evk.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h index 5e8f19c43f..1b8d6e6b9f 100644 --- a/include/configs/imx8mm_evk.h +++ b/include/configs/imx8mm_evk.h @@ -13,8 +13,13 @@ #define CONFIG_SYS_BOOTM_LEN (64 * SZ_1M) #define CONFIG_SPL_MAX_SIZE (148 * 1024) #define CONFIG_SYS_MONITOR_LEN SZ_512K +#define UBOOT_ITB_OFFSET 0x57C00 +#define QSPI0_AMBA_BASE 0x08000000
Shouldn't QSPI0_AMBA_BASE go to arch/arm/include/asm/arch-imx8m/imx-regs.h since it's an architecture thing?
+#define FSPI_CONF_BLOCK_SIZE 0x1000
Why not move FSPI_CONF_BLOCK_SIZE into Kconfig with the rest of the stuff you added with FSPI_CONF_HEADER, etc.
+#define UBOOT_ITB_OFFSET_FSPI \
(UBOOT_ITB_OFFSET + FSPI_CONF_BLOCK_SIZE)
#define CONFIG_SYS_UBOOT_BASE \
(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
(QSPI0_AMBA_BASE + UBOOT_ITB_OFFSET_FSPI)
Doesn't this make the offset in the FSPI location even when built for MMC/SD? It seems like there should be an ifdef here to determine if the offset is either the previous or UBOOT_ITB_OFFSET_FSPI
#ifdef CONFIG_SPL_BUILD
#define CONFIG_SPL_STACK 0x920000
2.25.1

Add entry for imx8mm_evk_fspi_defconfig in board/freescale/imx8mm_evk/MAINTAINERS
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -No changes
v3: -No changes
board/freescale/imx8mm_evk/MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
diff --git a/board/freescale/imx8mm_evk/MAINTAINERS b/board/freescale/imx8mm_evk/MAINTAINERS index b031bb0674..875adf58ee 100644 --- a/board/freescale/imx8mm_evk/MAINTAINERS +++ b/board/freescale/imx8mm_evk/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/freescale/imx8mm_evk/ F: include/configs/imx8mm_evk.h F: configs/imx8mm_evk_defconfig +F: configs/imx8mm_evk_fspi_defconfig

Add instructions to build and boot from QSPI Flash.
Signed-off-by: Mamta Shukla mamta.shukla@leica-geosystems.com Signed-off-by: Thomas Haemmerle thomas.haemmerle@leica-geosystems.com --- v2: -No changes
v3: -Fix Checkpatch Error for trailing whitespace
doc/board/nxp/imx8mm_evk.rst | 37 ++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/doc/board/nxp/imx8mm_evk.rst b/doc/board/nxp/imx8mm_evk.rst index b9e67b954f..64f7febdfb 100644 --- a/doc/board/nxp/imx8mm_evk.rst +++ b/doc/board/nxp/imx8mm_evk.rst @@ -35,8 +35,8 @@ Get the ddr firmware $ ./firmware-imx-8.9 $ cp firmware-imx-8.9/firmware/ddr/synopsys/lpddr4*.bin $(builddir)
-Build U-Boot ------------- +Build U-Boot for sd card +--------------------------
.. code-block:: bash
@@ -53,3 +53,36 @@ Burn the flash.bin to MicroSD card offset 33KB: Boot ---- Set Boot switch to SD boot + +Build U-Boot for qspi flash card +------------------------------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-poky-linux- + $ make imx8mm_evk_fspi_defconfig + $ make + +Currently, there is no direct support to write to QSPI Flash. +Copy flash.bin to ${loadaddr} either from sd card or over network and then copy to +qspi flash + +From sd card to memory + +.. code-block:: bash + $mmc dev 1 + $mmc read ${loadaddr} 0x00 <size_of_flash.bin/512> + +.. code-block:: bash + + $ sf probe + $ sf erase 0 <size_of_flash.bin_in_hex> + $ sf write $loadaddr 0x00 <size_of_flash.bin_in_hex> + +Boot from QSPI Flash +----------------------- +Set Boot Switch to QSPI Flash + +Pin configuration for imx8mm_revC evk to boot from qspi flash +SW1101: 0110xxxxxx +SW1102: 00100x0010
participants (2)
-
Adam Ford
-
Mamta Shukla