diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2023-05-05 09:13:10 +0200 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2023-05-05 09:13:10 +0200 |
commit | 266f9f2681b1ce7a9e8904dcb3b6f8de3ef59b5d (patch) | |
tree | 38e898f1d3725bd1348b5573ea4fe9dccfb90705 /include | |
parent | 5ecbc52530b00a6e2f39658be54d959c27a4f93d (diff) | |
parent | 2ee8efd6543648c6b8a14d93d52a6038854035c8 (diff) |
Merge tag '08.06.00.007' into toradex_ti-u-boot-2021.01_bringup-ELB-5176
Merge TI U-Boot RC Release 08.06.00.007
Diffstat (limited to 'include')
-rw-r--r-- | include/configs/am62ax_evm.h | 26 | ||||
-rw-r--r-- | include/configs/am62x_evm.h | 119 | ||||
-rw-r--r-- | include/configs/j784s4_evm.h | 8 | ||||
-rw-r--r-- | include/environment/ti/k3_dfu.h | 19 | ||||
-rw-r--r-- | include/linux/mtd/omap_elm.h | 79 | ||||
-rw-r--r-- | include/linux/mtd/spinand.h | 155 | ||||
-rw-r--r-- | include/mtd.h | 1 | ||||
-rw-r--r-- | include/spi-mem.h | 25 |
8 files changed, 329 insertions, 103 deletions
diff --git a/include/configs/am62ax_evm.h b/include/configs/am62ax_evm.h index 6c3a139cae..3685271d7e 100644 --- a/include/configs/am62ax_evm.h +++ b/include/configs/am62ax_evm.h @@ -91,6 +91,28 @@ "${bootdir}/${name_fit}\0" \ "partitions=" PARTS_DEFAULT +#define EXTRA_ENV_AM62A7_BOARD_SETTINGS_OSPI_NAND \ + "nbootpart=ospi.rootfs\0" \ + "nbootvolume=ubi0:rootfs\0" \ + "bootdir=/boot\0" \ + "rd_spec=-\0" \ + "ubi_init=ubi part ${nbootpart}; ubifsmount ${nbootvolume};\0" \ + "args_ospi_nand=setenv bootargs console=${console} " \ + "${optargs} ubi.mtd=${nbootpart} " \ + "root=${nbootvolume} rootfstype=ubifs\0" \ + "init_ospi_nand=run args_all args_ospi_nand ubi_init\0" \ + "get_fdt_ospi_nand=ubifsload ${fdtaddr} ${bootdir}/${fdtfile};\0" \ + "get_overlay_ospi_nand=" \ + "fdt address ${fdtaddr};" \ + "fdt resize 0x100000;" \ + "for overlay in $name_overlays;" \ + "do;" \ + "ubifsload ${dtboaddr} ${bootdir}/${overlay} && " \ + "fdt apply ${dtboaddr};" \ + "done;\0" \ + "get_kern_ospi_nand=ubifsload ${loadaddr} ${bootdir}/${name_kern}\0" \ + "get_fit_ospi_nand=ubifsload ${addr_fit} ${bootdir}/${name_fit}\0" + #if defined(CONFIG_TARGET_AM62A7_A53_EVM) #if defined(DEFAULT_RPROCS) #undef DEFAULT_RPROCS @@ -104,7 +126,8 @@ DFU_ALT_INFO_MMC \ DFU_ALT_INFO_EMMC \ DFU_ALT_INFO_RAM \ - DFU_ALT_INFO_OSPI + DFU_ALT_INFO_OSPI \ + DFU_ALT_INFO_OSPI_NAND /* Incorporate settings into the U-Boot environment */ #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -113,6 +136,7 @@ DEFAULT_MMC_TI_ARGS \ EXTRA_ENV_AM62A7_BOARD_SETTINGS \ EXTRA_ENV_AM62A7_BOARD_SETTINGS_MMC \ + EXTRA_ENV_AM62A7_BOARD_SETTINGS_OSPI_NAND \ EXTRA_ENV_RPROC_SETTINGS \ EXTRA_ENV_DFUARGS diff --git a/include/configs/am62x_evm.h b/include/configs/am62x_evm.h index f66e616693..97bd7c1fd7 100644 --- a/include/configs/am62x_evm.h +++ b/include/configs/am62x_evm.h @@ -13,11 +13,56 @@ #include <config_distro_bootcmd.h> #include <environment/ti/mmc.h> #include <environment/ti/k3_dfu.h> +#include <environment/ti/k3_rproc.h> /* DDR Configuration */ #define CONFIG_SYS_SDRAM_BASE1 0x880000000 #define CONFIG_SYS_BOOTM_LEN SZ_64M +/* NAND support */ + +/* NAND Device Configuration : MT29F8G08ADAFAH4 chip */ +#define CONFIG_SYS_NAND_PAGE_SIZE 4096 +#define CONFIG_SYS_NAND_OOBSIZE 256 +#define CONFIG_SYS_NAND_BLOCK_SIZE SZ_256K +#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ + CONFIG_SYS_NAND_PAGE_SIZE) +#define CONFIG_SYS_NAND_5_ADDR_CYCLE + +/* NAND Driver config */ +#define CONFIG_SPL_NAND_INIT 1 +#define CONFIG_SYS_NAND_ONFI_DETECTION +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW +#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS + +#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ + 10, 11, 12, 13, 14, 15, 16, 17, \ + 18, 19, 20, 21, 22, 23, 24, 25, \ + 26, 27, 28, 29, 30, 31, 32, 33, \ + 34, 35, 36, 37, 38, 39, 40, 41, \ + 42, 43, 44, 45, 46, 47, 48, 49, \ + 50, 51, 52, 53, 54, 55, 56, 57, } +#define CONFIG_SYS_NAND_ECCSIZE 512 +#define CONFIG_SYS_NAND_ECCBYTES 14 + +#ifdef CONFIG_SYS_K3_SPL_ATF +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x200000 /* tispl.bin partition */ +#else +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x600000 /* u-boot.img partition */ +#endif + +#define CONFIG_SYS_NAND_MAX_CHIPS 1 + +#define CONFIG_SYS_MAX_NAND_DEVICE 1 + +#define CONFIG_SYS_NAND_BASE 0x51000000 + +#if defined(CONFIG_ENV_IS_IN_NAND) +#define CONFIG_SYS_ENV_SECT_SIZE CONFIG_SYS_NAND_BLOCK_SIZE +#endif + +/*-- end NAND config --*/ + #ifdef CONFIG_SYS_K3_SPL_ATF #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "tispl.bin" #endif @@ -140,11 +185,70 @@ "run get_fdt_usb;" \ "run run_kern\0" +#ifdef CONFIG_TARGET_AM625_A53_EVM +#define EXTRA_ENV_AM625_BOARD_SETTINGS_MTD \ + "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \ + "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" +#else +#define EXTRA_ENV_AM625_BOARD_SETTINGS_MTD +#endif + +#define EXTRA_ENV_AM625_BOARD_SETTINGS_OSPI_NAND \ + "nbootpart=ospi.rootfs\0" \ + "nbootvolume=ubi0:rootfs\0" \ + "bootdir=/boot\0" \ + "rd_spec=-\0" \ + "ubi_init=ubi part ${nbootpart}; ubifsmount ${nbootvolume};\0" \ + "args_ospi_nand=setenv bootargs console=${console} " \ + "${optargs} ubi.mtd=${nbootpart} " \ + "root=${nbootvolume} rootfstype=ubifs\0" \ + "init_ospi_nand=run args_all args_ospi_nand ubi_init\0" \ + "get_fdt_ospi_nand=ubifsload ${fdtaddr} ${bootdir}/${fdtfile};\0" \ + "get_overlay_ospi_nand=" \ + "fdt address ${fdtaddr};" \ + "fdt resize 0x100000;" \ + "for overlay in $name_overlays;" \ + "do;" \ + "ubifsload ${dtboaddr} ${bootdir}/${overlay} && " \ + "fdt apply ${dtboaddr};" \ + "done;\0" \ + "get_kern_ospi_nand=ubifsload ${loadaddr} ${bootdir}/${name_kern}\0" \ + "get_fit_ospi_nand=ubifsload ${addr_fit} ${bootdir}/${name_fit}\0" + +#define EXTRA_ENV_AM625_BOARD_SETTINGS_NAND \ + "nbootpart=NAND.file-system\0" \ + "nbootvolume=ubi0:rootfs\0" \ + "bootdir=/boot\0" \ + "rd_spec=-\0" \ + "ubi_init=ubi part ${nbootpart}; ubifsmount ${nbootvolume};\0" \ + "args_nand=setenv bootargs console=${console} " \ + "${optargs} ubi.mtd=${nbootpart} " \ + "root=${nbootvolume} rootfstype=ubifs\0" \ + "init_nand=run args_all args_nand ubi_init\0" \ + "get_fdt_nand=ubifsload ${fdtaddr} ${bootdir}/${fdtfile};\0" \ + "get_overlay_nand=" \ + "fdt address ${fdtaddr};" \ + "fdt resize 0x100000;" \ + "for overlay in $name_overlays;" \ + "do;" \ + "ubifsload ${dtboaddr} ${bootdir}/${overlay} && " \ + "fdt apply ${dtboaddr};" \ + "done;\0" \ + "get_kern_nand=ubifsload ${loadaddr} ${bootdir}/${name_kern}\0" \ + "get_fit_nand=ubifsload ${addr_fit} ${bootdir}/${name_fit}\0" + +#if defined(CONFIG_TARGET_AM625_A53_EVM) +#if defined(DEFAULT_RPROCS) +#undef DEFAULT_RPROCS +#endif +#define DEFAULT_RPROCS "" \ + "0 /lib/firmware/am62-mcu-m4f0_0-fw " +#endif #define BOOTENV_DEV_LINUX(devtypeu, devtypel, instance) \ "bootcmd_linux=" \ "if test \"${android_boot}\" -eq 0; then;" \ - "run findfdt; run envboot; run init_${boot};" \ + "run findfdt; run envboot; run init_${boot}; run boot_rprocs;" \ "if test ${boot_fit} -eq 1; then;" \ "run get_fit_${boot}; run get_fit_${boot}; run get_overlaystring; run run_fit;"\ "else;" \ @@ -400,11 +504,17 @@ #endif +#ifdef CONFIG_TARGET_AM625_A53_EVM #define EXTRA_ENV_DFUARGS \ DFU_ALT_INFO_MMC \ DFU_ALT_INFO_EMMC \ DFU_ALT_INFO_RAM \ - DFU_ALT_INFO_OSPI + DFU_ALT_INFO_OSPI \ + DFU_ALT_INFO_OSPI_NAND \ + DFU_ALT_INFO_GPMC_NAND +#else +#define EXTRA_ENV_DFUARGS +#endif /* Incorporate settings into the U-Boot environment */ #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -414,8 +524,11 @@ DEFAULT_MMC_TI_ARGS \ EXTRA_ENV_AM625_BOARD_SETTINGS \ EXTRA_ENV_AM625_BOARD_SETTINGS_MMC \ + EXTRA_ENV_AM625_BOARD_SETTINGS_NAND \ EXTRA_ENV_DFUARGS \ - EXTRA_ENV_AM625_BOARD_SETTING_USBMSC + EXTRA_ENV_AM625_BOARD_SETTING_USBMSC \ + EXTRA_ENV_AM625_BOARD_SETTINGS_OSPI_NAND \ + EXTRA_ENV_RPROC_SETTINGS /* Now for the remaining common defines */ #include <configs/ti_armv7_common.h> diff --git a/include/configs/j784s4_evm.h b/include/configs/j784s4_evm.h index 7502aa72d0..eb609100b0 100644 --- a/include/configs/j784s4_evm.h +++ b/include/configs/j784s4_evm.h @@ -66,8 +66,12 @@ /* U-Boot general configuration */ #define EXTRA_ENV_J784S4_BOARD_SETTINGS \ "default_device_tree=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ - "findfdt=" \ - "setenv name_fdt ${default_device_tree};" \ + "findfdt=" \ + "setenv name_fdt ${default_device_tree};" \ + "if test $board_name = am69-sk; then " \ + "setenv name_fdt k3-am69-sk.dtb; fi;" \ + "if test $board_name = j784s4; then " \ + "setenv name_fdt k3-j784s4-evm.dtb; fi;" \ "setenv fdtfile ${name_fdt}\0" \ "name_kern=Image\0" \ "console=ttyS2,115200n8\0" \ diff --git a/include/environment/ti/k3_dfu.h b/include/environment/ti/k3_dfu.h index 0df8baf3c7..15cd8f2621 100644 --- a/include/environment/ti/k3_dfu.h +++ b/include/environment/ti/k3_dfu.h @@ -60,4 +60,23 @@ "tispl.bin ram 0x80080000 0x200000;" \ "u-boot.img ram 0x81000000 0x400000\0" \ +#define DFU_ALT_INFO_OSPI_NAND \ + "dfu_alt_info_ospi_nand=" \ + "tiboot3.bin raw 0x0 0x080000;" \ + "tispl.bin raw 0x080000 0x200000;" \ + "u-boot.img raw 0x280000 0x400000;" \ + "u-boot-env raw 0x680000 0x040000;" \ + "rootfs raw 0x2000000 0x5fc0000;" \ + "phypattern raw 0x7fc0000 0x40000\0" + +#define DFU_ALT_INFO_GPMC_NAND \ + "dfu_alt_info_gpmc_nand=" \ + "tiboot3.bin raw 0x0 0x00200000;" \ + "tispl.bin raw 0x00200000 0x00200000;" \ + "tiboot3.backup raw 0x00400000 0x00200000;"\ + "u-boot.img raw 0x00600000 0x00400000;" \ + "u-boot-env raw 0x00a00000 0x00040000;" \ + "u-boot-env.backup raw 0x00a40000 0x00040000;" \ + "file-system raw 0x00a80000 0x3f580000\0" \ + #endif /* __TI_DFU_H */ diff --git a/include/linux/mtd/omap_elm.h b/include/linux/mtd/omap_elm.h deleted file mode 100644 index f3db00d55d..0000000000 --- a/include/linux/mtd/omap_elm.h +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com> - * Mansoor Ahamed <mansoor.ahamed@ti.com> - * - * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3 - */ -#ifndef __ASM_ARCH_ELM_H -#define __ASM_ARCH_ELM_H -/* - * ELM Module Registers - */ - -/* ELM registers bit fields */ -#define ELM_SYSCONFIG_SOFTRESET_MASK (0x2) -#define ELM_SYSCONFIG_SOFTRESET (0x2) -#define ELM_SYSSTATUS_RESETDONE_MASK (0x1) -#define ELM_SYSSTATUS_RESETDONE (0x1) -#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK (0x3) -#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK (0x7FF0000) -#define ELM_LOCATION_CONFIG_ECC_SIZE_POS (16) -#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID (0x00010000) -#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK (0x100) -#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK (0x1F) - -#define ELM_MAX_CHANNELS 8 -#define ELM_MAX_ERROR_COUNT 16 - -#ifndef __ASSEMBLY__ - -enum bch_level { - BCH_4_BIT = 0, - BCH_8_BIT, - BCH_16_BIT -}; - - -/* BCH syndrome registers */ -struct syndrome { - u32 syndrome_fragment_x[7]; /* 0x400, 0x404.... 0x418 */ - u8 res1[36]; /* 0x41c */ -}; - -/* BCH error status & location register */ -struct location { - u32 location_status; /* 0x800 */ - u8 res1[124]; /* 0x804 */ - u32 error_location_x[ELM_MAX_ERROR_COUNT]; /* 0x880, 0x980, .. */ - u8 res2[64]; /* 0x8c0 */ -}; - -/* BCH ELM register map - do not try to allocate memmory for this structure. - * We have used plenty of reserved variables to fill the slots in the ELM - * register memory map. - * Directly initialize the struct pointer to ELM base address. - */ -struct elm { - u32 rev; /* 0x000 */ - u8 res1[12]; /* 0x004 */ - u32 sysconfig; /* 0x010 */ - u32 sysstatus; /* 0x014 */ - u32 irqstatus; /* 0x018 */ - u32 irqenable; /* 0x01c */ - u32 location_config; /* 0x020 */ - u8 res2[92]; /* 0x024 */ - u32 page_ctrl; /* 0x080 */ - u8 res3[892]; /* 0x084 */ - struct syndrome syndrome_fragments[ELM_MAX_CHANNELS]; /* 0x400,0x420 */ - u8 res4[512]; /* 0x600 */ - struct location error_location[ELM_MAX_CHANNELS]; /* 0x800,0x900 ... */ -}; - -int elm_check_error(u8 *syndrome, enum bch_level bch_type, u32 *error_count, - u32 *error_locations); -int elm_config(enum bch_level level); -void elm_reset(void); -void elm_init(void); -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_ARCH_ELM_H */ diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 88bacde91e..5c89bd1dcc 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -33,12 +33,25 @@ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_NO_DATA) +#define SPINAND_RESET_OP_OCTAL_DTR \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0xffff, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_ADDR, \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + #define SPINAND_WR_EN_DIS_OP(enable) \ SPI_MEM_OP(SPI_MEM_OP_CMD((enable) ? 0x06 : 0x04, 1), \ SPI_MEM_OP_NO_ADDR, \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_NO_DATA) +#define SPINAND_WR_EN_DIS_OP_OCTAL_DTR(enable) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, (enable) ? 0x0606 : 0x0404, 8, \ + SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_ADDR, \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + #define SPINAND_READID_OP(ndummy, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \ SPI_MEM_OP_NO_ADDR, \ @@ -51,24 +64,48 @@ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_OUT(1, valptr, 1)) +#define SPINAND_SET_FEATURE_OP_OCTAL_DTR(reg, valptr) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0x1f1f, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, reg, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_DATA_OUT(2, valptr, 8, SPI_MEM_OP_DTR)) + #define SPINAND_GET_FEATURE_OP(reg, valptr) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x0f, 1), \ SPI_MEM_OP_ADDR(1, reg, 1), \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_IN(1, valptr, 1)) +#define SPINAND_GET_FEATURE_OP_OCTAL_DTR(reg, valptr) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0x0f0f, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, reg, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_DUMMY(14, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_DATA_IN(2, valptr, 8, SPI_MEM_OP_DTR)) + #define SPINAND_BLK_ERASE_OP(addr) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0xd8, 1), \ SPI_MEM_OP_ADDR(3, addr, 1), \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_NO_DATA) +#define SPINAND_BLK_ERASE_OP_OCTAL_DTR(addr) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0xd8d8, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, addr, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + #define SPINAND_PAGE_READ_OP(addr) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x13, 1), \ SPI_MEM_OP_ADDR(3, addr, 1), \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_NO_DATA) +#define SPINAND_PAGE_READ_OP_OCTAL_DTR(addr) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0x1313, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, addr, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + #define SPINAND_PAGE_READ_FROM_CACHE_OP(fast, addr, ndummy, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \ SPI_MEM_OP_ADDR(2, addr, 1), \ @@ -99,18 +136,37 @@ SPI_MEM_OP_DUMMY(ndummy, 4), \ SPI_MEM_OP_DATA_IN(len, buf, 4)) +#define SPINAND_PAGE_READ_FROM_CACHE_OCTALIO_DTR_OP(addr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0x9d9d, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, addr, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_DUMMY(ndummy, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_DATA_IN(len, buf, 8, SPI_MEM_OP_DTR)) + #define SPINAND_PROG_EXEC_OP(addr) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \ SPI_MEM_OP_ADDR(3, addr, 1), \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_NO_DATA) +#define SPINAND_PROG_EXEC_OP_OCTAL_DTR(addr) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, 0x1010, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, addr, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + #define SPINAND_PROG_LOAD(reset, addr, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0x02 : 0x84, 1), \ SPI_MEM_OP_ADDR(2, addr, 1), \ SPI_MEM_OP_NO_DUMMY, \ SPI_MEM_OP_DATA_OUT(len, buf, 1)) +#define SPINAND_PROG_LOAD_OCTALIO_DTR(reset, addr, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_EXT_CMD(2, reset ? 0x0202 : 0x8484, 8, \ + SPI_MEM_OP_DTR), \ + SPI_MEM_OP_ADDR(2, addr, 8, SPI_MEM_OP_DTR), \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_DATA_OUT(len, buf, 8, SPI_MEM_OP_DTR)) + #define SPINAND_PROG_LOAD_X4(reset, addr, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0x32 : 0x34, 1), \ SPI_MEM_OP_ADDR(2, addr, 1), \ @@ -118,6 +174,18 @@ SPI_MEM_OP_DATA_OUT(len, buf, 4)) /** + * enum spinand_protocol - List of SPI protocols to denote the op protocol and + * SPI NAND flash IO modes. + */ +enum spinand_protocol { + SPINAND_1S, + SPINAND_2S, + SPINAND_4S, + SPINAND_8S, + SPINAND_8D, +}; + +/** * Standard SPI NAND flash commands */ #define SPINAND_CMD_PROG_LOAD_X4 0x32 @@ -177,6 +245,7 @@ struct spinand_id { * that properties of the NAND chip (spinand->base.memorg and * spinand->base.eccreq) have been filled * @init: initialize a SPI NAND device + * @change_protocol: switch the SPI NAND flash to a specific SPI protocol * @cleanup: cleanup a SPI NAND device * * Each SPI NAND manufacturer driver should implement this interface so that @@ -185,6 +254,8 @@ struct spinand_id { struct spinand_manufacturer_ops { int (*detect)(struct spinand_device *spinand); int (*init)(struct spinand_device *spinand); + int (*change_protocol)(struct spinand_device *spinand, + const enum spinand_protocol protocol); void (*cleanup)(struct spinand_device *spinand); }; @@ -229,6 +300,46 @@ struct spinand_op_variants { .nops = sizeof((struct spi_mem_op[]){ __VA_ARGS__ }) / \ sizeof(struct spi_mem_op), \ } +struct spinand_ctrl_ops { + const struct { + struct spi_mem_op reset; + struct spi_mem_op get_feature; + struct spi_mem_op set_feature; + struct spi_mem_op write_enable; + struct spi_mem_op block_erase; + struct spi_mem_op page_read; + struct spi_mem_op program_execute; + } ops; + const enum spinand_protocol protocol; +}; + +#define SPINAND_CTRL_OPS(__protocol, __reset, __get_feature, __set_feature, \ + __write_enable, __block_erase, __page_read, \ + __program_execute) \ + { \ + .ops = { \ + .reset = __reset, \ + .get_feature = __get_feature, \ + .set_feature = __set_feature, \ + .write_enable = __write_enable, \ + .block_erase = __block_erase, \ + .page_read = __page_read, \ + .program_execute = __program_execute, \ + }, \ + .protocol = __protocol, \ + } + +struct spinand_ctrl_ops_variants { + const struct spinand_ctrl_ops *ctrl_ops_list; + unsigned int nvariants; +}; + +#define SPINAND_CTRL_OPS_VARIANTS(name, ...) \ + const struct spinand_ctrl_ops_variants name = { \ + .ctrl_ops_list = (struct spinand_ctrl_ops[]){ __VA_ARGS__ }, \ + .nvariants = sizeof((struct spinand_ctrl_ops[]){ __VA_ARGS__ })/\ + sizeof(struct spinand_ctrl_ops), \ + } /** * spinand_ecc_info - description of the on-die ECC implemented by a SPI NAND @@ -247,6 +358,7 @@ struct spinand_ecc_info { #define SPINAND_HAS_QE_BIT BIT(0) #define SPINAND_HAS_CR_FEAT_BIT BIT(1) +#define SPINAND_HAS_OCTAL_DTR_BIT BIT(2) /** * struct spinand_info - Structure used to describe SPI NAND chips @@ -256,10 +368,10 @@ struct spinand_ecc_info { * @memorg: memory organization * @eccreq: ECC requirements * @eccinfo: on-die ECC info - * @op_variants: operations variants - * @op_variants.read_cache: variants of the read-cache operation - * @op_variants.write_cache: variants of the write-cache operation - * @op_variants.update_cache: variants of the update-cache operation + * @data_ops_variants: operations variants for page read/writes + * @data_ops_variants.read_cache: variants of the read-cache operation + * @data_ops_variants.write_cache: variants of the write-cache operation + * @data_ops_variants.update_cache: variants of the update-cache operation * @select_target: function used to select a target/die. Required only for * multi-die chips * @@ -277,7 +389,9 @@ struct spinand_info { const struct spinand_op_variants *read_cache; const struct spinand_op_variants *write_cache; const struct spinand_op_variants *update_cache; - } op_variants; + } data_ops_variants; + + const struct spinand_ctrl_ops_variants *ctrl_ops_variants; int (*select_target)(struct spinand_device *spinand, unsigned int target); }; @@ -289,6 +403,9 @@ struct spinand_info { .update_cache = __update, \ } +#define SPINAND_INFO_CTRL_OPS_VARIANTS(__ctrl_ops_variants) \ + .ctrl_ops_variants = __ctrl_ops_variants + #define SPINAND_ECCINFO(__ooblayout, __get_status) \ .eccinfo = { \ .ooblayout = __ooblayout, \ @@ -298,14 +415,14 @@ struct spinand_info { #define SPINAND_SELECT_TARGET(__func) \ .select_target = __func, -#define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants, \ - __flags, ...) \ +#define SPINAND_INFO(__model, __id, __memorg, __eccreq, \ + __data_ops_variants, __flags, ...) \ { \ .model = __model, \ .devid = __id, \ .memorg = __memorg, \ .eccreq = __eccreq, \ - .op_variants = __op_variants, \ + .data_ops_variants = __data_ops_variants, \ .flags = __flags, \ __VA_ARGS__ \ } @@ -317,15 +434,19 @@ struct spinand_info { * @lock: lock used to serialize accesses to the NAND * @id: NAND ID as returned by READ_ID * @flags: NAND flags - * @op_templates: various SPI mem op templates - * @op_templates.read_cache: read cache op template - * @op_templates.write_cache: write cache op template - * @op_templates.update_cache: update cache op template + * @data_ops: various SPI mem op templates for reading and writing on pages + * @data_ops.read_cache: read cache op template + * @data_ops.write_cache: write cache op template + * @data_ops.update_cache: update cache op template + * @ctrl_ops: various SPI mem op templates for handling the flash device, i.e. + * non page-read/write ops. * @select_target: select a specific target/die. Usually called before sending * a command addressing a page or an eraseblock embedded in * this die. Only required if your chip exposes several dies * @cur_target: currently selected target/die * @eccinfo: on-die ECC information + * @protocol: SPI IO protocol in operation. Update on successful transition into + * a different SPI IO protocol. * @cfg_cache: config register cache. One entry per die * @databuf: bounce buffer for data * @oobbuf: bounce buffer for OOB data @@ -334,6 +455,8 @@ struct spinand_info { * passed in spi_mem_op be DMA-able, so we can't based the bufs on * the stack * @manufacturer: SPI NAND manufacturer information + * @desc_entry: pointer to device description entry in the manufacturer's + * spinand_info tables * @priv: manufacturer private data */ struct spinand_device { @@ -351,7 +474,9 @@ struct spinand_device { const struct spi_mem_op *read_cache; const struct spi_mem_op *write_cache; const struct spi_mem_op *update_cache; - } op_templates; + } data_ops; + + const struct spinand_ctrl_ops *ctrl_ops; int (*select_target)(struct spinand_device *spinand, unsigned int target); @@ -359,11 +484,14 @@ struct spinand_device { struct spinand_ecc_info eccinfo; + enum spinand_protocol protocol; + u8 *cfg_cache; u8 *databuf; u8 *oobbuf; u8 *scratchbuf; const struct spinand_manufacturer *manufacturer; + const struct spinand_info *desc_entry; void *priv; }; @@ -431,5 +559,6 @@ int spinand_match_and_init(struct spinand_device *dev, int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); int spinand_select_target(struct spinand_device *spinand, unsigned int target); +int spinand_write_enable_op(struct spinand_device *spinand); #endif /* __LINUX_MTD_SPINAND_H */ diff --git a/include/mtd.h b/include/mtd.h index b0f8693386..926ee2075e 100644 --- a/include/mtd.h +++ b/include/mtd.h @@ -9,6 +9,7 @@ #include <linux/mtd/mtd.h> int mtd_probe(struct udevice *dev); +int mtd_remove(struct mtd_info *mtd); int mtd_probe_devices(void); void board_mtdparts_default(const char **mtdids, const char **mtdparts); diff --git a/include/spi-mem.h b/include/spi-mem.h index 1719fe0820..8255c54c6e 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -13,44 +13,59 @@ struct udevice; -#define SPI_MEM_OP_CMD(__opcode, __buswidth) \ +#define SPI_MEM_OP_DTR .dtr = 1 + +#define SPI_MEM_OP_CMD(__opcode, __buswidth, ...) \ { \ .buswidth = __buswidth, \ .opcode = __opcode, \ .nbytes = 1, \ + __VA_ARGS__ \ + } + +#define SPI_MEM_OP_EXT_CMD(__nbytes, __opcode, __buswidth, ...) \ + { \ + .buswidth = __buswidth, \ + .opcode = __opcode, \ + .nbytes = __nbytes, \ + __VA_ARGS__ \ } -#define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth) \ +#define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth, ...) \ { \ .nbytes = __nbytes, \ .val = __val, \ .buswidth = __buswidth, \ + __VA_ARGS__ \ } #define SPI_MEM_OP_NO_ADDR { } -#define SPI_MEM_OP_DUMMY(__nbytes, __buswidth) \ +#define SPI_MEM_OP_DUMMY(__nbytes, __buswidth, ...) \ { \ .nbytes = __nbytes, \ .buswidth = __buswidth, \ + __VA_ARGS__ \ } #define SPI_MEM_OP_NO_DUMMY { } -#define SPI_MEM_OP_DATA_IN(__nbytes, __buf, __buswidth) \ +#define SPI_MEM_OP_DATA_IN(__nbytes, __buf, __buswidth, ...) \ { \ .dir = SPI_MEM_DATA_IN, \ .nbytes = __nbytes, \ .buf.in = __buf, \ .buswidth = __buswidth, \ + __VA_ARGS__ \ } -#define SPI_MEM_OP_DATA_OUT(__nbytes, __buf, __buswidth) \ +#define SPI_MEM_OP_DATA_OUT(__nbytes, __buf, __buswidth, ...) \ { \ .dir = SPI_MEM_DATA_OUT, \ .nbytes = __nbytes, \ .buf.out = __buf, \ .buswidth = __buswidth, \ + __VA_ARGS__ \ } #define SPI_MEM_OP_NO_DATA { } |