From 13e012f7b5f31d700185d5c10c6090aec4628164 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:50:59 +0200 Subject: [PATCH 01/59] display5: factory: Add support for BOOT_FROM = FACTORY switch When BOOT_FROM = FACTORY, then the LEG's factory setup is performed. This code relies on boot_nfs u-boot command, so it shall be adjusted appropriately (e.g. provide proper fitImage file). Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/configs/display5.h b/include/configs/display5.h index cff6894..c6a46c8 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -100,7 +100,11 @@ #define CONFIG_BAUDRATE 115200 #ifndef CONFIG_BOOTCOMMAND -#define CONFIG_BOOTCOMMAND "run boot_mmc" +#define CONFIG_BOOTCOMMAND "if test ${BOOT_FROM} = FACTORY; then " \ + "run factory_nfs;" \ + "else " \ + "run boot_mmc;" \ + "fi" #endif #define PARTS_DEFAULT \ @@ -273,6 +277,9 @@ "up=run tftp_sf_SPL; run tftp_sf_uboot\0" \ "download_kernel=" \ "tftpboot ${loadaddr} ${kernel_file};\0" \ + "factory_nfs=" \ + "echo BOOT: FACTORY (LEG);" \ + "run boot_nfs\0" \ "boot_kernel_recovery=" KERNEL_RECOVERY_PROCEDURE "\0" \ "boot_swu_recovery=" SWUPDATE_RECOVERY_PROCEDURE "\0" \ "recovery=" \ From 4864ba7f4acf6a6030d49c0be5565b9161787025 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:00 +0200 Subject: [PATCH 02/59] display5: config: factory: Setup IP config data according to LEG production setup Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/display5.h b/include/configs/display5.h index c6a46c8..bcb1ac2 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -278,6 +278,10 @@ "download_kernel=" \ "tftpboot ${loadaddr} ${kernel_file};\0" \ "factory_nfs=" \ + "setenv ipaddr 192.168.1.102;" \ + "setenv gatewayip 192.168.1.1;" \ + "setenv netmask 255.255.255.0;" \ + "setenv serverip 192.168.1.2;" \ "echo BOOT: FACTORY (LEG);" \ "run boot_nfs\0" \ "boot_kernel_recovery=" KERNEL_RECOVERY_PROCEDURE "\0" \ From 86d759ea3c017a9c4549066a7b73d5e644f3d538 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:01 +0200 Subject: [PATCH 03/59] display5: config: Add "factory" (1MiB) SPI-NOR partition in u-boot To test if this partition is present - one needs to write: display5 > sf probe; mtdparts display5 > sf erase factory +0x100000 Signed-off-by: Lukasz Majewski --- configs/display5_defconfig | 2 +- include/configs/display5.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/display5_defconfig b/configs/display5_defconfig index 4db8a2b..ee0947f 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -48,7 +48,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" -CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),8m(lin-recovery),4m(swu-kernel),8m(swu-initramfs),-(reserved)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),8m(lin-recovery),4m(swu-kernel),8m(swu-initramfs),1m(factory),-(reserved)" CONFIG_EFI_PARTITION=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y diff --git a/include/configs/display5.h b/include/configs/display5.h index bcb1ac2..f4aa6d5 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -33,6 +33,7 @@ * 0x140000 - 0x940000 : SPI.fitImage-recovery (8MiB) * 0x940000 - 0xD40000 : SPI.swupdate-kernel-FIT (4MiB) * 0xD40000 - 0x1540000 : SPI.swupdate-initramfs (8MiB) + * 0x1540000 - 0x1640000 : SPI.factory (1MiB) */ #ifndef CONFIG_SPL_BUILD From 2f4372a101c235c6cf2b337df4c989e540b1b3e4 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:02 +0200 Subject: [PATCH 04/59] display5: config: Provide command to flash the whole SPI-NOR memory It may be necessary to update the content of the whole SPI-NOR memory at once with using a single command (tftp_sf_img). Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/configs/display5.h b/include/configs/display5.h index f4aa6d5..3cb6365 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -253,6 +253,16 @@ "sf write ${loadaddr} 0x400 ${filesize};" \ "fi\0" \ +#define TFTP_UPDATE_SPINOR \ + "spinorfile=core-image-lwn-display5.spinor\0" \ + "spinorsize=0x2000000\0" \ + "tftp_sf_img=" \ + "if tftp ${loadaddr} ${spinorfile}; then " \ + "sf probe;" \ + "sf erase 0x0 ${spinorsize};" \ + "sf write ${loadaddr} 0x0 ${filesize};" \ + "fi\0" \ + #define CONFIG_EXTRA_ENV_SETTINGS \ PARTS_DEFAULT \ "display=tianma-tm070-800x480\0" \ @@ -353,6 +363,7 @@ "BOOT_FROM=ACTIVE\0" \ "BOOT_FROM_RECOVERY=Linux\0" \ TFTP_UPDATE_BOOTLOADER \ + TFTP_UPDATE_SPINOR \ "kernel_part_active=1\0" \ "kernel_part_backup=3\0" \ __TFTP_UPDATE_KERNEL \ From e087905a48ee8042ffdd9531b6aada6be2751ed1 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:03 +0200 Subject: [PATCH 05/59] display5: spl: Check return code of the env_* functions Force booting through u-boot proper when environment error encountered (as a result of either broken SPI-NOR or erased envs). Signed-off-by: Lukasz Majewski --- board/liebherr/display5/spl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c index 6508e0f..0d25b0d 100644 --- a/board/liebherr/display5/spl.c +++ b/board/liebherr/display5/spl.c @@ -210,8 +210,8 @@ void board_boot_order(u32 *spl_boot_list) /* 'fastboot' */ const char *s; - env_init(); - env_load(); + if (env_init() || env_load()) + return; s = env_get("BOOT_FROM"); if (s && !bootcount_error() && strcmp(s, "ACTIVE") == 0) { From 1bcbf48f18dcd7c986166016105d0ccba5060b27 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:04 +0200 Subject: [PATCH 06/59] display5: config: Reset the board when bootm fails Since display5 is now supporting boot counting, we can just reset the board when bootm fails (i.e. it doesn't boot the fitImage kernel for any reason). Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/configs/display5.h b/include/configs/display5.h index 3cb6365..420ced7 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -151,7 +151,7 @@ "sf probe;" \ "sf read ${loadaddr} swu-kernel;" \ "sf read ${loadaddr_swu_initramfs} swu-initramfs;" \ - "bootm ${loadaddr} ${loadaddr_swu_initramfs};" + "bootm ${loadaddr} ${loadaddr_swu_initramfs};reset;" #define KERNEL_RECOVERY_PROCEDURE \ "echo '#######################';" \ @@ -159,7 +159,7 @@ "echo '#######################';" \ "sf probe;" \ "sf read ${loadaddr} lin-recovery;" \ - "bootm;" + "bootm;reset;" #define SETUP_BOOTARGS \ "run set_rootfs_part;" \ @@ -309,7 +309,7 @@ "if run download_kernel; then " \ "setenv bootargs console=${console} " \ "root=/dev/mmcblk0p2 rootwait;" \ - "bootm ${loadaddr} - ${fdtaddr};" \ + "bootm ${loadaddr} - ${fdtaddr};reset;" \ "fi\0" \ "addip=setenv bootargs ${bootargs} " \ "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \ @@ -326,7 +326,7 @@ "run addip;" \ "setenv bootargs ${bootargs} console=${console};" \ "setenv fdt_conf imx6q-${board}-${display}.dtb; " \ - "bootm ${loadaddr}#conf@${fdt_conf};" \ + "bootm ${loadaddr}#conf@${fdt_conf};reset;" \ "fi\0" \ "falcon_setup=" \ "if mmc dev ${mmcdev}; then " \ @@ -340,7 +340,7 @@ "boot_mmc=" \ "if mmc dev ${mmcdev}; then " \ SETUP_BOOTARGS \ - "bootm ${loadaddr}#conf@${fdt_conf};" \ + "bootm ${loadaddr}#conf@${fdt_conf};reset;" \ "fi\0" \ "set_kernel_part=" \ "if test ${BOOT_FROM} = ACTIVE; then " \ From b78e9c4f1e6442d33c48eec482022d8f13f7112a Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:05 +0200 Subject: [PATCH 07/59] display5: config: Remove support for Linux initramfs recovery image boot This is a prerequisite patch to combine SWUpdate and Linux recovery initramfs images. It removes the support for it. Signed-off-by: Lukasz Majewski --- configs/display5_defconfig | 2 +- configs/display5_factory_defconfig | 2 +- include/configs/display5.h | 29 +---------------------------- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/configs/display5_defconfig b/configs/display5_defconfig index ee0947f..196b202 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -48,7 +48,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" -CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),8m(lin-recovery),4m(swu-kernel),8m(swu-initramfs),1m(factory),-(reserved)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),8m(swu-initramfs),1m(factory),-(reserved)" CONFIG_EFI_PARTITION=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig index 10b025c..e1b5334 100644 --- a/configs/display5_factory_defconfig +++ b/configs/display5_factory_defconfig @@ -53,7 +53,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" -CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),8m(lin-recovery),4m(swu-kernel),8m(swu-initramfs),-(reserved)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),8m(swu-initramfs),-(reserved)" # CONFIG_SPL_EFI_PARTITION is not set CONFIG_PARTITION_TYPE_GUID=y CONFIG_ENV_IS_IN_SPI_FLASH=y diff --git a/include/configs/display5.h b/include/configs/display5.h index 420ced7..9bae8bc 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -30,7 +30,6 @@ * 0x020000 - 0x120000 : SPI.u-boot (1MiB) * 0x120000 - 0x130000 : SPI.u-boot-env1 (64KiB) * 0x130000 - 0x140000 : SPI.u-boot-env2 (64KiB) - * 0x140000 - 0x940000 : SPI.fitImage-recovery (8MiB) * 0x940000 - 0xD40000 : SPI.swupdate-kernel-FIT (4MiB) * 0xD40000 - 0x1540000 : SPI.swupdate-initramfs (8MiB) * 0x1540000 - 0x1640000 : SPI.factory (1MiB) @@ -128,7 +127,6 @@ "run tftp_sf_SPL;" \ "run tftp_sf_uboot;" \ TFTP_UPDATE_KERNEL \ - "run tftp_sf_fitImg_recovery;" \ "run tftp_sf_fitImg_SWU;" \ "run tftp_sf_initramfs_SWU;" \ TFTP_UPDATE_ROOTFS \ @@ -153,14 +151,6 @@ "sf read ${loadaddr_swu_initramfs} swu-initramfs;" \ "bootm ${loadaddr} ${loadaddr_swu_initramfs};reset;" -#define KERNEL_RECOVERY_PROCEDURE \ - "echo '#######################';" \ - "echo '# RECOVERY KERNEL IMG #';" \ - "echo '#######################';" \ - "sf probe;" \ - "sf read ${loadaddr} lin-recovery;" \ - "bootm;reset;" - #define SETUP_BOOTARGS \ "run set_rootfs_part;" \ "setenv bootargs ${bootargs} console=${console} " \ @@ -227,15 +217,6 @@ "sf write ${loadaddr} swu-initramfs ${filesize};" \ "; fi\0" \ -#define TFTP_UPDATE_RECOVERY_KERNEL_INITRAMFS \ - "kernel_recovery_file=fitImage-initramfs\0" \ - "tftp_sf_fitImg_recovery=" \ - "if tftp ${loadaddr} ${kernel_recovery_file}; then " \ - "sf probe;" \ - "sf erase lin-recovery +${filesize};" \ - "sf write ${loadaddr} lin-recovery ${filesize};" \ - "; fi\0" \ - #define TFTP_UPDATE_BOOTLOADER \ "ubootfile=u-boot.img\0" \ "ubootfileSPL=SPL\0" \ @@ -295,16 +276,10 @@ "setenv serverip 192.168.1.2;" \ "echo BOOT: FACTORY (LEG);" \ "run boot_nfs\0" \ - "boot_kernel_recovery=" KERNEL_RECOVERY_PROCEDURE "\0" \ "boot_swu_recovery=" SWUPDATE_RECOVERY_PROCEDURE "\0" \ "recovery=" \ - "if test ${BOOT_FROM_RECOVERY} = SWU; then " \ "echo BOOT: RECOVERY: SWU;" \ - "run boot_swu_recovery;" \ - "else " \ - "echo BOOT: RECOVERY: Linux;" \ - "run boot_kernel_recovery;" \ - "fi\0" \ + "run boot_swu_recovery\0" \ "boot_tftp=" \ "if run download_kernel; then " \ "setenv bootargs console=${console} " \ @@ -361,7 +336,6 @@ "run recovery;" \ "fi;fi\0" \ "BOOT_FROM=ACTIVE\0" \ - "BOOT_FROM_RECOVERY=Linux\0" \ TFTP_UPDATE_BOOTLOADER \ TFTP_UPDATE_SPINOR \ "kernel_part_active=1\0" \ @@ -371,7 +345,6 @@ "rootfs_part_backup=4\0" \ "rootfs_file=core-image-lwn-display5.ext4\0" \ __TFTP_UPDATE_ROOTFS \ - TFTP_UPDATE_RECOVERY_KERNEL_INITRAMFS \ TFTP_UPDATE_RECOVERY_SWU_KERNEL \ TFTP_UPDATE_RECOVERY_SWU_INITRAMFS \ "\0" \ From 1fa328f73a6b4f69f8d3132884f797b15bb23bbd Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:06 +0200 Subject: [PATCH 08/59] display5: config: Update SPI-NOR partition for larger swupdate-initramfs The SPI-NOR partition information has been updated to store swupdate-kernel-FIT just after envs as well as two times larger swupdate-initramfs image. Signed-off-by: Lukasz Majewski --- configs/display5_defconfig | 2 +- configs/display5_factory_defconfig | 2 +- include/configs/display5.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/display5_defconfig b/configs/display5_defconfig index 196b202..04671ab 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -48,7 +48,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" -CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),8m(swu-initramfs),1m(factory),-(reserved)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),1m(factory),-(reserved)" CONFIG_EFI_PARTITION=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig index e1b5334..7b3684e 100644 --- a/configs/display5_factory_defconfig +++ b/configs/display5_factory_defconfig @@ -53,7 +53,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" -CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),8m(swu-initramfs),-(reserved)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),-(reserved)" # CONFIG_SPL_EFI_PARTITION is not set CONFIG_PARTITION_TYPE_GUID=y CONFIG_ENV_IS_IN_SPI_FLASH=y diff --git a/include/configs/display5.h b/include/configs/display5.h index 9bae8bc..f5656a2 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -30,8 +30,8 @@ * 0x020000 - 0x120000 : SPI.u-boot (1MiB) * 0x120000 - 0x130000 : SPI.u-boot-env1 (64KiB) * 0x130000 - 0x140000 : SPI.u-boot-env2 (64KiB) - * 0x940000 - 0xD40000 : SPI.swupdate-kernel-FIT (4MiB) - * 0xD40000 - 0x1540000 : SPI.swupdate-initramfs (8MiB) + * 0x140000 - 0x540000 : SPI.swupdate-kernel-FIT (4MiB) + * 0x540000 - 0x1540000 : SPI.swupdate-initramfs (16MiB) * 0x1540000 - 0x1640000 : SPI.factory (1MiB) */ From cf74e0a96b0f99c4c6025f07549cc51e06a772e0 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:07 +0200 Subject: [PATCH 09/59] display5: config: factory: Extend mtdparts to support LEG factory partition This special partition has been added solely for production purpose. Signed-off-by: Lukasz Majewski --- configs/display5_factory_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig index 7b3684e..e23948b 100644 --- a/configs/display5_factory_defconfig +++ b/configs/display5_factory_defconfig @@ -53,7 +53,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" -CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),-(reserved)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),1m(factory),-(reserved)" # CONFIG_SPL_EFI_PARTITION is not set CONFIG_PARTITION_TYPE_GUID=y CONFIG_ENV_IS_IN_SPI_FLASH=y From 27aede24bcdec3777da7b23efc0a8cb777d83d6a Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:08 +0200 Subject: [PATCH 10/59] display5: Support for the emergency PAD pressing To enter the special mode, one needs to short cut two pads with e.g. screw driver. After power up the SPL will execute u-boot in which proper actions will be taken. It is worth noting that we do not alter envs (even the BOOT_FROM variable) and unconditionally go to recovery. Signed-off-by: Lukasz Majewski --- board/liebherr/display5/common.c | 10 ++++++++++ board/liebherr/display5/common.h | 1 + board/liebherr/display5/display5.c | 19 +++++++++++++++++++ board/liebherr/display5/spl.c | 22 ++++++++++++++++++++++ include/configs/display5.h | 8 ++++++-- 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/board/liebherr/display5/common.c b/board/liebherr/display5/common.c index 26575f7..4eb86d8 100644 --- a/board/liebherr/display5/common.c +++ b/board/liebherr/display5/common.c @@ -34,6 +34,16 @@ void displ5_set_iomux_uart(void) SETUP_IOMUX_PADS(uart_pads); } +iomux_v3_cfg_t const misc_pads_spl[] = { + /* Emergency recovery pin */ + MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +void displ5_set_iomux_misc_spl(void) +{ + SETUP_IOMUX_PADS(misc_pads_spl); +} + #ifdef CONFIG_MXC_SPI iomux_v3_cfg_t const ecspi_pads[] = { /* SPI3 */ diff --git a/board/liebherr/display5/common.h b/board/liebherr/display5/common.h index a507ef9..78c64b0 100644 --- a/board/liebherr/display5/common.h +++ b/board/liebherr/display5/common.h @@ -37,5 +37,6 @@ void displ5_set_iomux_ecspi_spl(void); void displ5_set_iomux_ecspi(void); void displ5_set_iomux_usdhc_spl(void); void displ5_set_iomux_usdhc(void); +void displ5_set_iomux_misc_spl(void); #endif /* __DISPL5_COMMON_H_ */ diff --git a/board/liebherr/display5/display5.c b/board/liebherr/display5/display5.c index ebc643e..4bade47 100644 --- a/board/liebherr/display5/display5.c +++ b/board/liebherr/display5/display5.c @@ -44,6 +44,7 @@ static bool sw_ids_valid; static u32 cpu_id; static u32 unit_id; +#define EM_PAD IMX_GPIO_NR(3, 29) #define SW0 IMX_GPIO_NR(2, 4) #define SW1 IMX_GPIO_NR(2, 5) #define SW2 IMX_GPIO_NR(2, 6) @@ -179,6 +180,9 @@ iomux_v3_cfg_t const misc_pads[] = { /* XTALOSC */ MX6_PAD_GPIO_3__XTALOSC_REF_CLK_24M | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* Emergency recovery pin */ + MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), }; #ifdef CONFIG_FSL_ESDHC @@ -369,7 +373,22 @@ static inline void setup_boot_modes(void) {} int misc_init_r(void) { + int ret; + setup_boot_modes(); + + ret = gpio_request(EM_PAD, "Emergency_PAD"); + if (ret) { + printf("Can't request emergency PAD gpio\n"); + return ret; + } + + ret = gpio_direction_input(EM_PAD); + if (ret) { + printf("Can't set emergency PAD direction\n"); + return ret; + } + return 0; } diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c index 0d25b0d..551a143 100644 --- a/board/liebherr/display5/spl.c +++ b/board/liebherr/display5/spl.c @@ -16,6 +16,7 @@ #include #include "asm/arch/iomux.h" #include +#include #include #include #include @@ -194,10 +195,24 @@ void board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); + displ5_set_iomux_misc_spl(); + /* load/boot image from boot device */ board_init_r(NULL, 0); } +#define EM_PAD IMX_GPIO_NR(3, 29) +int board_check_emergency_pad(void) +{ + int ret; + + ret = gpio_direction_input(EM_PAD); + if (ret) + return ret; + + return !gpio_get_value(EM_PAD); +} + void board_boot_order(u32 *spl_boot_list) { /* Default boot sequence SPI -> MMC */ @@ -206,6 +221,13 @@ void board_boot_order(u32 *spl_boot_list) spl_boot_list[2] = BOOT_DEVICE_UART; spl_boot_list[3] = BOOT_DEVICE_NONE; + /* + * In case of emergency PAD pressed, we always boot + * to proper u-boot and perform recovery tasks there. + */ + if (board_check_emergency_pad()) + return; + #ifdef CONFIG_SPL_ENV_SUPPORT /* 'fastboot' */ const char *s; diff --git a/include/configs/display5.h b/include/configs/display5.h index f5656a2..c4cd2ff 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -100,11 +100,13 @@ #define CONFIG_BAUDRATE 115200 #ifndef CONFIG_BOOTCOMMAND -#define CONFIG_BOOTCOMMAND "if test ${BOOT_FROM} = FACTORY; then " \ +#define CONFIG_BOOTCOMMAND "if run check_em_pad; then " \ + "run recovery;" \ + "else if test ${BOOT_FROM} = FACTORY; then " \ "run factory_nfs;" \ "else " \ "run boot_mmc;" \ - "fi" + "fi;fi" #endif #define PARTS_DEFAULT \ @@ -246,6 +248,8 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ PARTS_DEFAULT \ + "gpio_recovery=93\0" \ + "check_em_pad=gpio input ${gpio_recovery};test $? -eq 0;\0" \ "display=tianma-tm070-800x480\0" \ "board=display5\0" \ "mmcdev=0\0" \ From 76d1d169f302b533249aa1fb84b765af0722a629 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:09 +0200 Subject: [PATCH 11/59] display5: wdt: Enable WDT support (both SPL and u-boot) Test case: The fitImage gets corrupted: truncate -c -s 3M fitImage run tftp_mmc_fitImg setenv boot_os y reset [board shall hang in SPL with "Trying to boot from MMC1" information] Then after X seconds WDT is causing board to reset. After N boot attempts we enter recovery mode. Signed-off-by: Lukasz Majewski --- board/liebherr/display5/spl.c | 5 +++++ configs/display5_defconfig | 1 + configs/display5_factory_defconfig | 1 + include/configs/display5.h | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c index 551a143..5c6b8bf 100644 --- a/board/liebherr/display5/spl.c +++ b/board/liebherr/display5/spl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "common.h" DECLARE_GLOBAL_DATA_PTR; @@ -197,6 +198,10 @@ void board_init_f(ulong dummy) displ5_set_iomux_misc_spl(); + /* Initialize and reset WDT in SPL */ + hw_watchdog_init(); + WATCHDOG_RESET(); + /* load/boot image from boot device */ board_init_r(NULL, 0); } diff --git a/configs/display5_defconfig b/configs/display5_defconfig index 04671ab..aaf8529 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_DEFAULT_DEVICE_TREE="imx6q-display5" CONFIG_FIT=y CONFIG_SPL_LOAD_FIT=y diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig index e23948b..14df849 100644 --- a/configs/display5_factory_defconfig +++ b/configs/display5_factory_defconfig @@ -9,6 +9,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_FIT=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6Q" diff --git a/include/configs/display5.h b/include/configs/display5.h index c4cd2ff..929741d 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -383,6 +383,11 @@ #define CONFIG_MTD_PARTITIONS #define CONFIG_MTD_DEVICE +/* Watchdog */ +#define CONFIG_HW_WATCHDOG +#define CONFIG_IMX_WATCHDOG +#define CONFIG_WATCHDOG_TIMEOUT_MSECS 15000 + /* ENV config */ #ifdef CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SIZE (SZ_64K) From dd4ed88bf13d5357038446a6839ff9808d4981b4 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:10 +0200 Subject: [PATCH 12/59] display5: config: Provide 'tftp_mmc_rootfs_bkp' command to write BACKUP rootfs Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/configs/display5.h b/include/configs/display5.h index 929741d..fed8880 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -348,7 +348,12 @@ "rootfs_part_active=2\0" \ "rootfs_part_backup=4\0" \ "rootfs_file=core-image-lwn-display5.ext4\0" \ + "rootfs_file_backup=core-image-lwn-backup-display5.ext4\0" \ __TFTP_UPDATE_ROOTFS \ + "tftp_mmc_rootfs_bkp=" \ + "setenv rootfs_part ${rootfs_part_backup};" \ + "setenv rootfs_file ${rootfs_file_backup};" \ + "run tftp_mmc_rootfs\0" \ TFTP_UPDATE_RECOVERY_SWU_KERNEL \ TFTP_UPDATE_RECOVERY_SWU_INITRAMFS \ "\0" \ From 18ccca59e31bcf415b469ef2c71bfe9c14dbc6e3 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:11 +0200 Subject: [PATCH 13/59] display5: config: factory: Update BACKUP rootfs in factory mode After splitting rootfs images to BACKUP and ACTIVE, the "factory" u-boot also needs to update the former. Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/configs/display5.h b/include/configs/display5.h index fed8880..6b428c1 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -194,13 +194,11 @@ "mmc write ${loadaddr} ${lba_start} ${fw_sz}; " \ "; fi\0" \ -/* To save some considerable time, we only once download the rootfs image */ -/* and store it on 'active' and 'backup' rootfs partitions */ #define TFTP_UPDATE_ROOTFS \ "setenv rootfs_part ${rootfs_part_active};" \ "run tftp_mmc_rootfs;" \ - "part start mmc ${mmcdev} ${rootfs_part_backup} lba_start;" \ - "mmc write ${loadaddr} ${lba_start} ${fw_sz};" \ + "run tftp_mmc_rootfs_bkp;" \ + #define TFTP_UPDATE_RECOVERY_SWU_KERNEL \ "tftp_sf_fitImg_SWU=" \ From b5f4543c92dd7be011b9729ee9c998c0e805c23e Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:12 +0200 Subject: [PATCH 14/59] display5: config: Update swupdate initramfs file name (now supporting ext4) After moving to swupdate 2017.07, the default fs for swupdate rootfs is ext4, not ext3. Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/display5.h b/include/configs/display5.h index 6b428c1..1f76d90 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -209,7 +209,7 @@ "; fi\0" \ #define TFTP_UPDATE_RECOVERY_SWU_INITRAMFS \ - "swu_initramfs_file=swupdate-image-display5.ext3.gz.u-boot\0" \ + "swu_initramfs_file=swupdate-image-display5.ext4.gz.u-boot\0" \ "tftp_sf_initramfs_SWU=" \ "if tftp ${loadaddr} ${swu_initramfs_file}; then " \ "sf probe;" \ From ea4584d73d731c49cc838cae3955a2ef92d5eff7 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:13 +0200 Subject: [PATCH 15/59] display5: ddr: Enable support for DDR3 auto calibration This code performs DDR3 memory calibration for display5 board. Signed-off-by: Lukasz Majewski --- board/liebherr/display5/spl.c | 47 +++++++++++++++++++++++++++++++++++++++++++ configs/display5_defconfig | 1 + 2 files changed, 48 insertions(+) diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c index 5c6b8bf..0c0172e 100644 --- a/board/liebherr/display5/spl.c +++ b/board/liebherr/display5/spl.c @@ -117,6 +117,49 @@ static void ccgr_init(void) writel(0x000003FF, &ccm->CCGR6); } +#ifdef CONFIG_MX6_DDRCAL +static void spl_dram_print_cal(struct mx6_ddr_sysinfo const *sysinfo) +{ + struct mx6_mmdc_calibration calibration = {0}; + + mmdc_read_calibration(sysinfo, &calibration); + + debug(".p0_mpdgctrl0\t= 0x%08X\n", calibration.p0_mpdgctrl0); + debug(".p0_mpdgctrl1\t= 0x%08X\n", calibration.p0_mpdgctrl1); + debug(".p0_mprddlctl\t= 0x%08X\n", calibration.p0_mprddlctl); + debug(".p0_mpwrdlctl\t= 0x%08X\n", calibration.p0_mpwrdlctl); + debug(".p0_mpwldectrl0\t= 0x%08X\n", calibration.p0_mpwldectrl0); + debug(".p0_mpwldectrl1\t= 0x%08X\n", calibration.p0_mpwldectrl1); + debug(".p1_mpdgctrl0\t= 0x%08X\n", calibration.p1_mpdgctrl0); + debug(".p1_mpdgctrl1\t= 0x%08X\n", calibration.p1_mpdgctrl1); + debug(".p1_mprddlctl\t= 0x%08X\n", calibration.p1_mprddlctl); + debug(".p1_mpwrdlctl\t= 0x%08X\n", calibration.p1_mpwrdlctl); + debug(".p1_mpwldectrl0\t= 0x%08X\n", calibration.p1_mpwldectrl0); + debug(".p1_mpwldectrl1\t= 0x%08X\n", calibration.p1_mpwldectrl1); +} + +static void spl_dram_perform_cal(struct mx6_ddr_sysinfo const *sysinfo) +{ + int ret; + + /* Perform DDR DRAM calibration */ + udelay(100); + ret = mmdc_do_write_level_calibration(sysinfo); + if (ret) { + printf("DDR: Write level calibration error [%d]\n", ret); + return; + } + + ret = mmdc_do_dqs_calibration(sysinfo); + if (ret) { + printf("DDR: DQS calibration error [%d]\n", ret); + return; + } + + spl_dram_print_cal(sysinfo); +} +#endif /* CONFIG_MX6_DDRCAL */ + static void spl_dram_init(void) { struct mx6_ddr_sysinfo sysinfo = { @@ -143,6 +186,10 @@ static void spl_dram_init(void) mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); mx6_dram_cfg(&sysinfo, &mx6_4x256mx16_mmdc_calib, &mt41k128m16jt_125); + +#ifdef CONFIG_MX6_DDRCAL + spl_dram_perform_cal(&sysinfo); +#endif } #ifdef CONFIG_SPL_SPI_SUPPORT diff --git a/configs/display5_defconfig b/configs/display5_defconfig index aaf8529..6ae6d05 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_TEXT_BASE=0x17800000 CONFIG_SPL_GPIO_SUPPORT=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_MX6_DDRCAL=y CONFIG_TARGET_DISPLAY5=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y From c451713abf10db335cabe41099e8b28481a723b7 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:14 +0200 Subject: [PATCH 16/59] display5: net: Add function to read ethaddr from iMX6 fuses Signed-off-by: Lukasz Majewski --- board/liebherr/display5/display5.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/board/liebherr/display5/display5.c b/board/liebherr/display5/display5.c index 4bade47..a3deba2 100644 --- a/board/liebherr/display5/display5.c +++ b/board/liebherr/display5/display5.c @@ -254,6 +254,25 @@ static void setup_iomux_enet(void) gpio_direction_input(IMX_GPIO_NR(1, 28)); /*INT#_GBE*/ } +static int setup_mac_from_fuse(void) +{ + unsigned char enetaddr[6]; + int ret; + + ret = eth_env_get_enetaddr("ethaddr", enetaddr); + if (ret) /* ethaddr is already set */ + return 0; + + imx_get_mac_from_fuse(0, enetaddr); + + if (is_valid_ethaddr(enetaddr)) { + eth_env_set_enetaddr("ethaddr", enetaddr); + return 0; + } + + return 0; +} + int board_eth_init(bd_t *bd) { struct phy_device *phydev; @@ -268,6 +287,8 @@ int board_eth_init(bd_t *bd) if (ret) return ret; + setup_mac_from_fuse(); + bus = fec_get_miibus(IMX_FEC_BASE, -1); if (!bus) return -ENODEV; From 5d9254098c1063b55fd3d8d275b7cadcb396592d Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:15 +0200 Subject: [PATCH 17/59] display5: config: Add cma=256M to command line arguments Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/display5.h b/include/configs/display5.h index 1f76d90..f2fa824 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -263,7 +263,7 @@ "hostname=display5\0" \ "loadaddr=0x12000000\0" \ "fdtaddr=0x12800000\0" \ - "console=ttymxc4,115200 quiet\0" \ + "console=ttymxc4,115200 quiet cma=256M\0" \ "fdtfile=imx6q-display5.dtb\0" \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ From 9fea1ca013a322fca53cc1274f5479ccda6c7210 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:16 +0200 Subject: [PATCH 18/59] display5: config: Reduce rootfs2 (BACKUP) size from 1528M to 512M Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/display5.h b/include/configs/display5.h index f2fa824..1456cf4 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -116,7 +116,7 @@ "name=kernel_raw1,start=128K,size=8M,uuid=${uuid_gpt_kernel_raw1};" \ "name=rootfs1,size=1528M,uuid=${uuid_gpt_rootfs1};" \ "name=kernel_raw2,size=8M,uuid=${uuid_gpt_kernel_raw2};" \ - "name=rootfs2,size=1528M,uuid=${uuid_gpt_rootfs2};" \ + "name=rootfs2,size=512M,uuid=${uuid_gpt_rootfs2};" \ "name=data,size=-,uuid=${uuid_gpt_data}\0" #define FACTORY_PROCEDURE \ From bfb504bc7efb0bae6f0f8e865f79062d5ed6b014 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:17 +0200 Subject: [PATCH 19/59] display5: display5_defconfig: Enable support for gpt command (CMD_GPT) in production u-boot After this change one can run 'gpt' command on production u-boot. Signed-off-by: Lukasz Majewski --- configs/display5_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/display5_defconfig b/configs/display5_defconfig index 6ae6d05..f51fbd4 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -34,6 +34,7 @@ CONFIG_CMD_ASKENV=y CONFIG_CRC32_VERIFY=y CONFIG_CMD_EEPROM=y CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_PART=y @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=02008000.spi.1" CONFIG_MTDPARTS_DEFAULT="mtdparts=02008000.spi.1:128k(SPL),1m(u-boot),64k(env1),64k(env2),4m(swu-kernel),16m(swu-initramfs),1m(factory),-(reserved)" -CONFIG_EFI_PARTITION=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y CONFIG_ENV_IS_IN_SPI_FLASH=y From 0f05512d1135b034d09b058e2826d9c59cc26a7d Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:18 +0200 Subject: [PATCH 20/59] display5: config: Add GPT verification and restoration code on SWUpdate entry If GPT gets broken, then after N boot attempts we will run the SWUpdate restoration image. On its enter we will check GPT and restore it if needed. To test it: display5 > mmc write 0x12000000 4 8 It will overwrite the primary GPT table. Signed-off-by: Lukasz Majewski --- include/configs/display5.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/configs/display5.h b/include/configs/display5.h index 1456cf4..f3c8757 100644 --- a/include/configs/display5.h +++ b/include/configs/display5.h @@ -144,6 +144,16 @@ "echo '#######################';" \ "echo '# RECOVERY SWUupdate #';" \ "echo '#######################';" \ + "echo '#######################';" \ + "echo '# GPT verify #';" \ + "if gpt verify mmc ${mmcdev} ${partitions}; then " \ + "echo '# OK ! #';" \ + "else " \ + "echo '# FAILED ! #';" \ + "echo '# GPT RESTORATION #';" \ + "gpt write mmc ${mmcdev} ${partitions};" \ + "fi;" \ + "echo '#######################';" \ "setenv loadaddr_swu_initramfs 0x14000000;" \ "setenv bootargs console=${console} " \ "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ From 2c09dbf4250be1f6c8fc391cc1882df35b47a421 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 11 May 2018 16:51:19 +0200 Subject: [PATCH 21/59] display5: Add missing environment.h include to avoid warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this change the following warning shows up when building: board/liebherr/display5/display5.c:270:3: warning: implicit declaration of function ‘eth_env_set_enetaddr’ [-Wimplicit-function-declaration] This commit fixes this issue. Signed-off-by: Lukasz Majewski --- board/liebherr/display5/display5.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/liebherr/display5/display5.c b/board/liebherr/display5/display5.c index a3deba2..d838317 100644 --- a/board/liebherr/display5/display5.c +++ b/board/liebherr/display5/display5.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include From c5437e5b8aff9c952ebaab9be7670439c141e4e7 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 14 May 2018 09:44:29 -0300 Subject: [PATCH 22/59] imx: Enable ACTLR.SMP bit for all i.MX cortex-a7 platforms According to the Cortex-A7 TRM, for ACTLR.SMP bit "You must ensure this bit is set to 1 before the caches and MMU are enabled, or any cache and TLB maintenance operations are performed". ROM sets this bit in normal boot flow, but when in serial download mode, it is not set. Here we add it in u-boot as a common flow for all i.MX cortex-a7 platforms, including mx7d, mx6ul/ull and mx7ulp. Signed-off-by: Ye Li [fabio: adapted to U-Boot mainline codebase and make checkpatch happy] Signed-off-by: Fabio Estevam --- arch/arm/mach-imx/cache.c | 42 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/mx7/soc.c | 7 ------- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c index 11f90ed..82257f3 100644 --- a/arch/arm/mach-imx/cache.c +++ b/arch/arm/mach-imx/cache.c @@ -9,6 +9,34 @@ #include #include +static void enable_ca7_smp(void) +{ + u32 val; + + /* Read MIDR */ + asm volatile ("mrc p15, 0, %0, c0, c0, 0\n\t" : "=r"(val)); + val = (val >> 4); + val &= 0xf; + + /* Only set the SMP for Cortex A7 */ + if (val == 0x7) { + /* Read auxiliary control register */ + asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" : "=r"(val)); + + if (val & (1 << 6)) + return; + + /* Enable SMP */ + val |= (1 << 6); + + /* Write auxiliary control register */ + asm volatile ("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r"(val)); + + DSB; + ISB; + } +} + #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) { @@ -20,6 +48,9 @@ void enable_caches(void) /* Avoid random hang when download by usb */ invalidate_dcache_all(); + /* Set ACTLR.SMP bit for Cortex-A7 */ + enable_ca7_smp(); + /* Enable D-cache. I-cache is already enabled in start.S */ dcache_enable(); @@ -31,6 +62,17 @@ void enable_caches(void) IRAM_SIZE, option); } +#else +void enable_caches(void) +{ + /* + * Set ACTLR.SMP bit for Cortex-A7, even if the caches are + * disabled by u-boot + */ + enable_ca7_smp(); + + puts("WARNING: Caches not enabled\n"); +} #endif #ifndef CONFIG_SYS_L2CACHE_OFF diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c index f1dea66..2aca24b 100644 --- a/arch/arm/mach-imx/mx7/soc.c +++ b/arch/arm/mach-imx/mx7/soc.c @@ -280,13 +280,6 @@ const struct boot_mode soc_boot_modes[] = { void s_init(void) { -#if !defined CONFIG_SPL_BUILD - /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ - asm volatile( - "mrc p15, 0, r0, c1, c0, 1\n" - "orr r0, r0, #1 << 6\n" - "mcr p15, 0, r0, c1, c0, 1\n"); -#endif /* clock configuration. */ clock_init(); From 29b921b86c233eca7427e8974be2a9c6888c4dfa Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 27 Apr 2018 10:45:15 +0100 Subject: [PATCH 23/59] ARM: mxs: let boards override entire dram parameter table If many values differ from the defaults, overriding the full table is simpler and more space efficient than tweaking it through mxs_adjust_memory_params(). Signed-off-by: Mans Rullgard --- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index 8fef401..7818d72 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -15,7 +15,7 @@ #include "mxs_init.h" -static uint32_t dram_vals[] = { +__weak uint32_t mxs_dram_vals[] = { /* * i.MX28 DDR2 at 200MHz */ @@ -100,11 +100,11 @@ static void initialize_dram_values(void) int i; debug("SPL: Setting mx28 board specific SDRAM parameters\n"); - mxs_adjust_memory_params(dram_vals); + mxs_adjust_memory_params(mxs_dram_vals); debug("SPL: Applying SDRAM parameters\n"); - for (i = 0; i < ARRAY_SIZE(dram_vals); i++) - writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); + for (i = 0; i < ARRAY_SIZE(mxs_dram_vals); i++) + writel(mxs_dram_vals[i], MXS_DRAM_BASE + (4 * i)); } #else static void initialize_dram_values(void) @@ -112,7 +112,7 @@ static void initialize_dram_values(void) int i; debug("SPL: Setting mx23 board specific SDRAM parameters\n"); - mxs_adjust_memory_params(dram_vals); + mxs_adjust_memory_params(mxs_dram_vals); /* * HW_DRAM_CTL27, HW_DRAM_CTL28 and HW_DRAM_CTL35 are not initialized as @@ -124,10 +124,10 @@ static void initialize_dram_values(void) * So skip the initialization of these HW_DRAM_CTL registers. */ debug("SPL: Applying SDRAM parameters\n"); - for (i = 0; i < ARRAY_SIZE(dram_vals); i++) { + for (i = 0; i < ARRAY_SIZE(mxs_dram_vals); i++) { if (i == 8 || i == 27 || i == 28 || i == 35) continue; - writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); + writel(mxs_dram_vals[i], MXS_DRAM_BASE + (4 * i)); } /* From 97294a48c73ae16a03bce4b624334545e890e851 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Mon, 11 Jun 2018 15:08:04 -0300 Subject: [PATCH 24/59] wandboard: Remove hardcoded baudrate from "console" variable We should use the baudrate variable available inside U-Boot environment to allow it to be changed dynamically. Signed-off-by: Otavio Salvador --- include/configs/wandboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h index 1edd7a8..cb32cd1 100644 --- a/include/configs/wandboard.h +++ b/include/configs/wandboard.h @@ -78,7 +78,7 @@ #endif #define CONFIG_EXTRA_ENV_SETTINGS \ - "console=ttymxc0,115200\0" \ + "console=ttymxc0\0" \ "splashpos=m,m\0" \ "fdtfile=undefined\0" \ "fdt_high=0xffffffff\0" \ From 1da1938d57b3ead0bb638683375ab240ce0a0e7b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 11 Jun 2018 15:08:05 -0300 Subject: [PATCH 25/59] spl: Add default values for ARCH_MX7 ARCH_MX6 has default values for SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR and SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR. Do the same for ARCH_MX7 so that users may have a consistent experience through the i.MX families. Signed-off-by: Fabio Estevam Signed-off-by: Otavio Salvador --- common/spl/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 1f14797..0bbf8d5 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -152,7 +152,8 @@ config SPL_DISPLAY_PRINT config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR bool "MMC raw mode: by sector" - default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER ||ARCH_MX6 || \ + default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER || \ + ARCH_MX6 || ARCH_MX7 || \ ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \ ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ OMAP44XX || OMAP54XX || AM33XX || AM43XX @@ -165,7 +166,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR default 0x50 if ARCH_SUNXI default 0x75 if ARCH_DAVINCI - default 0x8a if ARCH_MX6 + default 0x8a if ARCH_MX6 || ARCH_MX7 default 0x100 if ARCH_UNIPHIER default 0x140 if ARCH_MVEBU default 0x200 if ARCH_SOCFPGA || ARCH_AT91 From faab193ea2a8992b18026318f36cc7139b4ca1b5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 11 Jun 2018 15:08:06 -0300 Subject: [PATCH 26/59] pico-imx7d: Adjust the dtb name Since kernel commit 41bbeadceb03 ("ARM: dts: imx7d-pico-pi: Separate into cpu and baseboard dts") the dtb name has changed. Fix it accordingly. Signed-off-by: Fabio Estevam Signed-off-by: Otavio Salvador --- include/configs/pico-imx7d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/pico-imx7d.h b/include/configs/pico-imx7d.h index b208d7f..d2ffa70 100644 --- a/include/configs/pico-imx7d.h +++ b/include/configs/pico-imx7d.h @@ -41,7 +41,7 @@ "console=ttymxc4\0" \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ - "fdt_file=imx7d-pico.dtb\0" \ + "fdt_file=imx7d-pico-pi.dtb\0" \ "fdt_addr=0x83000000\0" \ "ip_dyn=yes\0" \ "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ From 642c1f519a693989f07d1c43f50bd47bafb53422 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Sun, 20 May 2018 08:33:14 +0200 Subject: [PATCH 27/59] board: imx53: Always disable display before starting kernel This patch prevents from the situation where we may end up with garbage displayed on the LCD panel. Such situation occurs when one performs "reboot -f" in Linux and then stop in U-boot (or observe the garbage on the screen during boot up). To prevent from such situation - the PWM pin is configured as GPIO and set to LOW. Signed-off-by: Lukasz Majewski --- arch/arm/dts/imx53-kp.dts | 2 ++ board/k+p/kp_imx53/kp_imx53.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/arch/arm/dts/imx53-kp.dts b/arch/arm/dts/imx53-kp.dts index fd64a9f..6322ef1 100644 --- a/arch/arm/dts/imx53-kp.dts +++ b/arch/arm/dts/imx53-kp.dts @@ -86,6 +86,8 @@ MX53_PAD_PATA_DA_2__GPIO7_8 0x1e4 /* BOOSTER_OFF */ MX53_PAD_EIM_CS0__GPIO2_23 0x1e4 + /* LCD BACKLIGHT */ + MX53_PAD_GPIO_1__GPIO1_1 0x1e4 >; }; diff --git a/board/k+p/kp_imx53/kp_imx53.c b/board/k+p/kp_imx53/kp_imx53.c index c80eed3..6b0db6b 100644 --- a/board/k+p/kp_imx53/kp_imx53.c +++ b/board/k+p/kp_imx53/kp_imx53.c @@ -22,6 +22,7 @@ #define VBUS_PWR_EN IMX_GPIO_NR(7, 8) #define PHY_nRST IMX_GPIO_NR(7, 6) #define BOOSTER_OFF IMX_GPIO_NR(2, 23) +#define LCD_BACKLIGHT IMX_GPIO_NR(1, 1) DECLARE_GLOBAL_DATA_PTR; @@ -189,10 +190,17 @@ void eth_phy_reset(void) udelay(50); } +void board_disable_display(void) +{ + gpio_request(LCD_BACKLIGHT, "LCD_BACKLIGHT"); + gpio_direction_output(LCD_BACKLIGHT, 0); +} + int board_late_init(void) { int ret = 0; + board_disable_display(); setup_ups(); if (!power_init()) From 5ca614cae9ae8bef1bdd0c4621717d1598f50c21 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Sun, 20 May 2018 08:33:15 +0200 Subject: [PATCH 28/59] board: Adjust K+P script to run misc (per board) adjustments This change gives the opportunity to adjust Linux command line for the imx53 device with some legacy data. Signed-off-by: Lukasz Majewski --- board/k+p/bootscripts/tpcboot.cmd | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/board/k+p/bootscripts/tpcboot.cmd b/board/k+p/bootscripts/tpcboot.cmd index eac79dc..16b93eb 100644 --- a/board/k+p/bootscripts/tpcboot.cmd +++ b/board/k+p/bootscripts/tpcboot.cmd @@ -23,6 +23,10 @@ setenv mmcroot "/dev/mmcblk${devnum}p2 rootwait rw" setenv displayargs "" setenv mmcargs "setenv bootargs console=${console} ${smp} root=${mmcroot} \ ${displayargs}" +setenv miscadj " +if test '${boardsoc}' = 'imx53'; then + setenv bootargs '${bootargs} di=${dig_in} key1=${key1}'; +fi;" setenv boot_fitImage " setenv fdt_conf 'conf@${boardsoc}-${boardname}.dtb'; setenv itbcfg "\"#\${fdt_conf}\""; @@ -39,6 +43,7 @@ if test -e ${devtype} ${devnum}:${distro_bootpart} ${kernel_file}; then if load ${devtype} ${devnum}:${distro_bootpart} ${loadaddr} \ ${kernel_file}; then run mmcargs; + run miscadj; run boot_fitImage; fi; fi;" @@ -52,6 +57,7 @@ setenv download_kernel "tftpboot ${loadaddr} ${kernel_file}" setenv boot_tftp_kernel " if run download_kernel; then run mmcargs; + run miscadj; run boot_fitImage; fi" From 0b35b2d11774fadd48b9492bacd89a9757965ecc Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Sun, 20 May 2018 08:33:16 +0200 Subject: [PATCH 29/59] board: Add support for KEY1 status detection on K+P's HSC|DDC boards This code provides information if the K+P's imx53 boards had KEY1 pressed. Signed-off-by: Lukasz Majewski --- arch/arm/dts/imx53-kp.dts | 2 ++ board/k+p/kp_imx53/kp_imx53.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/arm/dts/imx53-kp.dts b/arch/arm/dts/imx53-kp.dts index 6322ef1..ca98fb5 100644 --- a/arch/arm/dts/imx53-kp.dts +++ b/arch/arm/dts/imx53-kp.dts @@ -88,6 +88,8 @@ MX53_PAD_EIM_CS0__GPIO2_23 0x1e4 /* LCD BACKLIGHT */ MX53_PAD_GPIO_1__GPIO1_1 0x1e4 + /* KEY1 GPIO */ + MX53_PAD_EIM_RW__GPIO2_26 0x1e4 >; }; diff --git a/board/k+p/kp_imx53/kp_imx53.c b/board/k+p/kp_imx53/kp_imx53.c index 6b0db6b..7e947fb 100644 --- a/board/k+p/kp_imx53/kp_imx53.c +++ b/board/k+p/kp_imx53/kp_imx53.c @@ -23,6 +23,7 @@ #define PHY_nRST IMX_GPIO_NR(7, 6) #define BOOSTER_OFF IMX_GPIO_NR(2, 23) #define LCD_BACKLIGHT IMX_GPIO_NR(1, 1) +#define KEY1 IMX_GPIO_NR(2, 26) DECLARE_GLOBAL_DATA_PTR; @@ -196,6 +197,17 @@ void board_disable_display(void) gpio_direction_output(LCD_BACKLIGHT, 0); } +void board_misc_setup(void) +{ + gpio_request(KEY1, "KEY1_GPIO"); + gpio_direction_input(KEY1); + + if (gpio_get_value(KEY1)) + env_set("key1", "off"); + else + env_set("key1", "on"); +} + int board_late_init(void) { int ret = 0; @@ -215,5 +227,7 @@ int board_late_init(void) show_eeprom(); read_board_id(); + board_misc_setup(); + return ret; } From e8d2f286ae48324f15d428d6dd1d6dc51664aa3f Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Sun, 20 May 2018 08:33:17 +0200 Subject: [PATCH 30/59] board: Silent out the console on the K+P's imx53 boards Disable console output by default on imx53 based boards from K+P. Signed-off-by: Lukasz Majewski --- include/configs/kp_imx53.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/kp_imx53.h b/include/configs/kp_imx53.h index 530c355..0dc708e 100644 --- a/include/configs/kp_imx53.h +++ b/include/configs/kp_imx53.h @@ -46,6 +46,7 @@ "fdt_high=0xffffffff\0" \ "scriptaddr=0x74000000\0" \ "kernel_file=fitImage\0"\ + "silent=1\0"\ "rdinit=/sbin/init\0" \ "addinitrd=setenv bootargs ${bootargs} rdinit=${rdinit} ${debug} \0" \ "upd_image=st.4k\0" \ From 61c16507d6d6ce8e8f93c33450f936172a1347b0 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Sun, 20 May 2018 08:33:18 +0200 Subject: [PATCH 31/59] board: Remove not needed function for the K+P's imx53 board The get_board_rev() is not needed anymore as a generic function for the imx53 SoC has been used instead. Signed-off-by: Lukasz Majewski --- board/k+p/kp_imx53/kp_imx53.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/board/k+p/kp_imx53/kp_imx53.c b/board/k+p/kp_imx53/kp_imx53.c index 7e947fb..becb6a6 100644 --- a/board/k+p/kp_imx53/kp_imx53.c +++ b/board/k+p/kp_imx53/kp_imx53.c @@ -45,18 +45,6 @@ int dram_init_banksize(void) return 0; } -u32 get_board_rev(void) -{ - struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; - struct fuse_bank *bank = &iim->bank[0]; - struct fuse_bank0_regs *fuse = - (struct fuse_bank0_regs *)bank->fuse_regs; - - int rev = readl(&fuse->gp[6]); - - return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8; -} - #ifdef CONFIG_USB_EHCI_MX5 int board_ehci_hcd_init(int port) { From 76881bbf40dd98ed5d4e42524e6562483f965651 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Sun, 20 May 2018 08:33:19 +0200 Subject: [PATCH 32/59] config: Update defconfig for imx53 K+P boards This commit updates the defconfig for the HSC and DDC boards. Signed-off-by: Lukasz Majewski --- configs/kp_imx53_defconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configs/kp_imx53_defconfig b/configs/kp_imx53_defconfig index 451b48d..d1b5331 100644 --- a/configs/kp_imx53_defconfig +++ b/configs/kp_imx53_defconfig @@ -6,10 +6,14 @@ CONFIG_TARGET_KP_IMX53=y CONFIG_DEFAULT_DEVICE_TREE="imx53-kp" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx53loco/imximage.cfg" +CONFIG_SILENT_CONSOLE=y +# CONFIG_SILENT_CONSOLE_UPDATE_ON_SET is not set CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_HUSH_PARSER=y +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_STOP_STR="." CONFIG_CMD_BOOTZ=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y @@ -18,6 +22,7 @@ CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y +CONFIG_CMD_PMIC=y CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y @@ -26,6 +31,7 @@ CONFIG_ENV_IS_IN_MMC=y CONFIG_I2C_SET_DEFAULT_BUS_NUM=y CONFIG_I2C_DEFAULT_BUS_NUMBER=0x1 CONFIG_PHYLIB=y +CONFIG_PHY_ADDR=1 CONFIG_PHY_SMSC=y CONFIG_FEC_MXC=y CONFIG_PINCTRL=y From 82e8ba056e3a8b7d5a1c0e8709a9f35b0219c1cb Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 2 Jun 2018 17:25:27 +0530 Subject: [PATCH 33/59] board: engicam: spl: match icore-mipi fit-config Match imx6q-icore-mipi and imx6dl-icore-mipi dtb in board_fit_config_name_match. Signed-off-by: Jagan Teki --- board/engicam/common/spl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/board/engicam/common/spl.c b/board/engicam/common/spl.c index 470d96a..1a1fe6c 100644 --- a/board/engicam/common/spl.c +++ b/board/engicam/common/spl.c @@ -43,10 +43,14 @@ int board_fit_config_name_match(const char *name) return 0; else if (is_mx6dq() && !strcmp(name, "imx6q-icore-rqs")) return 0; + else if (is_mx6dq() && !strcmp(name, "imx6q-icore-mipi")) + return 0; else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore")) return 0; else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-rqs")) return 0; + else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-mipi")) + return 0; else return -1; } From 8fd05fccc8b31a37017f33bc70bbb7bc819d77f0 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Thu, 7 Jun 2018 12:10:09 +0200 Subject: [PATCH 34/59] drivers/gpio/mxc: fix MXC GPIO name in KConfig The naming with "UART" is obviously wrong, we fix this here. Signed-off-by: Hannes Schmelzer Reviewed-by: Simon Glass Reviewed-by: Fabio Estevam --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b7e4ffb..29af22e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -109,7 +109,7 @@ config MSM_GPIO - MSM8916 config MXC_GPIO - bool "Freescale/NXP MXC UART driver" + bool "Freescale/NXP MXC GPIO driver" help Support GPIO controllers on various i.MX platforms From 73708200f05501c5d9b7cb6d0a29b0839120b3c0 Mon Sep 17 00:00:00 2001 From: Jon Nettleton Date: Thu, 7 Jun 2018 16:17:36 +0300 Subject: [PATCH 35/59] mx6cuboxi: consolidate board detection and add som revision checking In order to properly detect the board the checks need to be done in a specific order. Move these tests back into a single enum function that will always return the proper the board it is checking. This also adds the best test we have for detecting the rev 1.5 som, and it simplifies the device-tree filename building. Signed-off-by: Jon Nettleton Signed-off-by: Baruch Siach Reviewed-by: Fabio Estevam --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 136 ++++++++++++++++++++++------------- include/configs/mx6cuboxi.h | 24 +++---- 2 files changed, 98 insertions(+), 62 deletions(-) diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index 1fb3c69..1567cf0 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -57,6 +57,13 @@ DECLARE_GLOBAL_DATA_PTR; #define ETH_PHY_RESET IMX_GPIO_NR(4, 15) #define USB_H1_VBUS IMX_GPIO_NR(1, 0) +enum board_type { + CUBOXI = 0x00, + HUMMINGBOARD = 0x01, + HUMMINGBOARD2 = 0x02, + UNKNOWN = 0x03, +}; + int dram_init(void) { gd->ram_size = imx_ddr_size(); @@ -77,10 +84,17 @@ static iomux_v3_cfg_t const usdhc2_pads[] = { IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), }; -static iomux_v3_cfg_t const hb_cbi_sense[] = { +static iomux_v3_cfg_t const board_detect[] = { /* These pins are for sensing if it is a CuBox-i or a HummingBoard */ IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(UART_PAD_CTRL)), IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04 | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const som_rev_detect[] = { + /* These pins are for sensing if it is a CuBox-i or a HummingBoard */ + IOMUX_PADS(PAD_CSI0_DAT14__GPIO6_IO00 | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_CSI0_DAT18__GPIO6_IO04 | MUX_PAD_CTRL(UART_PAD_CTRL)), }; static iomux_v3_cfg_t const usb_pads[] = { @@ -333,88 +347,110 @@ int board_init(void) return ret; } -static bool is_hummingboard(void) +static enum board_type board_type(void) { - int val1, val2; + int val1, val2, val3; - SETUP_IOMUX_PADS(hb_cbi_sense); - - gpio_direction_input(IMX_GPIO_NR(4, 9)); - gpio_direction_input(IMX_GPIO_NR(3, 4)); - - val1 = gpio_get_value(IMX_GPIO_NR(4, 9)); - val2 = gpio_get_value(IMX_GPIO_NR(3, 4)); + SETUP_IOMUX_PADS(board_detect); /* * Machine selection - - * Machine val1, val2 - * ------------------------- - * HB2 x x - * HB rev 3.x x 0 - * CBi 0 1 - * HB 1 1 + * Machine val1, val2, val3 + * ---------------------------- + * HB2 x x 0 + * HB rev 3.x x 0 x + * CBi 0 1 x + * HB 1 1 x */ - if (val2 == 0) - return true; - else if (val1 == 0) - return false; - else - return true; -} + gpio_direction_input(IMX_GPIO_NR(2, 8)); + val3 = gpio_get_value(IMX_GPIO_NR(2, 8)); -static bool is_hummingboard2(void) -{ - int val1; + if (val3 == 0) + return HUMMINGBOARD2; - SETUP_IOMUX_PADS(hb_cbi_sense); + gpio_direction_input(IMX_GPIO_NR(3, 4)); + val2 = gpio_get_value(IMX_GPIO_NR(3, 4)); - gpio_direction_input(IMX_GPIO_NR(2, 8)); + if (val2 == 0) + return HUMMINGBOARD; - val1 = gpio_get_value(IMX_GPIO_NR(2, 8)); + gpio_direction_input(IMX_GPIO_NR(4, 9)); + val1 = gpio_get_value(IMX_GPIO_NR(4, 9)); - /* - * Machine selection - - * Machine val1 - * ------------------- - * HB2 0 - * HB rev 3.x x - * CBi x - * HB x - */ + if (val1 == 0) { + return CUBOXI; + } else { + return HUMMINGBOARD; + } +} + +static bool is_rev_15_som(void) +{ + int val1, val2; + SETUP_IOMUX_PADS(som_rev_detect); - if (val1 == 0) + val1 = gpio_get_value(IMX_GPIO_NR(6, 0)); + val2 = gpio_get_value(IMX_GPIO_NR(6, 4)); + + if (val1 == 1 && val2 == 0) return true; - else - return false; + + return false; } int checkboard(void) { - if (is_hummingboard2()) - puts("Board: MX6 Hummingboard2\n"); - else if (is_hummingboard()) - puts("Board: MX6 Hummingboard\n"); + switch (board_type()) { + case CUBOXI: + puts("Board: MX6 Cubox-i"); + break; + case HUMMINGBOARD: + puts("Board: MX6 HummingBoard"); + break; + case HUMMINGBOARD2: + puts("Board: MX6 HummingBoard2"); + break; + case UNKNOWN: + default: + puts("Board: Unknown\n"); + goto out; + } + + if (is_rev_15_som()) + puts(" (som rev 1.5)\n"); else - puts("Board: MX6 Cubox-i\n"); + puts("\n"); +out: return 0; } int board_late_init(void) { #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG - if (is_hummingboard2()) - env_set("board_name", "HUMMINGBOARD2"); - else if (is_hummingboard()) + switch (board_type()) { + case CUBOXI: + env_set("board_name", "CUBOXI"); + break; + case HUMMINGBOARD: env_set("board_name", "HUMMINGBOARD"); - else + break; + case HUMMINGBOARD2: + env_set("board_name", "HUMMINGBOARD2"); + break; + case UNKNOWN: + default: env_set("board_name", "CUBOXI"); + } if (is_mx6dq()) env_set("board_rev", "MX6Q"); else env_set("board_rev", "MX6DL"); + + if (is_rev_15_som()) + env_set("som_rev", "V15"); #endif return 0; diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h index 6e21377..803661c 100644 --- a/include/configs/mx6cuboxi.h +++ b/include/configs/mx6cuboxi.h @@ -101,18 +101,18 @@ "fi; " \ "fi\0" \ "findfdt="\ - "if test $board_name = HUMMINGBOARD2 && test $board_rev = MX6Q ; then " \ - "setenv fdtfile imx6q-hummingboard2.dtb; fi; " \ - "if test $board_name = HUMMINGBOARD2 && test $board_rev = MX6DL ; then " \ - "setenv fdtfile imx6dl-hummingboard2.dtb; fi; " \ - "if test $board_name = HUMMINGBOARD && test $board_rev = MX6Q ; then " \ - "setenv fdtfile imx6q-hummingboard.dtb; fi; " \ - "if test $board_name = HUMMINGBOARD && test $board_rev = MX6DL ; then " \ - "setenv fdtfile imx6dl-hummingboard.dtb; fi; " \ - "if test $board_name = CUBOXI && test $board_rev = MX6Q ; then " \ - "setenv fdtfile imx6q-cubox-i.dtb; fi; " \ - "if test $board_name = CUBOXI && test $board_rev = MX6DL ; then " \ - "setenv fdtfile imx6dl-cubox-i.dtb; fi; " \ + "if test $board_rev = MX6Q ; then " \ + "setenv fdtprefix imx6q; fi; " \ + "if test $board_rev = MX6DL ; then " \ + "setenv fdtprefix imx6dl; fi; " \ + "if test $som_rev = V15 ; then " \ + "setenv fdtsuffix -som-v15; fi; " \ + "if test $board_name = HUMMINGBOARD2 ; then " \ + "setenv fdtfile ${fdtprefix}-hummingboard2${fdtsuffix}.dtb; fi; " \ + "if test $board_name = HUMMINGBOARD ; then " \ + "setenv fdtfile ${fdtprefix}-hummingboard${fdtsuffix}.dtb; fi; " \ + "if test $board_name = CUBOXI ; then " \ + "setenv fdtfile ${fdtprefix}-cubox-i${fdtsuffix}.dtb; fi; " \ "if test $fdtfile = undefined; then " \ "echo WARNING: Could not determine dtb to use; fi; \0" \ BOOTENV From 51f957adf77575075b69a95a37f118653532892c Mon Sep 17 00:00:00 2001 From: Jon Nettleton Date: Thu, 7 Jun 2018 16:17:37 +0300 Subject: [PATCH 36/59] mx6cuboxi: fix 4GB ddr memory detection The soms with 4GB ddr have a rowaddr of 16 not 15, this allows the detection mechanism to properly identify them as 4GB. However these soms can be populated with whatever amount of memory the customer requests therefor we need a ram stride test. We can not use the get_ram_size() function because not all 4GB's of DDR is addressable on a 32-bit architecture. Therefore instead we use a memory stride of 128MB's and look for the address that the memory wraps. This function is used for all som types to catch most memory configurations. This is a revised version of Rabeeh Khoury's original code. Signed-off-by: Jon Nettleton Signed-off-by: Rabeeh Khoury Signed-off-by: Baruch Siach Reviewed-by: Fabio Estevam --- board/solidrun/mx6cuboxi/mx6cuboxi.c | 46 ++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index 1567cf0..38d89f0 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -64,9 +64,51 @@ enum board_type { UNKNOWN = 0x03, }; +#define MEM_STRIDE 0x4000000 +static u32 get_ram_size_stride_test(u32 *base, u32 maxsize) +{ + volatile u32 *addr; + u32 save[64]; + u32 cnt; + u32 size; + int i = 0; + + /* First save the data */ + for (cnt = 0; cnt < maxsize; cnt += MEM_STRIDE) { + addr = (volatile u32 *)((u32)base + cnt); /* pointer arith! */ + sync (); + save[i++] = *addr; + sync (); + } + + /* First write a signature */ + * (volatile u32 *)base = 0x12345678; + for (size = MEM_STRIDE; size < maxsize; size += MEM_STRIDE) { + * (volatile u32 *)((u32)base + size) = size; + sync (); + if (* (volatile u32 *)((u32)base) == size) { /* We reached the overlapping address */ + break; + } + } + + /* Restore the data */ + for (cnt = (maxsize - MEM_STRIDE); i > 0; cnt -= MEM_STRIDE) { + addr = (volatile u32 *)((u32)base + cnt); /* pointer arith! */ + sync (); + *addr = save[i--]; + sync (); + } + + return (size); +} + int dram_init(void) { - gd->ram_size = imx_ddr_size(); + u32 max_size = imx_ddr_size(); + + gd->ram_size = get_ram_size_stride_test((u32 *) CONFIG_SYS_SDRAM_BASE, + (u32)max_size); + return 0; } @@ -626,7 +668,7 @@ static struct mx6_ddr3_cfg mem_ddr_4g = { .density = 4, .width = 16, .banks = 8, - .rowaddr = 15, + .rowaddr = 16, .coladdr = 10, .pagesz = 2, .trcd = 1375, From 9345943b2b5ea890cb479770c3c802cf851ed3e6 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 17:19:46 +0200 Subject: [PATCH 37/59] mtd: nand: mxs_nand: introduce SPL specific init In preparation to convert the driver to use NAND self init provide a new minimal init for SPL builds. As a side effect this also reduces size of SPL by about 4KiB. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 43 +++++++++++++++++++++++++++++++++++++++++ drivers/mtd/nand/mxs_nand.h | 10 ++++++++++ drivers/mtd/nand/mxs_nand_spl.c | 3 ++- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/mxs_nand.h diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index b9ffa7c..5b7ad18 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -25,6 +25,7 @@ #include #include #include +#include "mxs_nand.h" #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 @@ -1149,6 +1150,48 @@ err1: return ret; } +int mxs_nand_init_spl(struct nand_chip *nand) +{ + struct mxs_nand_info *nand_info; + int err; + + nand_info = malloc(sizeof(struct mxs_nand_info)); + if (!nand_info) { + printf("MXS NAND: Failed to allocate private data\n"); + return -ENOMEM; + } + memset(nand_info, 0, sizeof(struct mxs_nand_info)); + + err = mxs_nand_alloc_buffers(nand_info); + if (err) + return err; + + err = mxs_nand_init(nand_info); + if (err) + return err; + + nand_set_controller_data(nand, nand_info); + + nand->options |= NAND_NO_SUBPAGE_WRITE; + + nand->cmd_ctrl = mxs_nand_cmd_ctrl; + nand->dev_ready = mxs_nand_device_ready; + nand->select_chip = mxs_nand_select_chip; + nand->scan_bbt = mxs_nand_scan_bbt; + + nand->read_byte = mxs_nand_read_byte; + nand->read_buf = mxs_nand_read_buf; + + nand->ecc.read_page = mxs_nand_ecc_read_page; + + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.bytes = 9; + nand->ecc.size = 512; + nand->ecc.strength = 8; + + return 0; +} + /*! * This function is called during the driver binding process. * diff --git a/drivers/mtd/nand/mxs_nand.h b/drivers/mtd/nand/mxs_nand.h new file mode 100644 index 0000000..9bb7148 --- /dev/null +++ b/drivers/mtd/nand/mxs_nand.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * NXP GPMI NAND flash driver + * + * Copyright (C) 2018 Toradex + * Authors: + * Stefan Agner + */ + +int mxs_nand_init_spl(struct nand_chip *nand); diff --git a/drivers/mtd/nand/mxs_nand_spl.c b/drivers/mtd/nand/mxs_nand_spl.c index 3e8b35f..47857a8 100644 --- a/drivers/mtd/nand/mxs_nand_spl.c +++ b/drivers/mtd/nand/mxs_nand_spl.c @@ -6,6 +6,7 @@ #include #include #include +#include "mxs_nand.h" static struct mtd_info *mtd; static struct nand_chip nand_chip; @@ -145,7 +146,7 @@ static int mxs_nand_init(void) return 0; /* init mxs nand driver */ - board_nand_init(&nand_chip); + mxs_nand_init_spl(&nand_chip); mtd = nand_to_mtd(&nand_chip); /* set mtd functions */ nand_chip.cmdfunc = mxs_nand_command; From 5346c31e305a37d39f535cc0d5ae87d8b7e81230 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 17:19:47 +0200 Subject: [PATCH 38/59] mtd: nand: mxs_nand: use self init Instead of completing initialization via scan_bbt callback use NAND self init to initialize the GPMI (MXS) NAND controller. Suggested-by: Scott Wood Signed-off-by: Stefan Agner --- drivers/mtd/nand/Kconfig | 1 + drivers/mtd/nand/mxs_nand.c | 53 +++++++++++++++++++++++++-------------------- drivers/mtd/nand/mxs_nand.h | 1 + 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 94fbf89..4db259f 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -143,6 +143,7 @@ config NAND_MXC config NAND_MXS bool "MXS NAND support" depends on MX23 || MX28 || MX6 || MX7 + select SYS_NAND_SELF_INIT imply CMD_NAND select APBH_DMA select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 5b7ad18..14d3210 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #define MXS_NAND_BCH_TIMEOUT 10000 struct mxs_nand_info { + struct nand_chip chip; int cur_chip; uint32_t cmd_queue_len; @@ -972,20 +974,15 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs) } /* - * Nominally, the purpose of this function is to look for or create the bad - * block table. In fact, since the we call this function at the very end of - * the initialization process started by nand_scan(), and we doesn't have a - * more formal mechanism, we "hook" this function to continue init process. - * * At this point, the physical NAND Flash chips have been identified and * counted, so we know the physical geometry. This enables us to make some * important configuration decisions. * * The return value of this function propagates directly back to this driver's - * call to nand_scan(). Anything other than zero will cause this driver to + * board_nand_init(). Anything other than zero will cause this driver to * tear everything down and declare failure. */ -static int mxs_nand_scan_bbt(struct mtd_info *mtd) +int mxs_nand_setup_ecc(struct mtd_info *mtd) { struct nand_chip *nand = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(nand); @@ -1047,8 +1044,7 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd) mtd->_block_markbad = mxs_nand_hook_block_markbad; } - /* We use the reference implementation for bad block management. */ - return nand_default_bbt(mtd); + return 0; } /* @@ -1177,7 +1173,6 @@ int mxs_nand_init_spl(struct nand_chip *nand) nand->cmd_ctrl = mxs_nand_cmd_ctrl; nand->dev_ready = mxs_nand_device_ready; nand->select_chip = mxs_nand_select_chip; - nand->scan_bbt = mxs_nand_scan_bbt; nand->read_byte = mxs_nand_read_byte; nand->read_buf = mxs_nand_read_buf; @@ -1192,27 +1187,22 @@ int mxs_nand_init_spl(struct nand_chip *nand) return 0; } -/*! - * This function is called during the driver binding process. - * - * @param pdev the device structure used to store device specific - * information that is used by the suspend, resume and - * remove functions - * - * @return The function always returns 0. - */ -int board_nand_init(struct nand_chip *nand) +void board_nand_init(void) { + struct mtd_info *mtd; struct mxs_nand_info *nand_info; + struct nand_chip *nand; int err; nand_info = malloc(sizeof(struct mxs_nand_info)); if (!nand_info) { printf("MXS NAND: Failed to allocate private data\n"); - return -ENOMEM; + return; } memset(nand_info, 0, sizeof(struct mxs_nand_info)); + nand = &nand_info->chip; + mtd = nand_to_mtd(nand); err = mxs_nand_alloc_buffers(nand_info); if (err) goto err1; @@ -1231,13 +1221,19 @@ int board_nand_init(struct nand_chip *nand) nand->dev_ready = mxs_nand_device_ready; nand->select_chip = mxs_nand_select_chip; nand->block_bad = mxs_nand_block_bad; - nand->scan_bbt = mxs_nand_scan_bbt; nand->read_byte = mxs_nand_read_byte; nand->read_buf = mxs_nand_read_buf; nand->write_buf = mxs_nand_write_buf; + /* first scan to find the device and get the page size */ + if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL)) + goto err2; + + if (mxs_nand_setup_ecc(mtd)) + goto err2; + nand->ecc.read_page = mxs_nand_ecc_read_page; nand->ecc.write_page = mxs_nand_ecc_write_page; nand->ecc.read_oob = mxs_nand_ecc_read_oob; @@ -1249,12 +1245,21 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.size = 512; nand->ecc.strength = 8; - return 0; + /* second phase scan */ + err = nand_scan_tail(mtd); + if (err) + goto err2; + + err = nand_register(0, mtd); + if (err) + goto err2; + + return; err2: free(nand_info->data_buf); free(nand_info->cmd_buf); err1: free(nand_info); - return err; + return; } diff --git a/drivers/mtd/nand/mxs_nand.h b/drivers/mtd/nand/mxs_nand.h index 9bb7148..379ed24 100644 --- a/drivers/mtd/nand/mxs_nand.h +++ b/drivers/mtd/nand/mxs_nand.h @@ -8,3 +8,4 @@ */ int mxs_nand_init_spl(struct nand_chip *nand); +int mxs_nand_setup_ecc(struct mtd_info *mtd); From dc0b69fa9f97df90cbcabf16a51d7eb88f26cd2d Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 17:19:48 +0200 Subject: [PATCH 39/59] mtd: nand: mxs_nand: allow to enable BBT support Add config option which allows to enable on flash bad block table support. This has the same effect as when using the device tree property "nand-on-flash-bbt" in Linux. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 14d3210..2584608 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -1213,6 +1213,10 @@ void board_nand_init(void) memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout)); +#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT + nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; +#endif + nand_set_controller_data(nand, nand_info); nand->options |= NAND_NO_SUBPAGE_WRITE; From 28897e8d21f8e197e259a91c693de09cd81f2d5a Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 17:19:49 +0200 Subject: [PATCH 40/59] mtd: nand: mxs_nand: use structure for BCH geometry Calculate BCH geometry at start and store the information in a structure. This avoids recalculation on every page access and allows to calculate ECC relevant information in one place. This patch does not change ECC layout or driver behavior in any way. The patch aligns the driver somewhat with the Linux GPMI NAND driver which drives the same IP. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 182 +++++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 87 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 2584608..dbf3546 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -30,7 +30,6 @@ #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 -#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512 #if (defined(CONFIG_MX6) || defined(CONFIG_MX7)) #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2 #else @@ -47,12 +46,35 @@ #define MXS_NAND_BCH_TIMEOUT 10000 +/** + * @gf_len: The length of Galois Field. (e.g., 13 or 14) + * @ecc_strength: A number that describes the strength of the ECC + * algorithm. + * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note + * the first chunk in the page includes both data and + * metadata, so it's a bit larger than this value. + * @ecc_chunk_count: The number of ECC chunks in the page, + * @block_mark_byte_offset: The byte offset in the ECC-based page view at + * which the underlying physical block mark appears. + * @block_mark_bit_offset: The bit offset into the ECC-based page view at + * which the underlying physical block mark appears. + */ +struct bch_geometry { + unsigned int gf_len; + unsigned int ecc_strength; + unsigned int ecc_chunk_size; + unsigned int ecc_chunk_count; + unsigned int block_mark_byte_offset; + unsigned int block_mark_bit_offset; +}; + struct mxs_nand_info { struct nand_chip chip; int cur_chip; uint32_t cmd_queue_len; uint32_t data_buf_size; + struct bch_geometry bch_geometry; uint8_t *cmd_buf; uint8_t *data_buf; @@ -75,8 +97,6 @@ struct mxs_nand_info { }; struct nand_ecclayout fake_ecc_layout; -static int chunk_data_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE; -static int galois_field = 13; /* * Cache management functions @@ -137,61 +157,21 @@ static void mxs_nand_return_dma_descs(struct mxs_nand_info *info) info->desc_index = 0; } -static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size) -{ - return page_data_size / chunk_data_size; -} - -static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength) -{ - return ecc_strength * galois_field; -} - static uint32_t mxs_nand_aux_status_offset(void) { return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3; } -static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size, - uint32_t page_oob_size) +static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo, + uint32_t page_data_size) { - int ecc_strength; - int max_ecc_strength_supported; - - /* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */ - if (is_mx6sx() || is_mx7()) - max_ecc_strength_supported = 62; - else - max_ecc_strength_supported = 40; - - /* - * Determine the ECC layout with the formula: - * ECC bits per chunk = (total page spare data bits) / - * (bits per ECC level) / (chunks per page) - * where: - * total page spare data bits = - * (page oob size - meta data size) * (bits per byte) - */ - ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8) - / (galois_field * - mxs_nand_ecc_chunk_cnt(page_data_size)); - - return min(round_down(ecc_strength, 2), max_ecc_strength_supported); -} - -static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, - uint32_t ecc_strength) -{ - uint32_t chunk_data_size_in_bits; - uint32_t chunk_ecc_size_in_bits; + uint32_t chunk_data_size_in_bits = geo->ecc_chunk_size * 8; + uint32_t chunk_ecc_size_in_bits = geo->ecc_strength * geo->gf_len; uint32_t chunk_total_size_in_bits; uint32_t block_mark_chunk_number; uint32_t block_mark_chunk_bit_offset; uint32_t block_mark_bit_offset; - chunk_data_size_in_bits = chunk_data_size * 8; - chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(ecc_strength); - chunk_total_size_in_bits = chunk_data_size_in_bits + chunk_ecc_size_in_bits; @@ -216,7 +196,7 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, (block_mark_chunk_number * chunk_total_size_in_bits); if (block_mark_chunk_bit_offset > chunk_data_size_in_bits) - return 1; + return -EINVAL; /* * Now that we know the chunk number in which the block mark appears, @@ -225,21 +205,59 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, block_mark_bit_offset -= block_mark_chunk_number * chunk_ecc_size_in_bits; - return block_mark_bit_offset; -} + geo->block_mark_byte_offset = block_mark_bit_offset >> 3; + geo->block_mark_bit_offset = block_mark_bit_offset & 0x7; -static uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd) -{ - uint32_t ecc_strength; - ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize); - return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3; + return 0; } -static uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd) +static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, + struct mtd_info *mtd) { - uint32_t ecc_strength; - ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize); - return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7; + unsigned int max_ecc_strength_supported; + + /* The default for the length of Galois Field. */ + geo->gf_len = 13; + + /* The default for chunk size. */ + geo->ecc_chunk_size = 512; + + if (geo->ecc_chunk_size < mtd->oobsize) { + geo->gf_len = 14; + geo->ecc_chunk_size *= 2; + } + + if (mtd->oobsize > geo->ecc_chunk_size) { + printf("Not support the NAND chips whose oob size is larger then %d bytes!\n", + geo->ecc_chunk_size); + return -EINVAL; + } + + geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; + + /* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */ + if (is_mx6sx() || is_mx7()) + max_ecc_strength_supported = 62; + else + max_ecc_strength_supported = 40; + + /* + * Determine the ECC layout with the formula: + * ECC bits per chunk = (total page spare data bits) / + * (bits per ECC level) / (chunks per page) + * where: + * total page spare data bits = + * (page oob size - meta data size) * (bits per byte) + */ + geo->ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8) + / (geo->gf_len * geo->ecc_chunk_count); + + geo->ecc_strength = min(round_down(geo->ecc_strength, 2), max_ecc_strength_supported); + + if (mxs_nand_calc_mark_offset(geo, mtd->writesize) < 0) + return -EINVAL; + + return 0; } /* @@ -380,18 +398,15 @@ static void mxs_nand_select_chip(struct mtd_info *mtd, int chip) * swapping the block mark, or swapping it *back* -- but it doesn't matter * because the the operation is the same. */ -static void mxs_nand_swap_block_mark(struct mtd_info *mtd, - uint8_t *data_buf, uint8_t *oob_buf) +static void mxs_nand_swap_block_mark(struct bch_geometry *geo, + uint8_t *data_buf, uint8_t *oob_buf) { - uint32_t bit_offset; - uint32_t buf_offset; + uint32_t bit_offset = geo->block_mark_bit_offset; + uint32_t buf_offset = geo->block_mark_byte_offset; uint32_t src; uint32_t dst; - bit_offset = mxs_nand_mark_bit_offset(mtd); - buf_offset = mxs_nand_mark_byte_offset(mtd); - /* * Get the byte from the data area that overlays the block mark. Since * the ECC engine applies its own view to the bits in the page, the @@ -567,6 +582,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, int page) { struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + struct bch_geometry *geo = &nand_info->bch_geometry; struct mxs_dma_desc *d; uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip; uint32_t corrected = 0, failed = 0; @@ -665,11 +681,11 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, mxs_nand_inval_data_buf(nand_info); /* Read DMA completed, now do the mark swapping. */ - mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf); + mxs_nand_swap_block_mark(geo, nand_info->data_buf, nand_info->oob_buf); /* Loop over status bytes, accumulating ECC status. */ status = nand_info->oob_buf + mxs_nand_aux_status_offset(); - for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd->writesize); i++) { + for (i = 0; i < geo->ecc_chunk_count; i++) { if (status[i] == 0x00) continue; @@ -717,6 +733,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, int oob_required, int page) { struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + struct bch_geometry *geo = &nand_info->bch_geometry; struct mxs_dma_desc *d; uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip; int ret; @@ -725,7 +742,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, memcpy(nand_info->oob_buf, nand->oob_poi, mtd->oobsize); /* Handle block mark swapping. */ - mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf); + mxs_nand_swap_block_mark(geo, nand_info->data_buf, nand_info->oob_buf); /* Compile the DMA descriptor - write data. */ d = mxs_nand_get_dma_desc(nand_info); @@ -986,39 +1003,30 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) { struct nand_chip *nand = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + struct bch_geometry *geo = &nand_info->bch_geometry; struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; uint32_t tmp; - if (mtd->oobsize > MXS_NAND_CHUNK_DATA_CHUNK_SIZE) { - galois_field = 14; - chunk_data_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 2; - } - - if (mtd->oobsize > chunk_data_size) { - printf("Not support the NAND chips whose oob size is larger then %d bytes!\n", chunk_data_size); + if (mxs_nand_calc_ecc_layout(geo, mtd)) return -EINVAL; - } /* Configure BCH and set NFC geometry */ mxs_reset_block(&bch_regs->hw_bch_ctrl_reg); /* Configure layout 0 */ - tmp = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1) - << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; + tmp = (geo->ecc_chunk_count - 1) << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; - tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1) - << BCH_FLASHLAYOUT0_ECC0_OFFSET; - tmp |= chunk_data_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; - tmp |= (14 == galois_field ? 1 : 0) << + tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT0_ECC0_OFFSET; + tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout0); tmp = (mtd->writesize + mtd->oobsize) << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; - tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1) - << BCH_FLASHLAYOUT1_ECCN_OFFSET; - tmp |= chunk_data_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; - tmp |= (14 == galois_field ? 1 : 0) << + tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT1_ECCN_OFFSET; + tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout1); From 5c69dd0730ff6bcad16e86fd93bf7a914d988a22 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 17:19:50 +0200 Subject: [PATCH 41/59] mtd: nand: mxs_nand: report correct ECC parameters Report correct ECC parameters back to the stack. Do not report bytes as we have it not immeaditly available and the Linux version also does not report it. It seems to have no aversive effect. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index dbf3546..b28d65f 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -1253,9 +1253,8 @@ void board_nand_init(void) nand->ecc.layout = &fake_ecc_layout; nand->ecc.mode = NAND_ECC_HW; - nand->ecc.bytes = 9; - nand->ecc.size = 512; - nand->ecc.strength = 8; + nand->ecc.size = nand_info->bch_geometry.ecc_chunk_size; + nand->ecc.strength = nand_info->bch_geometry.ecc_strength; /* second phase scan */ err = nand_scan_tail(mtd); From 984df7add1fe6e5a25854eae81f51940806456bc Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 17:19:51 +0200 Subject: [PATCH 42/59] mtd: nand: mxs_nand: add minimal ECC support Add support for minimum ECC strength supported by the NAND chip. This aligns with the behavior when using the fsl,use-minimum-ecc device tree property in Linux. Signed-off-by: Stefan Agner --- drivers/mtd/nand/Kconfig | 8 +++++ drivers/mtd/nand/mxs_nand.c | 72 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 4db259f..c039b9c 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -152,6 +152,14 @@ config NAND_MXS This enables NAND driver for the NAND flash controller on the MXS processors. +if NAND_MXS + +config NAND_MXS_USE_MINIMUM_ECC + bool "Use minimum ECC strength supported by the controller" + default false + +endif + config NAND_ZYNQ bool "Support for Zynq Nand controller" select SYS_NAND_SELF_INIT diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index b28d65f..15d8bcb 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -211,11 +212,52 @@ static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo, return 0; } +static inline unsigned int mxs_nand_max_ecc_strength_supported(void) +{ + /* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */ + if (is_mx6sx() || is_mx7()) + return 62; + else + return 40; +} + +static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, + struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + + if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) + return -ENOTSUPP; + + switch (chip->ecc_step_ds) { + case SZ_512: + geo->gf_len = 13; + break; + case SZ_1K: + geo->gf_len = 14; + break; + default: + return -EINVAL; + } + + geo->ecc_chunk_size = chip->ecc_step_ds; + geo->ecc_strength = round_up(chip->ecc_strength_ds, 2); + + /* Keep the C >= O */ + if (geo->ecc_chunk_size < mtd->oobsize) + return -EINVAL; + + if (geo->ecc_strength > mxs_nand_max_ecc_strength_supported()) + return -EINVAL; + + geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; + + return 0; +} + static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, struct mtd_info *mtd) { - unsigned int max_ecc_strength_supported; - /* The default for the length of Galois Field. */ geo->gf_len = 13; @@ -235,12 +277,6 @@ static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; - /* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */ - if (is_mx6sx() || is_mx7()) - max_ecc_strength_supported = 62; - else - max_ecc_strength_supported = 40; - /* * Determine the ECC layout with the formula: * ECC bits per chunk = (total page spare data bits) / @@ -252,10 +288,8 @@ static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, geo->ecc_strength = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8) / (geo->gf_len * geo->ecc_chunk_count); - geo->ecc_strength = min(round_down(geo->ecc_strength, 2), max_ecc_strength_supported); - - if (mxs_nand_calc_mark_offset(geo, mtd->writesize) < 0) - return -EINVAL; + geo->ecc_strength = min(round_down(geo->ecc_strength, 2), + mxs_nand_max_ecc_strength_supported()); return 0; } @@ -1006,9 +1040,19 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) struct bch_geometry *geo = &nand_info->bch_geometry; struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; uint32_t tmp; + int ret = -ENOTSUPP; - if (mxs_nand_calc_ecc_layout(geo, mtd)) - return -EINVAL; +#ifdef CONFIG_NAND_MXS_USE_MINIMUM_ECC + ret = mxs_nand_calc_ecc_layout_by_info(geo, mtd); +#endif + + if (ret == -ENOTSUPP) + ret = mxs_nand_calc_ecc_layout(geo, mtd); + + if (ret) + return ret; + + mxs_nand_calc_mark_offset(geo, mtd->writesize); /* Configure BCH and set NFC geometry */ mxs_reset_block(&bch_regs->hw_bch_ctrl_reg); From 931747e517b19387716cd56057e4afa9e2cdfff4 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:12 +0200 Subject: [PATCH 43/59] mtd: nand: mxs_nand: move register structs to driver data Move GPMI and BCH register structs to the driver struct mxs_nand_info in prepartion for device tree support. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 15d8bcb..65fed66 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -84,6 +84,9 @@ struct mxs_nand_info { uint8_t marking_block_bad; uint8_t raw_oob_mode; + struct mxs_gpmi_regs *gpmi_regs; + struct mxs_bch_regs *bch_regs; + /* Functions with altered behaviour */ int (*hooked_read_oob)(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); @@ -297,16 +300,15 @@ static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, /* * Wait for BCH complete IRQ and clear the IRQ */ -static int mxs_nand_wait_for_bch_complete(void) +static int mxs_nand_wait_for_bch_complete(struct mxs_nand_info *nand_info) { - struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; int timeout = MXS_NAND_BCH_TIMEOUT; int ret; - ret = mxs_wait_mask_set(&bch_regs->hw_bch_ctrl_reg, + ret = mxs_wait_mask_set(&nand_info->bch_regs->hw_bch_ctrl_reg, BCH_CTRL_COMPLETE_IRQ, timeout); - writel(BCH_CTRL_COMPLETE_IRQ, &bch_regs->hw_bch_ctrl_clr); + writel(BCH_CTRL_COMPLETE_IRQ, &nand_info->bch_regs->hw_bch_ctrl_clr); return ret; } @@ -404,11 +406,9 @@ static int mxs_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); - struct mxs_gpmi_regs *gpmi_regs = - (struct mxs_gpmi_regs *)MXS_GPMI_BASE; uint32_t tmp; - tmp = readl(&gpmi_regs->hw_gpmi_stat); + tmp = readl(&nand_info->gpmi_regs->hw_gpmi_stat); tmp >>= (GPMI_STAT_READY_BUSY_OFFSET + nand_info->cur_chip); return tmp & 1; @@ -705,7 +705,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, goto rtn; } - ret = mxs_nand_wait_for_bch_complete(); + ret = mxs_nand_wait_for_bch_complete(nand_info); if (ret) { printf("MXS NAND: BCH read timeout\n"); goto rtn; @@ -813,7 +813,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, goto rtn; } - ret = mxs_nand_wait_for_bch_complete(); + ret = mxs_nand_wait_for_bch_complete(nand_info); if (ret) { printf("MXS NAND: BCH write timeout\n"); goto rtn; @@ -1038,7 +1038,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) struct nand_chip *nand = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(nand); struct bch_geometry *geo = &nand_info->bch_geometry; - struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + struct mxs_bch_regs *bch_regs = nand_info->bch_regs; uint32_t tmp; int ret = -ENOTSUPP; @@ -1139,10 +1139,6 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info) */ int mxs_nand_init(struct mxs_nand_info *info) { - struct mxs_gpmi_regs *gpmi_regs = - (struct mxs_gpmi_regs *)MXS_GPMI_BASE; - struct mxs_bch_regs *bch_regs = - (struct mxs_bch_regs *)MXS_BCH_BASE; int i = 0, j, ret = 0; info->desc = malloc(sizeof(struct mxs_dma_desc *) * @@ -1171,14 +1167,14 @@ int mxs_nand_init(struct mxs_nand_info *info) } /* Reset the GPMI block. */ - mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg); - mxs_reset_block(&bch_regs->hw_bch_ctrl_reg); + mxs_reset_block(&info->gpmi_regs->hw_gpmi_ctrl0_reg); + mxs_reset_block(&info->bch_regs->hw_bch_ctrl_reg); /* * Choose NAND mode, set IRQ polarity, disable write protection and * select BCH ECC. */ - clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1, + clrsetbits_le32(&info->gpmi_regs->hw_gpmi_ctrl1, GPMI_CTRL1_GPMI_MODE, GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET | GPMI_CTRL1_BCH_MODE); @@ -1210,6 +1206,8 @@ int mxs_nand_init_spl(struct nand_chip *nand) } memset(nand_info, 0, sizeof(struct mxs_nand_info)); + nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; + nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; err = mxs_nand_alloc_buffers(nand_info); if (err) return err; @@ -1253,6 +1251,8 @@ void board_nand_init(void) } memset(nand_info, 0, sizeof(struct mxs_nand_info)); + nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; + nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; nand = &nand_info->chip; mtd = nand_to_mtd(nand); err = mxs_nand_alloc_buffers(nand_info); From 0d4e9d8be23a30f5f1ca5bad2188e8a1c9848c5c Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:13 +0200 Subject: [PATCH 44/59] mtd: nand: mxs_nand: use more precise function name This function initializes DMA descriptors so mxs_nand_init_dma is more precise. It also frees up the rather generic name mxs_nand_init. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 65fed66..6bd3cb1 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -1137,7 +1137,7 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info) /* * Initializes the NFC hardware. */ -int mxs_nand_init(struct mxs_nand_info *info) +int mxs_nand_init_dma(struct mxs_nand_info *info) { int i = 0, j, ret = 0; @@ -1212,7 +1212,7 @@ int mxs_nand_init_spl(struct nand_chip *nand) if (err) return err; - err = mxs_nand_init(nand_info); + err = mxs_nand_init_dma(nand_info); if (err) return err; @@ -1259,7 +1259,7 @@ void board_nand_init(void) if (err) goto err1; - err = mxs_nand_init(nand_info); + err = mxs_nand_init_dma(nand_info); if (err) goto err2; From 3b1328a0ad7624f7e7bd803d0709c7c2fd13fc46 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:14 +0200 Subject: [PATCH 45/59] mtd: nand: mxs_nand: separate board/controller init In preparation for device tree support separate board init from controller init similar to other raw NAND drivers. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 54 +++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 6bd3cb1..bb40237 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -1237,31 +1237,21 @@ int mxs_nand_init_spl(struct nand_chip *nand) return 0; } -void board_nand_init(void) +int mxs_nand_init(struct mxs_nand_info *nand_info) { struct mtd_info *mtd; - struct mxs_nand_info *nand_info; struct nand_chip *nand; int err; - nand_info = malloc(sizeof(struct mxs_nand_info)); - if (!nand_info) { - printf("MXS NAND: Failed to allocate private data\n"); - return; - } - memset(nand_info, 0, sizeof(struct mxs_nand_info)); - - nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; - nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; nand = &nand_info->chip; mtd = nand_to_mtd(nand); err = mxs_nand_alloc_buffers(nand_info); if (err) - goto err1; + return err; err = mxs_nand_init_dma(nand_info); if (err) - goto err2; + goto err_free_buffers; memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout)); @@ -1285,10 +1275,10 @@ void board_nand_init(void) /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL)) - goto err2; + goto err_free_buffers; if (mxs_nand_setup_ecc(mtd)) - goto err2; + goto err_free_buffers; nand->ecc.read_page = mxs_nand_ecc_read_page; nand->ecc.write_page = mxs_nand_ecc_write_page; @@ -1303,18 +1293,40 @@ void board_nand_init(void) /* second phase scan */ err = nand_scan_tail(mtd); if (err) - goto err2; + goto err_free_buffers; err = nand_register(0, mtd); if (err) - goto err2; + goto err_free_buffers; - return; + return 0; -err2: +err_free_buffers: free(nand_info->data_buf); free(nand_info->cmd_buf); -err1: - free(nand_info); + + return err; +} + +void board_nand_init(void) +{ + struct mxs_nand_info *nand_info; + + nand_info = malloc(sizeof(struct mxs_nand_info)); + if (!nand_info) { + printf("MXS NAND: Failed to allocate private data\n"); + return; + } + memset(nand_info, 0, sizeof(struct mxs_nand_info)); + + nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; + nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + + if (mxs_nand_init(nand_info) < 0) + goto err; + return; + +err: + free(nand_info); } From 502bdc6b4f52fff92d19b5072a60e8b8cbfb1c04 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:15 +0200 Subject: [PATCH 46/59] mtd: nand: mxs_nand: add use_minimum_ecc to struct Add use_minimum_ecc as struct mxs_nand_info field in preparation for device tree support. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index bb40237..3c9ee07 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -71,6 +71,8 @@ struct bch_geometry { struct mxs_nand_info { struct nand_chip chip; + unsigned int max_ecc_strength_supported; + bool use_minimum_ecc; int cur_chip; uint32_t cmd_queue_len; @@ -215,19 +217,11 @@ static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo, return 0; } -static inline unsigned int mxs_nand_max_ecc_strength_supported(void) -{ - /* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */ - if (is_mx6sx() || is_mx7()) - return 62; - else - return 40; -} - static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) return -ENOTSUPP; @@ -250,7 +244,7 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, if (geo->ecc_chunk_size < mtd->oobsize) return -EINVAL; - if (geo->ecc_strength > mxs_nand_max_ecc_strength_supported()) + if (geo->ecc_strength > nand_info->max_ecc_strength_supported) return -EINVAL; geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; @@ -261,6 +255,9 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, struct mtd_info *mtd) { + struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + /* The default for the length of Galois Field. */ geo->gf_len = 13; @@ -292,7 +289,7 @@ static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, / (geo->gf_len * geo->ecc_chunk_count); geo->ecc_strength = min(round_down(geo->ecc_strength, 2), - mxs_nand_max_ecc_strength_supported()); + nand_info->max_ecc_strength_supported); return 0; } @@ -1042,9 +1039,8 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) uint32_t tmp; int ret = -ENOTSUPP; -#ifdef CONFIG_NAND_MXS_USE_MINIMUM_ECC - ret = mxs_nand_calc_ecc_layout_by_info(geo, mtd); -#endif + if (nand_info->use_minimum_ecc) + ret = mxs_nand_calc_ecc_layout_by_info(geo, mtd); if (ret == -ENOTSUPP) ret = mxs_nand_calc_ecc_layout(geo, mtd); @@ -1322,6 +1318,16 @@ void board_nand_init(void) nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + /* Refer to Chapter 17 for i.MX6DQ, Chapter 18 for i.MX6SX */ + if (is_mx6sx() || is_mx7()) + nand_info->max_ecc_strength_supported = 62; + else + nand_info->max_ecc_strength_supported = 40; + +#ifdef CONFIG_NAND_MXS_USE_MINIMUM_ECC + nand_info->use_minimum_ecc = true; +#endif + if (mxs_nand_init(nand_info) < 0) goto err; From 68748340c8613877d71b444c0dffe63b536d5a5f Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:16 +0200 Subject: [PATCH 47/59] mtd: nand: mxs_nand: move structs into header file Move structs into header file so we can use a separate compile unit for device tree support. Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 63 +++------------------------------------------ drivers/mtd/nand/mxs_nand.h | 62 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 60 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 3c9ee07..8748c92 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -13,12 +13,11 @@ */ #include -#include +#include #include #include #include #include -#include #include #include #include @@ -26,7 +25,6 @@ #include #include #include -#include #include "mxs_nand.h" #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 @@ -47,61 +45,6 @@ #define MXS_NAND_BCH_TIMEOUT 10000 -/** - * @gf_len: The length of Galois Field. (e.g., 13 or 14) - * @ecc_strength: A number that describes the strength of the ECC - * algorithm. - * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note - * the first chunk in the page includes both data and - * metadata, so it's a bit larger than this value. - * @ecc_chunk_count: The number of ECC chunks in the page, - * @block_mark_byte_offset: The byte offset in the ECC-based page view at - * which the underlying physical block mark appears. - * @block_mark_bit_offset: The bit offset into the ECC-based page view at - * which the underlying physical block mark appears. - */ -struct bch_geometry { - unsigned int gf_len; - unsigned int ecc_strength; - unsigned int ecc_chunk_size; - unsigned int ecc_chunk_count; - unsigned int block_mark_byte_offset; - unsigned int block_mark_bit_offset; -}; - -struct mxs_nand_info { - struct nand_chip chip; - unsigned int max_ecc_strength_supported; - bool use_minimum_ecc; - int cur_chip; - - uint32_t cmd_queue_len; - uint32_t data_buf_size; - struct bch_geometry bch_geometry; - - uint8_t *cmd_buf; - uint8_t *data_buf; - uint8_t *oob_buf; - - uint8_t marking_block_bad; - uint8_t raw_oob_mode; - - struct mxs_gpmi_regs *gpmi_regs; - struct mxs_bch_regs *bch_regs; - - /* Functions with altered behaviour */ - int (*hooked_read_oob)(struct mtd_info *mtd, - loff_t from, struct mtd_oob_ops *ops); - int (*hooked_write_oob)(struct mtd_info *mtd, - loff_t to, struct mtd_oob_ops *ops); - int (*hooked_block_markbad)(struct mtd_info *mtd, - loff_t ofs); - - /* DMA descriptors */ - struct mxs_dma_desc **desc; - uint32_t desc_index; -}; - struct nand_ecclayout fake_ecc_layout; /* @@ -1233,7 +1176,7 @@ int mxs_nand_init_spl(struct nand_chip *nand) return 0; } -int mxs_nand_init(struct mxs_nand_info *nand_info) +int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info) { struct mtd_info *mtd; struct nand_chip *nand; @@ -1328,7 +1271,7 @@ void board_nand_init(void) nand_info->use_minimum_ecc = true; #endif - if (mxs_nand_init(nand_info) < 0) + if (mxs_nand_init_ctrl(nand_info) < 0) goto err; return; diff --git a/drivers/mtd/nand/mxs_nand.h b/drivers/mtd/nand/mxs_nand.h index 379ed24..4bd65cd 100644 --- a/drivers/mtd/nand/mxs_nand.h +++ b/drivers/mtd/nand/mxs_nand.h @@ -7,5 +7,67 @@ * Stefan Agner */ +#include +#include +#include +#include + +/** + * @gf_len: The length of Galois Field. (e.g., 13 or 14) + * @ecc_strength: A number that describes the strength of the ECC + * algorithm. + * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note + * the first chunk in the page includes both data and + * metadata, so it's a bit larger than this value. + * @ecc_chunk_count: The number of ECC chunks in the page, + * @block_mark_byte_offset: The byte offset in the ECC-based page view at + * which the underlying physical block mark appears. + * @block_mark_bit_offset: The bit offset into the ECC-based page view at + * which the underlying physical block mark appears. + */ +struct bch_geometry { + unsigned int gf_len; + unsigned int ecc_strength; + unsigned int ecc_chunk_size; + unsigned int ecc_chunk_count; + unsigned int block_mark_byte_offset; + unsigned int block_mark_bit_offset; +}; + +struct mxs_nand_info { + struct nand_chip chip; + struct udevice *dev; + unsigned int max_ecc_strength_supported; + bool use_minimum_ecc; + int cur_chip; + + uint32_t cmd_queue_len; + uint32_t data_buf_size; + struct bch_geometry bch_geometry; + + uint8_t *cmd_buf; + uint8_t *data_buf; + uint8_t *oob_buf; + + uint8_t marking_block_bad; + uint8_t raw_oob_mode; + + struct mxs_gpmi_regs *gpmi_regs; + struct mxs_bch_regs *bch_regs; + + /* Functions with altered behaviour */ + int (*hooked_read_oob)(struct mtd_info *mtd, + loff_t from, struct mtd_oob_ops *ops); + int (*hooked_write_oob)(struct mtd_info *mtd, + loff_t to, struct mtd_oob_ops *ops); + int (*hooked_block_markbad)(struct mtd_info *mtd, + loff_t ofs); + + /* DMA descriptors */ + struct mxs_dma_desc **desc; + uint32_t desc_index; +}; + +int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info); int mxs_nand_init_spl(struct nand_chip *nand); int mxs_nand_setup_ecc(struct mtd_info *mtd); From f75e83bfae2bcf36197e25b8b3d539b0652b83fa Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:17 +0200 Subject: [PATCH 48/59] mtd: nand: mxs_nand: add device tree support Support driver data from device tree. Also support fsl,use-minimal-ecc similar to Linux' GPMI NAND driver. Signed-off-by: Stefan Agner --- drivers/mtd/nand/Kconfig | 7 ++++ drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/mxs_nand.c | 5 +++ drivers/mtd/nand/mxs_nand_dt.c | 86 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 drivers/mtd/nand/mxs_nand_dt.c diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index c039b9c..bdc2721 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -154,6 +154,13 @@ config NAND_MXS if NAND_MXS +config NAND_MXS_DT + bool "Support MXS NAND controller as a DT device" + depends on OF_CONTROL && MTD + help + Enable the driver for MXS NAND flash on platforms using + device tree. + config NAND_MXS_USE_MINIMUM_ECC bool "Use minimum ECC strength supported by the controller" default false diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index e20ef07..e00cbca 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o obj-$(CONFIG_NAND_MXC) += mxc_nand.o obj-$(CONFIG_NAND_MXS) += mxs_nand.o +obj-$(CONFIG_NAND_MXS_DT) += mxs_nand_dt.o obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o obj-$(CONFIG_NAND_SPEAR) += spr_nand.o obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 8748c92..99f392e 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -1201,6 +1201,9 @@ int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info) nand_set_controller_data(nand, nand_info); nand->options |= NAND_NO_SUBPAGE_WRITE; + if (nand_info->dev) + nand->flash_node = dev_of_offset(nand_info->dev); + nand->cmd_ctrl = mxs_nand_cmd_ctrl; nand->dev_ready = mxs_nand_device_ready; @@ -1247,6 +1250,7 @@ err_free_buffers: return err; } +#ifndef CONFIG_NAND_MXS_DT void board_nand_init(void) { struct mxs_nand_info *nand_info; @@ -1279,3 +1283,4 @@ void board_nand_init(void) err: free(nand_info); } +#endif diff --git a/drivers/mtd/nand/mxs_nand_dt.c b/drivers/mtd/nand/mxs_nand_dt.c new file mode 100644 index 0000000..f89eb09 --- /dev/null +++ b/drivers/mtd/nand/mxs_nand_dt.c @@ -0,0 +1,86 @@ +/* + * NXP GPMI NAND flash driver (DT initialization) + * + * Copyright (C) 2018 Toradex + * Authors: + * Stefan Agner + * + * Based on denali_dt.c + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +#include "mxs_nand.h" + +struct mxs_nand_dt_data { + unsigned int max_ecc_strength_supported; +}; + +static const struct mxs_nand_dt_data mxs_nand_imx7d_data = { + .max_ecc_strength_supported = 62, +}; + +static const struct udevice_id mxs_nand_dt_ids[] = { + { + .compatible = "fsl,imx7d-gpmi-nand", + .data = (unsigned long)&mxs_nand_imx7d_data, + }, + { /* sentinel */ } +}; + +static int mxs_nand_dt_probe(struct udevice *dev) +{ + struct mxs_nand_info *info = dev_get_priv(dev); + const struct mxs_nand_dt_data *data; + struct resource res; + int ret; + + data = (void *)dev_get_driver_data(dev); + if (data) + info->max_ecc_strength_supported = data->max_ecc_strength_supported; + + info->dev = dev; + + ret = dev_read_resource_byname(dev, "gpmi-nand", &res); + if (ret) + return ret; + + info->gpmi_regs = devm_ioremap(dev, res.start, resource_size(&res)); + + + ret = dev_read_resource_byname(dev, "bch", &res); + if (ret) + return ret; + + info->bch_regs = devm_ioremap(dev, res.start, resource_size(&res)); + + info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc"); + + return mxs_nand_init_ctrl(info); +} + +U_BOOT_DRIVER(mxs_nand_dt) = { + .name = "mxs-nand-dt", + .id = UCLASS_MTD, + .of_match = mxs_nand_dt_ids, + .probe = mxs_nand_dt_probe, + .priv_auto_alloc_size = sizeof(struct mxs_nand_info), +}; + +void board_nand_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_GET_DRIVER(mxs_nand_dt), + &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize MXS NAND controller. (error %d)\n", + ret); +} From 627544506f5709bb2d14f0db66661a27cd78ec0a Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:18 +0200 Subject: [PATCH 49/59] mtd: nand: mxs_nand: add support for specific ECC strength Add support for specified ECC strength/size using device tree properties nand-ecc-strength/nand-ecc-step-size. This aligns behavior with the mainline driver, such that: - If fsl,use-minimal-ecc is requested it will use data from data sheet/ONFI. If this is not available the driver will fail. - If nand-ecc-strength/nand-ecc-step-size are specified those value will be used. - By default maximum possible ECC strength is used Signed-off-by: Stefan Agner --- drivers/mtd/nand/mxs_nand.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index 99f392e..e334181 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -161,15 +161,14 @@ static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo, } static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, - struct mtd_info *mtd) + struct mtd_info *mtd, + unsigned int ecc_strength, + unsigned int ecc_step) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); - if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) - return -ENOTSUPP; - - switch (chip->ecc_step_ds) { + switch (ecc_step) { case SZ_512: geo->gf_len = 13; break; @@ -180,8 +179,8 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, return -EINVAL; } - geo->ecc_chunk_size = chip->ecc_step_ds; - geo->ecc_strength = round_up(chip->ecc_strength_ds, 2); + geo->ecc_chunk_size = ecc_step; + geo->ecc_strength = round_up(ecc_strength, 2); /* Keep the C >= O */ if (geo->ecc_chunk_size < mtd->oobsize) @@ -964,6 +963,28 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs) return 0; } +static int mxs_nand_set_geometry(struct mtd_info *mtd, struct bch_geometry *geo) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_chip *nand = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + + if (chip->ecc.strength > 0 && chip->ecc.size > 0) + return mxs_nand_calc_ecc_layout_by_info(geo, mtd, + chip->ecc.strength, chip->ecc.size); + + if (nand_info->use_minimum_ecc || + mxs_nand_calc_ecc_layout(geo, mtd)) { + if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) + return -EINVAL; + + return mxs_nand_calc_ecc_layout_by_info(geo, mtd, + chip->ecc_strength_ds, chip->ecc_step_ds); + } + + return 0; +} + /* * At this point, the physical NAND Flash chips have been identified and * counted, so we know the physical geometry. This enables us to make some @@ -980,14 +1001,9 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) struct bch_geometry *geo = &nand_info->bch_geometry; struct mxs_bch_regs *bch_regs = nand_info->bch_regs; uint32_t tmp; - int ret = -ENOTSUPP; - - if (nand_info->use_minimum_ecc) - ret = mxs_nand_calc_ecc_layout_by_info(geo, mtd); - - if (ret == -ENOTSUPP) - ret = mxs_nand_calc_ecc_layout(geo, mtd); + int ret; + ret = mxs_nand_set_geometry(mtd, geo); if (ret) return ret; From aba6a0fb8f14b048dfbc6282ce015e9a45dcd02f Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:19 +0200 Subject: [PATCH 50/59] arm: dts: imx7: sync with Linux Sync with Linux commit 60cc43fc8884 ("Linux 4.17-rc1"). Signed-off-by: Stefan Agner --- arch/arm/dts/imx7s.dtsi | 491 ++++++++++++++++++++------------ include/dt-bindings/clock/imx7d-clock.h | 15 +- include/dt-bindings/power/imx7-power.h | 16 ++ 3 files changed, 341 insertions(+), 181 deletions(-) create mode 100644 include/dt-bindings/power/imx7-power.h diff --git a/arch/arm/dts/imx7s.dtsi b/arch/arm/dts/imx7s.dtsi index a7d48e7..4d42335 100644 --- a/arch/arm/dts/imx7s.dtsi +++ b/arch/arm/dts/imx7s.dtsi @@ -42,6 +42,7 @@ */ #include +#include #include #include #include @@ -57,7 +58,7 @@ * Also for U-Boot there must be a pre-existing /memory node. */ chosen {}; - memory { device_type = "memory"; reg = <0 0>; }; + memory { device_type = "memory"; }; aliases { gpio0 = &gpio1; @@ -115,11 +116,77 @@ clock-output-names = "osc"; }; + usbphynop1: usbphynop1 { + compatible = "usb-nop-xceiv"; + clocks = <&clks IMX7D_USB_PHY1_CLK>; + clock-names = "main_clk"; + #phy-cells = <0>; + }; + + usbphynop3: usbphynop3 { + compatible = "usb-nop-xceiv"; + clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>; + clock-names = "main_clk"; + #phy-cells = <0>; + }; + + pmu { + compatible = "arm,cortex-a7-pmu"; + interrupt-parent = <&gpc>; + interrupts = ; + interrupt-affinity = <&cpu0>; + }; + + replicator { + /* + * non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell" + */ + compatible = "arm,coresight-replicator"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + /* replicator output ports */ + port@0 { + reg = <0>; + replicator_out_port0: endpoint { + remote-endpoint = <&tpiu_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator_out_port1: endpoint { + remote-endpoint = <&etr_in_port>; + }; + }; + + /* replicator input port */ + port@2 { + reg = <0>; + replicator_in_port0: endpoint { + slave-mode; + remote-endpoint = <&etf_out_port>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupt-parent = <&intc>; + interrupts = , + , + , + ; + }; + soc { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; - interrupt-parent = <&intc>; + interrupt-parent = <&gpc>; ranges; funnel@30041000 { @@ -259,62 +326,18 @@ }; }; - replicator { - /* - * non-configurable replicators don't show up on the - * AMBA bus. As such no need to add "arm,primecell" - */ - compatible = "arm,coresight-replicator"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - /* replicator output ports */ - port@0 { - reg = <0>; - replicator_out_port0: endpoint { - remote-endpoint = <&tpiu_in_port>; - }; - }; - - port@1 { - reg = <1>; - replicator_out_port1: endpoint { - remote-endpoint = <&etr_in_port>; - }; - }; - - /* replicator input port */ - port@2 { - reg = <0>; - replicator_in_port0: endpoint { - slave-mode; - remote-endpoint = <&etf_out_port>; - }; - }; - }; - }; - intc: interrupt-controller@31001000 { compatible = "arm,cortex-a7-gic"; interrupts = ; #interrupt-cells = <3>; interrupt-controller; + interrupt-parent = <&intc>; reg = <0x31001000 0x1000>, <0x31002000 0x2000>, <0x31004000 0x2000>, <0x31006000 0x2000>; }; - timer { - compatible = "arm,armv7-timer"; - interrupts = , - , - , - ; - }; - aips1: aips-bus@30000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; @@ -482,20 +505,49 @@ status = "disabled"; }; + kpp: kpp@30320000 { + compatible = "fsl,imx7d-kpp", "fsl,imx21-kpp"; + reg = <0x30320000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_KPP_ROOT_CLK>; + status = "disabled"; + }; + iomuxc: iomuxc@30330000 { compatible = "fsl,imx7d-iomuxc"; reg = <0x30330000 0x10000>; }; gpr: iomuxc-gpr@30340000 { - compatible = "fsl,imx7d-iomuxc-gpr", "syscon"; + compatible = "fsl,imx7d-iomuxc-gpr", + "fsl,imx6q-iomuxc-gpr", "syscon"; reg = <0x30340000 0x10000>; }; ocotp: ocotp-ctrl@30350000 { + #address-cells = <1>; + #size-cells = <1>; compatible = "fsl,imx7d-ocotp", "syscon"; reg = <0x30350000 0x10000>; clocks = <&clks IMX7D_OCOTP_CLK>; + + tempmon_calib: calib@3c { + reg = <0x3c 0x4>; + }; + + tempmon_temp_grade: temp-grade@10 { + reg = <0x10 0x4>; + }; + }; + + tempmon: tempmon { + compatible = "fsl,imx7d-tempmon"; + interrupts = ; + fsl,tempmon =<&anatop>; + nvmem-cells = <&tempmon_calib>, + <&tempmon_temp_grade>; + nvmem-cell-names = "calib", "temp_grade"; + clocks = <&clks IMX7D_PLL_SYS_MAIN_CLK>; }; anatop: anatop@30360000 { @@ -504,8 +556,11 @@ reg = <0x30360000 0x10000>; interrupts = , ; + #address-cells = <1>; + #size-cells = <0>; - reg_1p0d: regulator-vdd1p0d { + reg_1p0d: regulator-vdd1p0d@30360210 { + reg = <0x30360210>; compatible = "fsl,anatop-regulator"; regulator-name = "vdd1p0d"; regulator-min-microvolt = <800000>; @@ -516,6 +571,7 @@ anatop-min-bit-val = <8>; anatop-min-voltage = <800000>; anatop-max-voltage = <1200000>; + anatop-enable-bit = <0>; }; }; @@ -529,12 +585,15 @@ offset = <0x34>; interrupts = , ; + clocks = <&clks IMX7D_SNVS_CLK>; + clock-names = "snvs-rtc"; }; snvs_poweroff: snvs-poweroff { compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; }; @@ -558,11 +617,32 @@ }; src: src@30390000 { - compatible = "fsl,imx7d-src", "fsl,imx51-src", "syscon"; + compatible = "fsl,imx7d-src", "syscon"; reg = <0x30390000 0x10000>; interrupts = ; #reset-cells = <1>; }; + + gpc: gpc@303a0000 { + compatible = "fsl,imx7d-gpc"; + reg = <0x303a0000 0x10000>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + #power-domain-cells = <1>; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + pgc_pcie_phy: pgc-power-domain@1 { + #power-domain-cells = <0>; + reg = <1>; + power-supply = <®_1p0d>; + }; + }; + }; }; aips2: aips-bus@30400000 { @@ -609,7 +689,7 @@ clocks = <&clks IMX7D_PWM1_ROOT_CLK>, <&clks IMX7D_PWM1_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -620,7 +700,7 @@ clocks = <&clks IMX7D_PWM2_ROOT_CLK>, <&clks IMX7D_PWM2_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -631,7 +711,7 @@ clocks = <&clks IMX7D_PWM3_ROOT_CLK>, <&clks IMX7D_PWM3_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -642,7 +722,7 @@ clocks = <&clks IMX7D_PWM4_ROOT_CLK>, <&clks IMX7D_PWM4_ROOT_CLK>; clock-names = "ipg", "per"; - #pwm-cells = <2>; + #pwm-cells = <3>; status = "disabled"; }; @@ -664,118 +744,156 @@ reg = <0x30800000 0x400000>; ranges; - ecspi1: ecspi@30820000 { + spba-bus@30800000 { + compatible = "fsl,spba-bus", "simple-bus"; #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi"; - reg = <0x30820000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>, - <&clks IMX7D_ECSPI1_ROOT_CLK>; - clock-names = "ipg", "per"; - status = "disabled"; - }; + #size-cells = <1>; + reg = <0x30800000 0x100000>; + ranges; + + ecspi1: ecspi@30820000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi"; + reg = <0x30820000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>, + <&clks IMX7D_ECSPI1_ROOT_CLK>; + clock-names = "ipg", "per"; + status = "disabled"; + }; - ecspi2: ecspi@30830000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi"; - reg = <0x30830000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>, - <&clks IMX7D_ECSPI2_ROOT_CLK>; - clock-names = "ipg", "per"; - status = "disabled"; - }; + ecspi2: ecspi@30830000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi"; + reg = <0x30830000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>, + <&clks IMX7D_ECSPI2_ROOT_CLK>; + clock-names = "ipg", "per"; + status = "disabled"; + }; - ecspi3: ecspi@30840000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi"; - reg = <0x30840000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>, - <&clks IMX7D_ECSPI3_ROOT_CLK>; - clock-names = "ipg", "per"; - status = "disabled"; - }; + ecspi3: ecspi@30840000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi"; + reg = <0x30840000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>, + <&clks IMX7D_ECSPI3_ROOT_CLK>; + clock-names = "ipg", "per"; + status = "disabled"; + }; - uart1: serial@30860000 { - compatible = "fsl,imx7d-uart", - "fsl,imx6q-uart"; - reg = <0x30860000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_UART1_ROOT_CLK>, - <&clks IMX7D_UART1_ROOT_CLK>; - clock-names = "ipg", "per"; - status = "disabled"; - }; + uart1: serial@30860000 { + compatible = "fsl,imx7d-uart", + "fsl,imx6q-uart"; + reg = <0x30860000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_UART1_ROOT_CLK>, + <&clks IMX7D_UART1_ROOT_CLK>; + clock-names = "ipg", "per"; + status = "disabled"; + }; - uart2: serial@30890000 { - compatible = "fsl,imx7d-uart", - "fsl,imx6q-uart"; - reg = <0x30890000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_UART2_ROOT_CLK>, - <&clks IMX7D_UART2_ROOT_CLK>; - clock-names = "ipg", "per"; - status = "disabled"; - }; + uart2: serial@30890000 { + compatible = "fsl,imx7d-uart", + "fsl,imx6q-uart"; + reg = <0x30890000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_UART2_ROOT_CLK>, + <&clks IMX7D_UART2_ROOT_CLK>; + clock-names = "ipg", "per"; + status = "disabled"; + }; - uart3: serial@30880000 { - compatible = "fsl,imx7d-uart", - "fsl,imx6q-uart"; - reg = <0x30880000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_UART3_ROOT_CLK>, - <&clks IMX7D_UART3_ROOT_CLK>; - clock-names = "ipg", "per"; - status = "disabled"; - }; + uart3: serial@30880000 { + compatible = "fsl,imx7d-uart", + "fsl,imx6q-uart"; + reg = <0x30880000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_UART3_ROOT_CLK>, + <&clks IMX7D_UART3_ROOT_CLK>; + clock-names = "ipg", "per"; + status = "disabled"; + }; - sai1: sai@308a0000 { - #sound-dai-cells = <0>; - compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai"; - reg = <0x308a0000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_SAI1_IPG_CLK>, - <&clks IMX7D_SAI1_ROOT_CLK>, - <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>; - clock-names = "bus", "mclk1", "mclk2", "mclk3"; - dma-names = "rx", "tx"; - dmas = <&sdma 8 24 0>, <&sdma 9 24 0>; - status = "disabled"; - }; + sai1: sai@308a0000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai"; + reg = <0x308a0000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_SAI1_IPG_CLK>, + <&clks IMX7D_SAI1_ROOT_CLK>, + <&clks IMX7D_CLK_DUMMY>, + <&clks IMX7D_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "rx", "tx"; + dmas = <&sdma 8 24 0>, <&sdma 9 24 0>; + status = "disabled"; + }; - sai2: sai@308b0000 { - #sound-dai-cells = <0>; - compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai"; - reg = <0x308b0000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_SAI2_IPG_CLK>, - <&clks IMX7D_SAI2_ROOT_CLK>, - <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>; - clock-names = "bus", "mclk1", "mclk2", "mclk3"; - dma-names = "rx", "tx"; - dmas = <&sdma 10 24 0>, <&sdma 11 24 0>; - status = "disabled"; + sai2: sai@308b0000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai"; + reg = <0x308b0000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_SAI2_IPG_CLK>, + <&clks IMX7D_SAI2_ROOT_CLK>, + <&clks IMX7D_CLK_DUMMY>, + <&clks IMX7D_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "rx", "tx"; + dmas = <&sdma 10 24 0>, <&sdma 11 24 0>; + status = "disabled"; + }; + + sai3: sai@308c0000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai"; + reg = <0x308c0000 0x10000>; + interrupts = ; + clocks = <&clks IMX7D_SAI3_IPG_CLK>, + <&clks IMX7D_SAI3_ROOT_CLK>, + <&clks IMX7D_CLK_DUMMY>, + <&clks IMX7D_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "rx", "tx"; + dmas = <&sdma 12 24 0>, <&sdma 13 24 0>; + status = "disabled"; + }; }; - sai3: sai@308c0000 { - #sound-dai-cells = <0>; - compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai"; - reg = <0x308c0000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_SAI3_IPG_CLK>, - <&clks IMX7D_SAI3_ROOT_CLK>, - <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>; - clock-names = "bus", "mclk1", "mclk2", "mclk3"; - dma-names = "rx", "tx"; - dmas = <&sdma 12 24 0>, <&sdma 13 24 0>; - status = "disabled"; + crypto: caam@30900000 { + compatible = "fsl,sec-v4.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x30900000 0x40000>; + ranges = <0 0x30900000 0x40000>; + interrupts = ; + clocks = <&clks IMX7D_CAAM_CLK>, + <&clks IMX7D_AHB_CHANNEL_ROOT_CLK>; + clock-names = "ipg", "aclk"; + + sec_jr0: jr0@1000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x1000 0x1000>; + interrupts = ; + }; + + sec_jr1: jr1@2000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x2000 0x1000>; + interrupts = ; + }; + + sec_jr2: jr1@3000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x3000 0x1000>; + interrupts = ; + }; }; flexcan1: can@30a00000 { @@ -918,24 +1036,12 @@ reg = <0x30b30200 0x200>; }; - usbphynop1: usbphynop1 { - compatible = "usb-nop-xceiv"; - clocks = <&clks IMX7D_USB_PHY1_CLK>; - clock-names = "main_clk"; - }; - - usbphynop3: usbphynop3 { - compatible = "usb-nop-xceiv"; - clocks = <&clks IMX7D_USB_HSIC_ROOT_CLK>; - clock-names = "main_clk"; - }; - usdhc1: usdhc@30b40000 { compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b40000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC1_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -946,8 +1052,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b50000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC2_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -958,8 +1064,8 @@ compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc"; reg = <0x30b60000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, - <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_IPG_ROOT_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>, <&clks IMX7D_USDHC3_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; @@ -980,9 +1086,11 @@ fec1: ethernet@30be0000 { compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec"; reg = <0x30be0000 0x10000>; - interrupts = , + interrupt-names = "int0", "int1", "int2", "pps"; + interrupts = , + , , - ; + ; clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>, <&clks IMX7D_ENET_AXI_ROOT_CLK>, <&clks IMX7D_ENET1_TIME_ROOT_CLK>, @@ -995,5 +1103,36 @@ status = "disabled"; }; }; + + dma_apbh: dma-apbh@33000000 { + compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh"; + reg = <0x33000000 0x2000>; + interrupts = , + , + , + ; + interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; + }; + + gpmi: gpmi-nand@33002000{ + compatible = "fsl,imx7d-gpmi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x33002000 0x2000>, <0x33004000 0x4000>; + reg-names = "gpmi-nand", "bch"; + interrupts = ; + interrupt-names = "bch"; + clocks = <&clks IMX7D_NAND_RAWNAND_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; + clock-names = "gpmi_io", "gpmi_bch_apb"; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; + status = "disabled"; + assigned-clocks = <&clks IMX7D_NAND_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_500M_CLK>; + }; }; }; diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h index a7a1a50..b2325d3 100644 --- a/include/dt-bindings/clock/imx7d-clock.h +++ b/include/dt-bindings/clock/imx7d-clock.h @@ -80,10 +80,10 @@ #define IMX7D_ARM_M4_ROOT_SRC 67 #define IMX7D_ARM_M4_ROOT_CG 68 #define IMX7D_ARM_M4_ROOT_DIV 69 -#define IMX7D_ARM_M0_ROOT_CLK 70 -#define IMX7D_ARM_M0_ROOT_SRC 71 -#define IMX7D_ARM_M0_ROOT_CG 72 -#define IMX7D_ARM_M0_ROOT_DIV 73 +#define IMX7D_ARM_M0_ROOT_CLK 70 /* unused */ +#define IMX7D_ARM_M0_ROOT_SRC 71 /* unused */ +#define IMX7D_ARM_M0_ROOT_CG 72 /* unused */ +#define IMX7D_ARM_M0_ROOT_DIV 73 /* unused */ #define IMX7D_MAIN_AXI_ROOT_CLK 74 #define IMX7D_MAIN_AXI_ROOT_SRC 75 #define IMX7D_MAIN_AXI_ROOT_CG 76 @@ -450,5 +450,10 @@ #define IMX7D_CLK_ARM 437 #define IMX7D_CKIL 438 #define IMX7D_OCOTP_CLK 439 -#define IMX7D_CLK_END 440 +#define IMX7D_NAND_RAWNAND_CLK 440 +#define IMX7D_NAND_USDHC_BUS_RAWNAND_CLK 441 +#define IMX7D_SNVS_CLK 442 +#define IMX7D_CAAM_CLK 443 +#define IMX7D_KPP_ROOT_CLK 444 +#define IMX7D_CLK_END 445 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ diff --git a/include/dt-bindings/power/imx7-power.h b/include/dt-bindings/power/imx7-power.h new file mode 100644 index 0000000..3a181e4 --- /dev/null +++ b/include/dt-bindings/power/imx7-power.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2017 Impinj + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __DT_BINDINGS_IMX7_POWER_H__ +#define __DT_BINDINGS_IMX7_POWER_H__ + +#define IMX7_POWER_DOMAIN_MIPI_PHY 0 +#define IMX7_POWER_DOMAIN_PCIE_PHY 1 +#define IMX7_POWER_DOMAIN_USB_HSIC_PHY 2 + +#endif From fd8c1fc943017dd4d68eef5e4f996133051d3bc6 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 22 Jun 2018 18:06:20 +0200 Subject: [PATCH 51/59] arm: dts: imx7: colibri: add raw NAND support Signed-off-by: Stefan Agner --- arch/arm/dts/imx7-colibri.dts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/dts/imx7-colibri.dts b/arch/arm/dts/imx7-colibri.dts index a2cade7..dca501b 100644 --- a/arch/arm/dts/imx7-colibri.dts +++ b/arch/arm/dts/imx7-colibri.dts @@ -16,6 +16,15 @@ }; }; +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + fsl,use-minimum-ecc; + nand-on-flash-bbt; + nand-ecc-mode = "hw"; + status = "okay"; +}; + &i2c1 { pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; @@ -48,6 +57,25 @@ }; &iomuxc { + pinctrl_gpmi_nand: gpmi-nand-grp { + fsl,pins = < + MX7D_PAD_SD3_CLK__NAND_CLE 0x71 + MX7D_PAD_SD3_CMD__NAND_ALE 0x71 + MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B 0x71 + MX7D_PAD_SAI1_TX_DATA__NAND_READY_B 0x74 + MX7D_PAD_SD3_STROBE__NAND_RE_B 0x71 + MX7D_PAD_SD3_RESET_B__NAND_WE_B 0x71 + MX7D_PAD_SD3_DATA0__NAND_DATA00 0x71 + MX7D_PAD_SD3_DATA1__NAND_DATA01 0x71 + MX7D_PAD_SD3_DATA2__NAND_DATA02 0x71 + MX7D_PAD_SD3_DATA3__NAND_DATA03 0x71 + MX7D_PAD_SD3_DATA4__NAND_DATA04 0x71 + MX7D_PAD_SD3_DATA5__NAND_DATA05 0x71 + MX7D_PAD_SD3_DATA6__NAND_DATA06 0x71 + MX7D_PAD_SD3_DATA7__NAND_DATA07 0x71 + >; + }; + pinctrl_i2c4: i2c4-grp { fsl,pins = < MX7D_PAD_ENET1_RGMII_TD3__I2C4_SDA 0x4000007f From 7da7ff54914ca58a289bd8e0fda6e7240c545826 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 25 Apr 2018 10:06:00 -0700 Subject: [PATCH 52/59] power: pmic: Let PFUZE3000 see all 256 registers The PFUZE3000 uses registers addresses up to 0xff. The DM pfuze100 driver supports both pfuze100 and pfuze3000. Allow it to use the device type to return the correct number of registers. Also rename the too generic PMIC_NUM_OF_REGS enumeration value for pfuze3000 to match the other "PFUZE3000_" prefixed enumerations and the pfuze100 enumeration value PFUZE100_NUM_OF_REGS. Cc: Peng Fan Cc: Jaehoon Chung Cc: Stefano Babic Cc: Fabio Estevam Signed-off-by: Trent Piepho Reviewed-by: Fabio Estevam --- drivers/power/pmic/pfuze100.c | 3 ++- drivers/power/pmic/pmic_pfuze3000.c | 2 +- include/power/pfuze3000_pmic.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c index 4670a84..8a5a899 100644 --- a/drivers/power/pmic/pfuze100.c +++ b/drivers/power/pmic/pfuze100.c @@ -12,6 +12,7 @@ #include #include #include +#include static const struct pmic_child_info pmic_children_info[] = { /* sw[x], swbst */ @@ -23,7 +24,7 @@ static const struct pmic_child_info pmic_children_info[] = { static int pfuze100_reg_count(struct udevice *dev) { - return PFUZE100_NUM_OF_REGS; + return dev->driver_data == PFUZE3000 ? PFUZE3000_NUM_OF_REGS : PFUZE100_NUM_OF_REGS; } static int pfuze100_write(struct udevice *dev, uint reg, const uint8_t *buff, diff --git a/drivers/power/pmic/pmic_pfuze3000.c b/drivers/power/pmic/pmic_pfuze3000.c index f2a51fe..1077fa5 100644 --- a/drivers/power/pmic/pmic_pfuze3000.c +++ b/drivers/power/pmic/pmic_pfuze3000.c @@ -22,7 +22,7 @@ int power_pfuze3000_init(unsigned char bus) p->name = name; p->interface = PMIC_I2C; - p->number_of_regs = PMIC_NUM_OF_REGS; + p->number_of_regs = PFUZE3000_NUM_OF_REGS; p->hw.i2c.addr = CONFIG_POWER_PFUZE3000_I2C_ADDR; p->hw.i2c.tx_num = 1; p->bus = bus; diff --git a/include/power/pfuze3000_pmic.h b/include/power/pfuze3000_pmic.h index 87ea7ca..b836d67 100644 --- a/include/power/pfuze3000_pmic.h +++ b/include/power/pfuze3000_pmic.h @@ -69,7 +69,7 @@ enum { PFUZE3000_VLDO3CTL = 0x70, PFUZE3000_VLD4CTL = 0x71, - PMIC_NUM_OF_REGS = 0x7F, + PFUZE3000_NUM_OF_REGS = 0x100, }; int power_pfuze3000_init(unsigned char bus); From 18053a8505d353336ae784d70a52e1f96f8bae7e Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Mon, 18 Jun 2018 11:12:19 +0530 Subject: [PATCH 53/59] imx6ul: geam: Fix fdt_file mismatch fdt_file is looking for imx6ul-geam-kit.dtb but Linux has imx6ul-geam.dtb, since Linux skipped -kit on file name by below commit. "ARM: dts: imx6ul-geam: Skip suffix -kit from dts name" (sha1: 182de5ebce71e469cfa686fcdf08c9cbe11ece97) So, due to this mismatch U-Boot failed to pick the proper dtb which eventually break the Linux boot. This patch fixed this mismatch by - renaming dts files - update config option to use new dtb file - update fdt_file to new dtb file name Signed-off-by: Jagan Teki Reviewed-by: Fabio Estevam --- arch/arm/dts/Makefile | 2 +- arch/arm/dts/{imx6ul-geam-kit-u-boot.dtsi => imx6ul-geam-u-boot.dtsi} | 0 arch/arm/dts/{imx6ul-geam-kit.dts => imx6ul-geam.dts} | 0 board/engicam/common/board.c | 4 ++-- configs/imx6ul_geam_mmc_defconfig | 2 +- configs/imx6ul_geam_nand_defconfig | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename arch/arm/dts/{imx6ul-geam-kit-u-boot.dtsi => imx6ul-geam-u-boot.dtsi} (100%) rename arch/arm/dts/{imx6ul-geam-kit.dts => imx6ul-geam.dts} (100%) diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 493652e..baad87d 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -425,7 +425,7 @@ dtb-$(CONFIG_MX6SX) += \ imx6sx-sdb.dtb dtb-$(CONFIG_MX6UL) += \ - imx6ul-geam-kit.dtb \ + imx6ul-geam.dtb \ imx6ul-isiot-emmc.dtb \ imx6ul-isiot-nand.dtb \ imx6ul-opos6uldev.dtb diff --git a/arch/arm/dts/imx6ul-geam-kit-u-boot.dtsi b/arch/arm/dts/imx6ul-geam-u-boot.dtsi similarity index 100% rename from arch/arm/dts/imx6ul-geam-kit-u-boot.dtsi rename to arch/arm/dts/imx6ul-geam-u-boot.dtsi diff --git a/arch/arm/dts/imx6ul-geam-kit.dts b/arch/arm/dts/imx6ul-geam.dts similarity index 100% rename from arch/arm/dts/imx6ul-geam-kit.dts rename to arch/arm/dts/imx6ul-geam.dts diff --git a/board/engicam/common/board.c b/board/engicam/common/board.c index fb37403..5dccb17 100644 --- a/board/engicam/common/board.c +++ b/board/engicam/common/board.c @@ -50,8 +50,8 @@ static void setenv_fdt_file(void) env_set("fdt_file", "imx6q-icore-rqs.dtb"); else if (is_mx6dl() || is_mx6solo()) env_set("fdt_file", "imx6dl-icore-rqs.dtb"); - } else if (!strcmp(cmp_dtb, "imx6ul-geam-kit")) - env_set("fdt_file", "imx6ul-geam-kit.dtb"); + } else if (!strcmp(cmp_dtb, "imx6ul-geam")) + env_set("fdt_file", "imx6ul-geam.dtb"); else if (!strcmp(cmp_dtb, "imx6ul-isiot-mmc")) env_set("fdt_file", "imx6ul-isiot-emmc.dtb"); else if (!strcmp(cmp_dtb, "imx6ul-isiot-emmc")) diff --git a/configs/imx6ul_geam_mmc_defconfig b/configs/imx6ul_geam_mmc_defconfig index 4ae09ff..6cd1bfd 100644 --- a/configs/imx6ul_geam_mmc_defconfig +++ b/configs/imx6ul_geam_mmc_defconfig @@ -10,7 +10,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL=y CONFIG_SPL_LIBDISK_SUPPORT=y # CONFIG_CMD_BMODE is not set -CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam-kit" +CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam" CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_FIT_VERBOSE=y diff --git a/configs/imx6ul_geam_nand_defconfig b/configs/imx6ul_geam_nand_defconfig index e8f9cb4..d3364a7 100644 --- a/configs/imx6ul_geam_nand_defconfig +++ b/configs/imx6ul_geam_nand_defconfig @@ -8,7 +8,7 @@ CONFIG_TARGET_MX6UL_ENGICAM=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL=y # CONFIG_CMD_BMODE is not set -CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam-kit" +CONFIG_DEFAULT_DEVICE_TREE="imx6ul-geam" CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_FIT_VERBOSE=y From 02bbe2aaa28fe2dde79b6d0e9ed5ed8963f79a8b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Jun 2018 12:57:35 -0300 Subject: [PATCH 54/59] cl-som-imx7: Remove CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y Since commit 1da1938d57b3 ("spl: Add default values for ARCH_MX7") CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is selected by default on i.MX7 platforms, so remove it from the board defconfig. Signed-off-by: Fabio Estevam --- configs/cl-som-imx7_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/cl-som-imx7_defconfig b/configs/cl-som-imx7_defconfig index 6d403ee..38be7db 100644 --- a/configs/cl-som-imx7_defconfig +++ b/configs/cl-som-imx7_defconfig @@ -17,7 +17,6 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" CONFIG_SPI_BOOT=y CONFIG_BOOTDELAY=3 CONFIG_SPL_BOARD_INIT=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x80 CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_SPI_LOAD=y From da37d096820e15b2bcdb0243da2dc01707c650f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= Date: Sun, 14 Jan 2018 19:26:37 +0100 Subject: [PATCH 55/59] mtd: nand: export nand_get_flash_type function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `nand_get_flash_type()` allows identification of supported NAND flashs. The function is useful in SPL (like mxs_nand_spl.c) to lookup for a NAND flash (which does not support ONFi) instead of using nand_simple.c and hard-coding all required NAND parameters. Signed-off-by: Jörg Krause --- drivers/mtd/nand/nand_base.c | 3 ++- include/linux/mtd/rawnand.h | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index eb9f121..64e4621 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3755,7 +3755,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, /* * Get the flash and manufacturer id and lookup if the type is supported. */ -static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, +struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, struct nand_chip *chip, int *maf_id, int *dev_id, struct nand_flash_dev *type) @@ -3927,6 +3927,7 @@ ident_done: mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); return type; } +EXPORT_SYMBOL(nand_get_flash_type); #if CONFIG_IS_ENABLED(OF_CONTROL) DECLARE_GLOBAL_DATA_PTR; diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 7fe553f..cdad7b8 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -22,9 +22,16 @@ #include struct mtd_info; +struct nand_chip; struct nand_flash_dev; struct device_node; +/* Get the flash and manufacturer id and lookup if the type is supported. */ +struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, + struct nand_chip *chip, + int *maf_id, int *dev_id, + struct nand_flash_dev *type); + /* Scan and identify a NAND device */ int nand_scan(struct mtd_info *mtd, int max_chips); /* @@ -247,9 +254,6 @@ typedef enum { #define NAND_CI_CELLTYPE_MSK 0x0C #define NAND_CI_CELLTYPE_SHIFT 2 -/* Keep gcc happy */ -struct nand_chip; - /* ONFI features */ #define ONFI_FEATURE_16_BIT_BUS (1 << 0) #define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7) From 15e207faa0c32b587c173844936cadd7bf8dee01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= Date: Sun, 14 Jan 2018 19:26:38 +0100 Subject: [PATCH 56/59] spl, nand: add option CONFIG_SPL_NAND_IDENT to lookup for supported NAND chips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the config option `CONFIG_SPL_NAND_IDENT` for using the NAND chip ID list to identify the NAND flash in SPL. Signed-off-by: Jörg Krause --- README | 4 ++++ drivers/mtd/nand/Makefile | 1 + scripts/config_whitelist.txt | 1 + 3 files changed, 6 insertions(+) diff --git a/README b/README index fb331f9..b1ddf89 100644 --- a/README +++ b/README @@ -2625,6 +2625,10 @@ FIT uImage format: CONFIG_SPL_NAND_DRIVERS SPL uses normal NAND drivers, not minimal drivers. + CONFIG_SPL_NAND_IDENT + SPL uses the chip ID list to identify the NAND flash. + Requires CONFIG_SPL_NAND_BASE. + CONFIG_SPL_NAND_ECC Include standard software ECC in the SPL diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index e00cbca..c61e3f3 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o +obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o obj-$(CONFIG_SPL_NAND_INIT) += nand.o ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 1a54337..1219dcc 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1937,6 +1937,7 @@ CONFIG_SPL_NAND_BASE CONFIG_SPL_NAND_BOOT CONFIG_SPL_NAND_DRIVERS CONFIG_SPL_NAND_ECC +CONFIG_SPL_NAND_IDENT CONFIG_SPL_NAND_INIT CONFIG_SPL_NAND_LOAD CONFIG_SPL_NAND_MINIMAL From f3f2af3bdf2af89d0621aa0fbd94a918e4447081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= Date: Sun, 14 Jan 2018 19:26:39 +0100 Subject: [PATCH 57/59] mtd: nand: mxs_nand_spl: refactor mxs_flash_ident MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing `mxs_flash_ident()` is limited to identify ONFi compliant NAND chips only. In order to support non-ONFi NAND chips refactor the function and rename it to `mxs_flash_onfi_ident()`. A follow-up patch will add `mxs_flash_full_ident()` which allows to use the chip ID list to lookup for supported NAND flashs. Signed-off-by: Jörg Krause --- drivers/mtd/nand/mxs_nand_spl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/mxs_nand_spl.c b/drivers/mtd/nand/mxs_nand_spl.c index 47857a8..adb12c5 100644 --- a/drivers/mtd/nand/mxs_nand_spl.c +++ b/drivers/mtd/nand/mxs_nand_spl.c @@ -49,7 +49,7 @@ static void mxs_nand_command(struct mtd_info *mtd, unsigned int command, } } -static int mxs_flash_ident(struct mtd_info *mtd) +static int mxs_flash_onfi_ident(struct mtd_info *mtd) { register struct nand_chip *chip = mtd_to_nand(mtd); int i; @@ -109,6 +109,13 @@ static int mxs_flash_ident(struct mtd_info *mtd) return 0; } +static int mxs_flash_ident(struct mtd_info *mtd) +{ + int ret; + ret = mxs_flash_onfi_ident(mtd); + return ret; +} + static int mxs_read_page_ecc(struct mtd_info *mtd, void *buf, unsigned int page) { register struct nand_chip *chip = mtd_to_nand(mtd); From 4368f85359b947da7f151265d8969d6af1235357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Krause?= Date: Sun, 14 Jan 2018 19:26:40 +0100 Subject: [PATCH 58/59] mtd: nand: mxs_nand_spl: add mxs_flash_full_ident MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For now, the existing SPL MXS NAND driver only supports to identify ONFi-compliant NAND chips. In order to allow identifying non-ONFi-compliant chips add `mxs_flash_full_ident()` which uses the `nand_get_flash_type()` functionality from `nand_base.c` to lookup for supported NAND chips in the chip ID list. For compatibility reason the full identification support is only available if the config option `CONFIG_SPL_NAND_IDENT` is enabled. The lookup was tested on a custom i.MX6ULL board with a Toshiba TC58NVG1S3HTAI0 NAND chip. Signed-off-by: Jörg Krause --- drivers/mtd/nand/mxs_nand_spl.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/mtd/nand/mxs_nand_spl.c b/drivers/mtd/nand/mxs_nand_spl.c index adb12c5..2d7bbe8 100644 --- a/drivers/mtd/nand/mxs_nand_spl.c +++ b/drivers/mtd/nand/mxs_nand_spl.c @@ -49,6 +49,28 @@ static void mxs_nand_command(struct mtd_info *mtd, unsigned int command, } } +#if defined (CONFIG_SPL_NAND_IDENT) + +/* Trying to detect the NAND flash using ONFi, JEDEC, and (extended) IDs */ +static int mxs_flash_full_ident(struct mtd_info *mtd) +{ + int nand_maf_id, nand_dev_id; + struct nand_chip *chip = mtd_to_nand(mtd); + struct nand_flash_dev *type; + + type = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL); + + if (IS_ERR(type)) { + chip->select_chip(mtd, -1); + return PTR_ERR(type); + } + + return 0; +} + +#else + +/* Trying to detect the NAND flash using ONFi only */ static int mxs_flash_onfi_ident(struct mtd_info *mtd) { register struct nand_chip *chip = mtd_to_nand(mtd); @@ -109,10 +131,16 @@ static int mxs_flash_onfi_ident(struct mtd_info *mtd) return 0; } +#endif /* CONFIG_SPL_NAND_IDENT */ + static int mxs_flash_ident(struct mtd_info *mtd) { int ret; +#if defined (CONFIG_SPL_NAND_IDENT) + ret = mxs_flash_full_ident(mtd); +#else ret = mxs_flash_onfi_ident(mtd); +#endif return ret; } From b4cb809289235eb39dc2a3e521d8254da0ad752e Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 27 Jun 2018 13:02:36 +0200 Subject: [PATCH 59/59] imx: bx50v3: fix Maintainers This fixes the warnings: WARNING: no status info for 'ge_bx50v3' WARNING: no maintainers for 'ge_bx50v3 Signed-off-by: Stefano Babic --- board/ge/bx50v3/MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/board/ge/bx50v3/MAINTAINERS b/board/ge/bx50v3/MAINTAINERS index 8e60791..a44edd4 100644 --- a/board/ge/bx50v3/MAINTAINERS +++ b/board/ge/bx50v3/MAINTAINERS @@ -3,6 +3,7 @@ M: Martin Donnelly S: Maintained F: board/ge/bx50v3/ F: include/configs/ge_bx50v3.h +F: configs/ge_bx50v3_defconfig F: configs/ge_b450v3_defconfig F: configs/ge_b650v3_defconfig F: configs/ge_b850v3_defconfig