diff options
110 files changed, 1480 insertions, 1441 deletions
diff --git a/Documentation/devicetree/bindings/power/restart.rst b/Documentation/devicetree/bindings/power/restart.rst index 42b87f7e9c..9a84c4f224 100644 --- a/Documentation/devicetree/bindings/power/restart.rst +++ b/Documentation/devicetree/bindings/power/restart.rst @@ -7,7 +7,7 @@ Optional properties: - ``restart-priority`` : Overrides the priority set by the driver. Normally, the device with the biggest reach should reset the system. - See :ref:`_system_reset` for more information. + See :ref:`system_reset` for more information. - ``barebox,restart-warm-bootrom`` : Restart will not cause loss to non-volatile registers sampled by the bootrom at startup. This is a necessary precondition diff --git a/Documentation/devicetree/bindings/watchdog/watchdog.rst b/Documentation/devicetree/bindings/watchdog/watchdog.rst index 415a4520f4..753dc7e35f 100644 --- a/Documentation/devicetree/bindings/watchdog/watchdog.rst +++ b/Documentation/devicetree/bindings/watchdog/watchdog.rst @@ -7,4 +7,4 @@ Optional properties: - ``watchdog-priority`` : Overrides the priority set by the driver. Normally, the watchdog device with the biggest reach should reset the system. - See :ref:`_system_reset` for more information. + See :ref:`system_reset` for more information. diff --git a/Documentation/devicetree/index.rst b/Documentation/devicetree/index.rst index d03db3cf82..61ac0433fb 100644 --- a/Documentation/devicetree/index.rst +++ b/Documentation/devicetree/index.rst @@ -114,5 +114,7 @@ Contents: bindings/leds/* bindings/misc/* bindings/mtd/* + bindings/power/* bindings/regulator/* bindings/rtc/* + bindings/watchdog/* @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 2022 -PATCHLEVEL = 11 +PATCHLEVEL = 12 SUBLEVEL = 0 EXTRAVERSION = NAME = None diff --git a/arch/arm/boards/lxa-mc1/board.c b/arch/arm/boards/lxa-mc1/board.c index 9126973dcb..f8a7a6bd1f 100644 --- a/arch/arm/boards/lxa-mc1/board.c +++ b/arch/arm/boards/lxa-mc1/board.c @@ -5,6 +5,7 @@ #include <asm/memory.h> #include <mach/bbu.h> #include <bootsource.h> +#include <deep-probe.h> #include <of.h> static int of_fixup_regulator_supply_disable(struct device_node *root, void *path) @@ -58,6 +59,7 @@ static const struct of_device_id mc1_of_match[] = { { .compatible = "lxa,stm32mp157c-mc1" }, { /* sentinel */ }, }; +BAREBOX_DEEP_PROBE_ENABLE(mc1_of_match); static struct driver_d mc1_board_driver = { .name = "board-lxa-mc1", diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c index d2c73fc7ce..e8577369dc 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c +++ b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c @@ -11,6 +11,8 @@ void ddr_cfg_phy(void) { unsigned int tmp, tmp_t; + ddr_get_firmware(DRAM_TYPE_LPDDR4); + //Init DDRPHY register... reg32_write(0x3c080440,0x2); reg32_write(0x3c080444,0x3); diff --git a/arch/arm/boards/phytec-som-imx8mq/ddrphy_train.c b/arch/arm/boards/phytec-som-imx8mq/ddrphy_train.c index 2c84a0f5fd..2ed6578093 100644 --- a/arch/arm/boards/phytec-som-imx8mq/ddrphy_train.c +++ b/arch/arm/boards/phytec-som-imx8mq/ddrphy_train.c @@ -12,6 +12,8 @@ void ddr_cfg_phy(void) { unsigned int tmp, tmp_t; + ddr_get_firmware(DRAM_TYPE_LPDDR4); + //Init DDRPHY register... reg32_write(0x3c080440,0x2); reg32_write(0x3c080444,0x3); diff --git a/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c b/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c index d2c73fc7ce..e8577369dc 100644 --- a/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c +++ b/arch/arm/boards/zii-imx8mq-dev/ddrphy_train.c @@ -11,6 +11,8 @@ void ddr_cfg_phy(void) { unsigned int tmp, tmp_t; + ddr_get_firmware(DRAM_TYPE_LPDDR4); + //Init DDRPHY register... reg32_write(0x3c080440,0x2); reg32_write(0x3c080444,0x3); diff --git a/arch/arm/cpu/head_64.S b/arch/arm/cpu/head_64.S index f934e96c6e..398c4d3471 100644 --- a/arch/arm/cpu/head_64.S +++ b/arch/arm/cpu/head_64.S @@ -30,4 +30,4 @@ ENTRY(__barebox_arm64_head) .rept 8 .word 0x55555555 .endr -END(__barebox_arm64_head) +ENDPROC(__barebox_arm64_head) diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index dd12f642d9..2dcd415320 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -73,6 +73,13 @@ static inline void arm_fixup_vectors(void) void *barebox_arm_boot_dtb(void); +#define __arm_mem_scratch(endmem) ((endmem) - SZ_32K) + +static inline const void *arm_mem_scratch_get(void) +{ + return (const void *)__arm_mem_scratch(arm_mem_endmem_get()); +} + #define __arm_mem_stack_top(membase, endmem) ((endmem) - SZ_64K) #if defined(CONFIG_BOOTM_OPTEE) || defined(CONFIG_PBL_OPTEE) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index dd9aaf8041..84b763f83f 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -908,6 +908,10 @@ config IMX_IIM_FUSE_BLOW enable it: imx_iim0.permanent_write_enable=1 +config IMX_SAVE_BOOTROM_LOG + bool + default CMD_BOOTROM + config HAB bool diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 390cdaf502..cc834fed7b 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_NAND_IMX) += nand.o lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o obj-y += devices.o imx.o +obj-$(CONFIG_CMD_BOOTROM) += bootrom-cmd.o obj-pbl-y += esdctl.o boot.o obj-$(CONFIG_BAREBOX_UPDATE) += imx-bbu-internal.o obj-$(CONFIG_BAREBOX_UPDATE_IMX_EXTERNAL_NAND) += imx-bbu-external-nand.o diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c index 5301c0fbe8..61b6028166 100644 --- a/arch/arm/mach-imx/atf.c +++ b/arch/arm/mach-imx/atf.c @@ -123,6 +123,7 @@ void imx8mm_load_bl33(void *bl33) __noreturn void imx8mm_load_and_start_image_via_tfa(void) { + imx8mm_save_bootrom_log(); imx8mm_load_bl33((void *)MX8M_ATF_BL33_BASE_ADDR); imx8mm_load_and_start_tfa(imx8mm_bl31_bin); } @@ -159,6 +160,7 @@ void imx8mp_load_bl33(void *bl33) void imx8mp_load_and_start_image_via_tfa(void) { + imx8mp_save_bootrom_log(); imx8mp_load_bl33((void *)MX8M_ATF_BL33_BASE_ADDR); imx8mp_load_and_start_tfa(imx8mp_bl31_bin); } @@ -195,6 +197,7 @@ void imx8mn_load_bl33(void *bl33) void imx8mn_load_and_start_image_via_tfa(void) { + imx8mn_save_bootrom_log(); imx8mn_load_bl33((void *)MX8M_ATF_BL33_BASE_ADDR); imx8mn_load_and_start_tfa(imx8mn_bl31_bin); } diff --git a/arch/arm/mach-imx/bootrom-cmd.c b/arch/arm/mach-imx/bootrom-cmd.c new file mode 100644 index 0000000000..0238d09b16 --- /dev/null +++ b/arch/arm/mach-imx/bootrom-cmd.c @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <command.h> +#include <errno.h> +#include <getopt.h> +#include <printk.h> +#include <linux/bitops.h> +#include <linux/bitfield.h> +#include <mach/imx8m-regs.h> +#include <mach/xload.h> +#include <asm/barebox-arm.h> + +/* i.MX7 and later ID field is swapped compared to i.MX6 */ +#define ROM_EVENT_FORMAT_V0_RES GENMASK(31, 24) +#define ROM_EVENT_FORMAT_V0_ID GENMASK(23, 0) +#define ROM_EVENT_FORMAT_V1_ID GENMASK(31, 24) +#define ROM_EVENT_FORMAT_V1_ID_TYPE GENMASK(31, 28) +#define ROM_EVENT_FORMAT_V1_ID_IDX GENMASK(27, 24) +#define ROM_EVENT_FORMAT_V1_RES GENMASK(23, 0) + +static const char *lookup(const char *table[], size_t table_size, size_t idx) +{ + const char *str = NULL; + + if (idx < table_size) + str = table[idx]; + + return str ?: "unknown"; +} + +#define LOOKUP(table, idx) lookup(table, ARRAY_SIZE(table), idx) + +static const char *boot_mode_0x1y[] = { + "Fuse", "Serial Download", "Internal Download", "Test Mode" +}; + +static const char *secure_config_0x2y[] = { + "FAB", "Field Return", "Open", "Closed" +}; + +static const char *boot_image_0x5y[] = { + "primary", "secondary" +}; + +static const char *boot_device_0x6y[] = { + "RAW NAND", "SD or EMMC", NULL, NULL, "ECSPI NOR", NULL, NULL, "QSPI NOR" +}; + +/* Parse the ROM event ID defintion version 1 log, see AN12853 */ +static int imx8m_bootrom_decode_log(const u32 *rom_log) +{ + int i; + + for (i = 0; i < 128; i++) { + u8 event_id = FIELD_GET(ROM_EVENT_FORMAT_V1_ID, rom_log[i]); + u8 event_id_idx = FIELD_GET(ROM_EVENT_FORMAT_V1_ID_IDX, rom_log[i]); + const char *arg = NULL; + + printf("[%02x] ", event_id); + switch (event_id) { + case 0x0: + printf("End of list\n"); + return 0; + case 0x01: + printf("ROM event version 0x%02x\n", rom_log[i] & 0xFF); + continue; + + case 0x10 ... 0x13: + printf("Boot mode is Boot from %s\n", + LOOKUP(boot_mode_0x1y, event_id_idx)); + continue; + + case 0x20 ... 0x23: + printf("Secure config is %s\n", + LOOKUP(secure_config_0x2y, event_id_idx)); + continue; + + case 0x30 ... 0x31: + case 0xe0: + printf("Internal use\n"); + continue; + + case 0x40 ... 0x41: + printf("FUSE_SEL_VALUE Fuse is %sblown\n", + event_id_idx ? "" : "not "); + continue; + + case 0x50 ... 0x51: + printf("Boot from the %s boot image\n", + LOOKUP(boot_image_0x5y, event_id_idx)); + continue; + + case 0x74: + arg = "SPI NAND"; + fallthrough; + case 0x60 ... 0x67: + printf("Primary boot from %s device\n", + arg ?: LOOKUP(boot_device_0x6y, event_id_idx)); + continue; + + case 0x71: + printf("Recovery boot from ECSPI NOR device\n"); + continue; + case 0x72: + printf("No Recovery boot device\n"); + continue; + case 0x73: + printf("Manufacture boot from SD or EMMC\n"); + continue; + + case 0x80: + printf("Start to perform the device initialization: @%u ticks\n", + rom_log[++i]); + continue; + case 0x81: + printf("The boot device initialization completes: @%u ticks\n", + rom_log[++i]); + continue; + case 0x82: + printf("Start to execute boot device driver pre-config @%u ticks\n", + rom_log[++i]); + continue; + case 0x83: + printf("Boot device driver pre-config completes\n"); + continue; + case 0x8E: + printf("Boot device driver pre-config fails\n"); + continue; + case 0x8f: + printf("boot device initialization fails: @%u ticks\n", + rom_log[++i]); + continue; + + case 0x90: + printf("Start to read data from boot device: @ offset %08x\n", + rom_log[++i]); + continue; + case 0x91: + printf("Reading data from boot device completes: @%u ticks\n", + rom_log[++i]); + continue; + case 0x9f: + printf("Reading data from boot device fails: @%u ticks\n", + rom_log[++i]); + continue; + + case 0xa0: + printf("Image authentication result: %s(0x%08x) @%u ticks\n", + (rom_log[i+1] & 0xFF) == 0xF0 ? "PASS " : "", + rom_log[i+1], rom_log[i+2]); + i += 2; + continue; + case 0xa1: + printf("IVT header is not valid\n"); + continue; + + case 0xc0: + printf("Jump to the boot image soon: @ offset 0x%08x @ %u ticks\n", + rom_log[i+1], rom_log[i+2]); + i += 2; + continue; + + case 0xd0: + printf("Enters serial download processing\n"); + continue; + + case 0xf0: + printf("Enters ROM exception handler\n"); + continue; + default: + printf("Unknown\n"); + continue; + } + } + + return -EILSEQ; +} + +static int do_bootrom(int argc, char *argv[]) +{ + const struct imx_scratch_space *scratch = arm_mem_scratch_get(); + const u32 *rom_log_addr = scratch->bootrom_log; + bool log = false; + int ret, opt; + + while((opt = getopt(argc, argv, "la:")) > 0) { + switch(opt) { + case 'a': + ret = kstrtoul(optarg, 0, (ulong *)&rom_log_addr); + if (ret) + return ret; + rom_log_addr = (const u32 *)rom_log_addr; + case 'l': + log = true; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (log) + return imx8m_bootrom_decode_log(rom_log_addr); + + return COMMAND_ERROR_USAGE; +} + +BAREBOX_CMD_HELP_START(bootrom) +BAREBOX_CMD_HELP_TEXT("List information about the specified files or directories.") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-l", "list event log") +BAREBOX_CMD_HELP_OPT ("-a ADDR", "event log address (default PBL scratch space)") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(bootrom) + .cmd = do_bootrom, + BAREBOX_CMD_DESC("Interact with BootROM on i.MX8M") + BAREBOX_CMD_OPTS("[-la]") + BAREBOX_CMD_HELP(cmd_bootrom_help) + BAREBOX_CMD_GROUP(CMD_GRP_INFO) +BAREBOX_CMD_END diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c index a55ee06b83..8de20ed423 100644 --- a/arch/arm/mach-imx/esdctl.c +++ b/arch/arm/mach-imx/esdctl.c @@ -923,7 +923,7 @@ void __noreturn vf610_barebox_entry(void *boarddata) boarddata); } -static void __noreturn imx8m_barebox_entry(void *boarddata, unsigned buswidth) +resource_size_t imx8m_barebox_earlymem_size(unsigned buswidth) { resource_size_t size; @@ -937,8 +937,13 @@ static void __noreturn imx8m_barebox_entry(void *boarddata, unsigned buswidth) * pool placement. The rest of the system should be able to * detect and utilize full amount of memory. */ - size = min_t(resource_size_t, SZ_4G - MX8M_DDR_CSD1_BASE_ADDR, size); - barebox_arm_entry(MX8M_DDR_CSD1_BASE_ADDR, size, boarddata); + return min_t(resource_size_t, SZ_4G - MX8M_DDR_CSD1_BASE_ADDR, size); +} + +static void __noreturn imx8m_barebox_entry(void *boarddata, unsigned buswidth) +{ + barebox_arm_entry(MX8M_DDR_CSD1_BASE_ADDR, + imx8m_barebox_earlymem_size(buswidth), boarddata); } void __noreturn imx8mm_barebox_entry(void *boarddata) diff --git a/arch/arm/mach-imx/imx50.c b/arch/arm/mach-imx/imx50.c index 20670a7446..e1a743f403 100644 --- a/arch/arm/mach-imx/imx50.c +++ b/arch/arm/mach-imx/imx50.c @@ -21,6 +21,8 @@ static int imx50_silicon_revision(void) u32 rev; u32 mx50_silicon_revision; + OPTIMIZER_HIDE_VAR(rom); + rev = readl(rom + SI_REV); switch (rev) { case 0x10: diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c index 3906a48917..e5da326a7f 100644 --- a/arch/arm/mach-imx/imx53.c +++ b/arch/arm/mach-imx/imx53.c @@ -21,6 +21,8 @@ static int imx53_silicon_revision(void) u32 rev; u32 mx53_silicon_revision; + OPTIMIZER_HIDE_VAR(rom); + rev = readl(rom + SI_REV); switch (rev) { case 0x10: diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h index b0b531aed4..01533478cc 100644 --- a/arch/arm/mach-imx/include/mach/esdctl.h +++ b/arch/arm/mach-imx/include/mach/esdctl.h @@ -131,6 +131,8 @@ #define ESDCFGx_tRC_16 0x0000000f #ifndef __ASSEMBLY__ +#include <linux/types.h> + void __noreturn imx1_barebox_entry(void *boarddata); void __noreturn imx25_barebox_entry(void *boarddata); void __noreturn imx27_barebox_entry(void *boarddata); @@ -148,6 +150,7 @@ void __noreturn imx8mq_barebox_entry(void *boarddata); void __noreturn imx7d_barebox_entry(void *boarddata); #define imx6sx_barebox_entry(boarddata) imx6ul_barebox_entry(boarddata) void imx_esdctl_disable(void); +resource_size_t imx8m_barebox_earlymem_size(unsigned buswidth); #endif #endif /* __MACH_ESDCTL_V2_H */ diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h index 35f03036cb..39e2751533 100644 --- a/arch/arm/mach-imx/include/mach/imx6-regs.h +++ b/arch/arm/mach-imx/include/mach/imx6-regs.h @@ -3,7 +3,9 @@ #ifndef __MACH_IMX6_REGS_H #define __MACH_IMX6_REGS_H +#define MX6_APBH_BASE_ADDR 0x00110000 #define MX6_GPMI_BASE_ADDR 0x00112000 +#define MX6_BCH_BASE_ADDR 0x00114000 #define MX6_FAST1_BASE_ADDR 0x00c00000 #define MX6_FAST2_BASE_ADDR 0x00b00000 diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h index 1ee7d86e0e..379be9e062 100644 --- a/arch/arm/mach-imx/include/mach/imx7-regs.h +++ b/arch/arm/mach-imx/include/mach/imx7-regs.h @@ -118,6 +118,7 @@ #define MX7_ENET1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3E0000) #define MX7_ENET2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3F0000) +#define MX7_APBH_BASE 0x33000000 #define MX7_GPMI_BASE 0x33002000 #define MX7_BCH_BASE 0x33004000 diff --git a/arch/arm/mach-imx/include/mach/imx8m-regs.h b/arch/arm/mach-imx/include/mach/imx8m-regs.h index a5017faf83..794e1bdd88 100644 --- a/arch/arm/mach-imx/include/mach/imx8m-regs.h +++ b/arch/arm/mach-imx/include/mach/imx8m-regs.h @@ -3,6 +3,14 @@ #ifndef __MACH_IMX8M_REGS_H #define __MACH_IMX8M_REGS_H +/* + * Actual addressable OCRAM size may differ from SoC to SoC, but all of + * i.MX8MQ/M/N/P have this region of MMIO address space set aside for + * OCRAM only. + */ +#define MX8M_OCRAM_BASE_ADDR 0x00900000 +#define MX8M_OCRAM_MAX_SIZE 0x00200000 + #define MX8M_GPIO1_BASE_ADDR 0X30200000 #define MX8M_GPIO2_BASE_ADDR 0x30210000 #define MX8M_GPIO3_BASE_ADDR 0x30220000 diff --git a/arch/arm/mach-imx/include/mach/romapi.h b/arch/arm/mach-imx/include/mach/romapi.h index 8022fc411e..d22ba7259d 100644 --- a/arch/arm/mach-imx/include/mach/romapi.h +++ b/arch/arm/mach-imx/include/mach/romapi.h @@ -1,6 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef __MACH_IMX_ROMAPI_H #define __MACH_IMX_ROMAPI_H +#include <mach/xload.h> + struct rom_api { u16 ver; u16 tag; @@ -34,4 +37,12 @@ enum boot_dev_type_e { int imx8mp_bootrom_load_image(void); int imx8mn_bootrom_load_image(void); +/* only call after DRAM has been configured */ +void imx8m_save_bootrom_log(void *dst); + +#define imx8mq_save_bootrom_log() imx8m_save_bootrom_log(imx8mq_scratch_space()) +#define imx8mm_save_bootrom_log() imx8m_save_bootrom_log(imx8mm_scratch_space()) +#define imx8mn_save_bootrom_log() imx8m_save_bootrom_log(imx8mn_scratch_space()) +#define imx8mp_save_bootrom_log() imx8m_save_bootrom_log(imx8mp_scratch_space()) + #endif /* __MACH_IMX_ROMAPI_H */ diff --git a/arch/arm/mach-imx/include/mach/vf610.h b/arch/arm/mach-imx/include/mach/vf610.h index 6de300a2a0..505aab0211 100644 --- a/arch/arm/mach-imx/include/mach/vf610.h +++ b/arch/arm/mach-imx/include/mach/vf610.h @@ -15,6 +15,7 @@ #define VF610_CPUTYPE_VF510 0x510 #define VF610_CPUTYPE_VF500 0x500 +#define VF610_ROM_BASE_ADDR 0x0 #define VF610_ROM_VERSION_OFFSET 0x80 static inline int __vf610_cpu_type(void) @@ -39,6 +40,10 @@ static inline int vf610_cpu_type(void) static inline int vf610_cpu_revision(void) { + void __iomem *rom = IOMEM(VF610_ROM_BASE_ADDR); + + OPTIMIZER_HIDE_VAR(rom); + if (!cpu_is_vf610()) return IMX_CHIP_REV_UNKNOWN; @@ -47,7 +52,7 @@ static inline int vf610_cpu_revision(void) * silicon revision on VFxxx cpus, so we just report Mask ROM * version instead */ - return readl(VF610_ROM_VERSION_OFFSET) & 0xff; + return readl(rom + VF610_ROM_VERSION_OFFSET) & 0xff; } u64 vf610_uid(void); diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h index 82bf663c42..aa2fa5129a 100644 --- a/arch/arm/mach-imx/include/mach/xload.h +++ b/arch/arm/mach-imx/include/mach/xload.h @@ -12,6 +12,7 @@ int imx6_spi_start_image(int instance); int imx6_esdhc_start_image(int instance); int imx6_nand_start_image(void); int imx7_esdhc_start_image(int instance); +int imx7_nand_start_image(void); int imx8m_esdhc_load_image(int instance, bool start); int imx8mn_esdhc_load_image(int instance, bool start); int imx8mp_esdhc_load_image(int instance, bool start); @@ -30,4 +31,15 @@ int piggydata_size(void); extern unsigned char input_data[]; extern unsigned char input_data_end[]; +struct imx_scratch_space { + u32 bootrom_log[128]; +}; + +struct imx_scratch_space *__imx8m_scratch_space(int ddr_buswidth); + +#define imx8mq_scratch_space() __imx8m_scratch_space(32) +#define imx8mm_scratch_space() __imx8m_scratch_space(32) +#define imx8mn_scratch_space() __imx8m_scratch_space(16) +#define imx8mp_scratch_space() __imx8m_scratch_space(32) + #endif /* __MACH_XLOAD_H */ diff --git a/arch/arm/mach-imx/romapi.c b/arch/arm/mach-imx/romapi.c index 56bf7e135f..5885fb698e 100644 --- a/arch/arm/mach-imx/romapi.c +++ b/arch/arm/mach-imx/romapi.c @@ -1,7 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define pr_fmt(fmt) "romapi: " fmt + #include <common.h> #include <asm/sections.h> #include <mach/romapi.h> #include <mach/atf.h> +#include <mach/imx8m-regs.h> static int imx8m_bootrom_load(struct rom_api *rom_api, void *adr, size_t size) { @@ -44,3 +49,24 @@ int imx8mn_bootrom_load_image(void) { return imx8mp_bootrom_load_image(); } + +void imx8m_save_bootrom_log(void *dest) +{ + ulong rom_log_addr; + + if (!IS_ENABLED(CONFIG_IMX_SAVE_BOOTROM_LOG)) { + pr_debug("skipping bootrom log saving\n"); + return; + } + + rom_log_addr = *(u32 *)0x9e0; + + if (rom_log_addr < MX8M_OCRAM_BASE_ADDR || + rom_log_addr >= MX8M_OCRAM_BASE_ADDR + MX8M_OCRAM_MAX_SIZE || + rom_log_addr & 0x3) { + pr_warn("No BootROM log found at address 0x%08lx\n", rom_log_addr); + return; + } + + memcpy(dest, (u32 *)rom_log_addr, 128 * sizeof(u32)); +} diff --git a/arch/arm/mach-imx/xload-common.c b/arch/arm/mach-imx/xload-common.c index f4bcca1d14..710dcc1ed9 100644 --- a/arch/arm/mach-imx/xload-common.c +++ b/arch/arm/mach-imx/xload-common.c @@ -4,6 +4,9 @@ #include <asm/sections.h> #include <linux/sizes.h> #include <mach/xload.h> +#include <mach/esdctl.h> +#include <mach/imx8m-regs.h> +#include <asm/barebox-arm.h> int imx_image_size(void) { @@ -16,3 +19,10 @@ int piggydata_size(void) return input_data_end - input_data; } +struct imx_scratch_space *__imx8m_scratch_space(int ddr_buswidth) +{ + ulong endmem = MX8M_DDR_CSD1_BASE_ADDR + + imx8m_barebox_earlymem_size(ddr_buswidth); + + return (void *)__arm_mem_scratch(endmem); +} diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c index 3a4f331ce6..dcef8cda48 100644 --- a/arch/arm/mach-imx/xload-gpmi-nand.c +++ b/arch/arm/mach-imx/xload-gpmi-nand.c @@ -7,47 +7,16 @@ #include <asm-generic/io.h> #include <linux/sizes.h> #include <linux/mtd/nand.h> +#include <linux/bitfield.h> #include <asm/cache.h> #include <mach/xload.h> #include <soc/imx/imx-nand-bcb.h> #include <linux/mtd/rawnand.h> +#include <soc/imx/gpmi-nand.h> #include <mach/imx6-regs.h> +#include <mach/imx7-regs.h> #include <mach/clock-imx6.h> - -/* - * MXS DMA hardware command. - * - * This structure describes the in-memory layout of an entire DMA command, - * including space for the maximum number of PIO accesses. See the appropriate - * reference manual for a detailed description of what these fields mean to the - * DMA hardware. - */ -#define DMACMD_COMMAND_DMA_WRITE 0x1 -#define DMACMD_COMMAND_DMA_READ 0x2 -#define DMACMD_COMMAND_DMA_SENSE 0x3 -#define DMACMD_CHAIN (1 << 2) -#define DMACMD_IRQ (1 << 3) -#define DMACMD_NAND_LOCK (1 << 4) -#define DMACMD_NAND_WAIT_4_READY (1 << 5) -#define DMACMD_DEC_SEM (1 << 6) -#define DMACMD_WAIT4END (1 << 7) -#define DMACMD_HALT_ON_TERMINATE (1 << 8) -#define DMACMD_TERMINATE_FLUSH (1 << 9) -#define DMACMD_PIO_WORDS(words) ((words) << 12) -#define DMACMD_XFER_COUNT(x) ((x) << 16) - -struct mxs_dma_cmd { - unsigned long next; - unsigned long data; - unsigned long address; -#define APBH_DMA_PIO_WORDS 6 - unsigned long pio_words[APBH_DMA_PIO_WORDS]; -}; - -enum mxs_dma_id { - IMX23_DMA, - IMX28_DMA, -}; +#include <dma/apbh-dma.h> struct apbh_dma { void __iomem *regs; @@ -60,25 +29,6 @@ struct mxs_dma_chan { struct apbh_dma *apbh; }; -#define HW_APBHX_CTRL0 0x000 -#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29) -#define BM_APBH_CTRL0_APB_BURST_EN (1 << 28) -#define BP_APBH_CTRL0_CLKGATE_CHANNEL 8 -#define BP_APBH_CTRL0_RESET_CHANNEL 16 -#define HW_APBHX_CTRL1 0x010 -#define BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN 16 -#define HW_APBHX_CTRL2 0x020 -#define HW_APBHX_CHANNEL_CTRL 0x030 -#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16 -#define BP_APBHX_VERSION_MAJOR 24 -#define HW_APBHX_CHn_NXTCMDAR_MX23(n) (0x050 + (n) * 0x70) -#define HW_APBHX_CHn_NXTCMDAR_MX28(n) (0x110 + (n) * 0x70) -#define HW_APBHX_CHn_SEMA_MX23(n) (0x080 + (n) * 0x70) -#define HW_APBHX_CHn_SEMA_MX28(n) (0x140 + (n) * 0x70) -#define NAND_ONFI_CRC_BASE 0x4f4e - -#define apbh_dma_is_imx23(aphb) ((apbh)->id == IMX23_DMA) - /* udelay() is not available in PBL, need to improvise */ static void __udelay(int us) { @@ -167,7 +117,7 @@ static int mxs_dma_run(struct mxs_dma_chan *pchan, struct mxs_dma_cmd *pdesc, /* chain descriptors */ for (i = 0; i < num - 1; i++) { pdesc[i].next = (unsigned long)(&pdesc[i + 1]); - pdesc[i].data |= DMACMD_CHAIN; + pdesc[i].data |= MXS_DMA_DESC_CHAIN; } writel(1 << (pchan->channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN), @@ -203,39 +153,6 @@ static int mxs_dma_run(struct mxs_dma_chan *pchan, struct mxs_dma_cmd *pdesc, /* ----------------------------- NAND driver part -------------------------- */ -#define GPMI_CTRL0 0x00000000 -#define GPMI_CTRL0_RUN (1 << 29) -#define GPMI_CTRL0_DEV_IRQ_EN (1 << 28) -#define GPMI_CTRL0_UDMA (1 << 26) -#define GPMI_CTRL0_COMMAND_MODE_MASK (0x3 << 24) -#define GPMI_CTRL0_COMMAND_MODE_OFFSET 24 -#define GPMI_CTRL0_COMMAND_MODE_WRITE (0x0 << 24) -#define GPMI_CTRL0_COMMAND_MODE_READ (0x1 << 24) -#define GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE (0x2 << 24) -#define GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY (0x3 << 24) -#define GPMI_CTRL0_WORD_LENGTH (1 << 23) -#define GPMI_CTRL0_CS(cs) ((cs) << 20) -#define GPMI_CTRL0_ADDRESS_MASK (0x7 << 17) -#define GPMI_CTRL0_ADDRESS_OFFSET 17 -#define GPMI_CTRL0_ADDRESS_NAND_DATA (0x0 << 17) -#define GPMI_CTRL0_ADDRESS_NAND_CLE (0x1 << 17) -#define GPMI_CTRL0_ADDRESS_NAND_ALE (0x2 << 17) -#define GPMI_CTRL0_ADDRESS_INCREMENT (1 << 16) -#define GPMI_CTRL0_XFER_COUNT_MASK 0xffff -#define GPMI_CTRL0_XFER_COUNT_OFFSET 0 - -#define GPMI_ECCCTRL_ECC_CMD_DECODE (0x0 << 13) -#define GPMI_ECCCTRL_ENABLE_ECC (1 << 12) -#define GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE 0x1ff - -#define BCH_CTRL 0x00000000 -#define BCH_CTRL_COMPLETE_IRQ (1 << 0) - -#define MXS_NAND_DMA_DESCRIPTOR_COUNT 6 -#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512 -#define MXS_NAND_METADATA_SIZE 10 -#define MXS_NAND_COMMAND_BUFFER_SIZE 128 - struct mxs_nand_info { void __iomem *io_base; void __iomem *bch_base; @@ -313,7 +230,7 @@ static uint32_t mxs_nand_aux_status_offset(void) } static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize, - int oobsize, int pagenum, void *databuf, int raw) + int oobsize, int pagenum, void *databuf, int raw, bool randomizer) { void __iomem *bch_regs = info->bch_base; unsigned column = 0; @@ -321,8 +238,6 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize, int cmd_queue_len; u8 *cmd_buf; int ret; - uint8_t *status; - int i; int timeout; int descnum = 0; int max_pagenum = info->nand_size / @@ -345,14 +260,14 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize, if ((max_pagenum - 1) >= SZ_64K) cmd_buf[cmd_queue_len++] = pagenum >> 16; - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(cmd_queue_len); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | cmd_queue_len; @@ -365,50 +280,50 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize, cmd_buf[cmd_queue_len++] = NAND_CMD_READSTART; - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(cmd_queue_len); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | cmd_queue_len; /* Compile DMA descriptor - wait for ready. */ d = &info->desc[descnum++]; - d->data = DMACMD_CHAIN | - DMACMD_NAND_WAIT_4_READY | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(2); + d->data = MXS_DMA_DESC_CHAIN | + MXS_DMA_DESC_NAND_WAIT_4_READY | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(2); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA; if (raw) { /* Compile DMA descriptor - read. */ d = &info->desc[descnum++]; - d->data = DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(writesize + oobsize) | - DMACMD_COMMAND_DMA_WRITE; + d->data = MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(writesize + oobsize) | + MXS_DMA_DESC_COMMAND_DMA_WRITE; d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA | (writesize + oobsize); d->address = (dma_addr_t)databuf; } else { /* Compile DMA descriptor - enable the BCH block and read. */ d = &info->desc[descnum++]; - d->data = DMACMD_WAIT4END | DMACMD_PIO_WORDS(6); + d->data = MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(6); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA | (writesize + oobsize); d->pio_words[1] = 0; @@ -419,21 +334,27 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize, d->pio_words[4] = (dma_addr_t)databuf; d->pio_words[5] = (dma_addr_t)(databuf + writesize); + if (randomizer) { + d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | + GPMI_ECCCTRL_RANDOMIZER_TYPE2; + d->pio_words[3] |= (pagenum % 256) << 16; + } + /* Compile DMA descriptor - disable the BCH block. */ d = &info->desc[descnum++]; - d->data = DMACMD_NAND_WAIT_4_READY | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(3); + d->data = MXS_DMA_DESC_NAND_WAIT_4_READY | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(3); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA | (writesize + oobsize); } /* Compile DMA descriptor - de-assert the NAND lock and interrupt. */ d = &info->desc[descnum++]; - d->data = DMACMD_IRQ | DMACMD_DEC_SEM; + d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; /* Execute the DMA chain. */ ret = mxs_dma_run(info->dma_channel, info->desc, descnum); @@ -460,20 +381,26 @@ static int mxs_nand_read_page(struct mxs_nand_info *info, int writesize, writel(BCH_CTRL_COMPLETE_IRQ, bch_regs + BCH_CTRL + STMP_OFFSET_REG_CLR); - /* Loop over status bytes, accumulating ECC status. */ - status = databuf + writesize + mxs_nand_aux_status_offset(); - for (i = 0; i < writesize / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; i++) { - if (status[i] == 0xfe) { - ret = -EBADMSG; - goto err; - } - } - ret = 0; err: return ret; } +static int mxs_nand_get_ecc_status(struct mxs_nand_info *info, void *databuf) +{ + uint8_t *status; + int i; + + /* Loop over status bytes, accumulating ECC status. */ + status = databuf + info->organization.pagesize + mxs_nand_aux_status_offset(); + for (i = 0; i < info->organization.pagesize / MXS_NAND_CHUNK_DATA_CHUNK_SIZE; i++) { + if (status[i] == 0xfe) + return -EBADMSG; + } + + return 0; +} + static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf) { int ret; @@ -492,34 +419,34 @@ static int mxs_nand_get_read_status(struct mxs_nand_info *info, void *databuf) d->address = (dma_addr_t)(cmd_buf); cmd_buf[cmd_queue_len++] = NAND_CMD_STATUS; - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(cmd_queue_len); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | cmd_queue_len; /* Compile DMA descriptor - read. */ d = &info->desc[descnum++]; - d->data = DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(1) | - DMACMD_COMMAND_DMA_WRITE; + d->data = MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(1) | + MXS_DMA_DESC_COMMAND_DMA_WRITE; d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA | (1); d->address = (dma_addr_t)databuf; /* Compile DMA descriptor - de-assert the NAND lock and interrupt. */ d = &info->desc[descnum++]; - d->data = DMACMD_IRQ | DMACMD_DEC_SEM; + d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; /* Execute the DMA chain. */ ret = mxs_dma_run(info->dma_channel, info->desc, descnum); @@ -550,21 +477,21 @@ static int mxs_nand_reset(struct mxs_nand_info *info, void *databuf) d->address = (dma_addr_t)(cmd_buf); cmd_buf[cmd_queue_len++] = NAND_CMD_RESET; - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(cmd_queue_len); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | cmd_queue_len; /* Compile DMA descriptor - de-assert the NAND lock and interrupt. */ d = &info->desc[descnum++]; - d->data = DMACMD_IRQ | DMACMD_DEC_SEM; + d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; /* Execute the DMA chain. */ ret = mxs_dma_run(info->dma_channel, info->desc, descnum); @@ -622,46 +549,46 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf) cmd_buf[cmd_queue_len++] = NAND_CMD_PARAM; cmd_buf[cmd_queue_len++] = 0x00; - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(cmd_queue_len); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | cmd_queue_len; /* Compile DMA descriptor - wait for ready. */ d = &info->desc[descnum++]; - d->data = DMACMD_CHAIN | - DMACMD_NAND_WAIT_4_READY | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(2); + d->data = MXS_DMA_DESC_CHAIN | + MXS_DMA_DESC_NAND_WAIT_4_READY | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(2); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA; /* Compile DMA descriptor - read. */ d = &info->desc[descnum++]; - d->data = DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(sizeof(struct nand_onfi_params)) | - DMACMD_COMMAND_DMA_WRITE; + d->data = MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(sizeof(struct nand_onfi_params)) | + MXS_DMA_DESC_COMMAND_DMA_WRITE; d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA | (sizeof(struct nand_onfi_params)); d->address = (dma_addr_t)databuf; /* Compile DMA descriptor - de-assert the NAND lock and interrupt. */ d = &info->desc[descnum++]; - d->data = DMACMD_IRQ | DMACMD_DEC_SEM; + d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; /* Execute the DMA chain. */ ret = mxs_dma_run(info->dma_channel, info->desc, descnum); @@ -700,7 +627,7 @@ static int mxs_nand_get_onfi(struct mxs_nand_info *info, void *databuf) return ret; } -static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf) +static int mxs_nand_read_id(struct mxs_nand_info *info, u8 adr, void *databuf, size_t len) { int ret; u8 *cmd_buf; @@ -708,13 +635,6 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf) int descnum = 0; int cmd_queue_len; - struct onfi_header { - u8 byte0; - u8 byte1; - u8 byte2; - u8 byte3; - } onfi_head; - memset(info->desc, 0, sizeof(*info->desc) * MXS_NAND_DMA_DESCRIPTOR_COUNT); @@ -724,152 +644,118 @@ static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf) d = &info->desc[descnum++]; d->address = (dma_addr_t)(cmd_buf); cmd_buf[cmd_queue_len++] = NAND_CMD_READID; - cmd_buf[cmd_queue_len++] = 0x20; + cmd_buf[cmd_queue_len++] = adr; - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | + MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(cmd_queue_len); d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | cmd_queue_len; /* Compile DMA descriptor - read. */ d = &info->desc[descnum++]; - d->data = DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(sizeof(struct onfi_header)) | - DMACMD_COMMAND_DMA_WRITE; + d->data = MXS_DMA_DESC_WAIT4END | + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(len) | + MXS_DMA_DESC_COMMAND_DMA_WRITE; d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | + FIELD_PREP(GPMI_CTRL0_CS, info->cs) | GPMI_CTRL0_ADDRESS_NAND_DATA | - (sizeof(struct onfi_header)); + len; d->address = (dma_addr_t)databuf; /* Compile DMA descriptor - de-assert the NAND lock and interrupt. */ d = &info->desc[descnum++]; - d->data = DMACMD_IRQ | DMACMD_DEC_SEM; + d->data = MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; /* Execute the DMA chain. */ ret = mxs_dma_run(info->dma_channel, info->desc, descnum); - if (ret) { + if (ret) pr_err("DMA read error\n"); - return ret; - } - - memcpy(&onfi_head, databuf, sizeof(struct onfi_header)); - - pr_debug("ONFI Byte0: 0x%x\n", onfi_head.byte0); - pr_debug("ONFI Byte1: 0x%x\n", onfi_head.byte1); - pr_debug("ONFI Byte2: 0x%x\n", onfi_head.byte2); - pr_debug("ONFI Byte3: 0x%x\n", onfi_head.byte3); - - /* check if returned values correspond to ascii characters "ONFI" */ - if (onfi_head.byte0 != 0x4f || onfi_head.byte1 != 0x4e || - onfi_head.byte2 != 0x46 || onfi_head.byte3 != 0x49) - return 1; - return 0; + return ret; } -static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf) +struct onfi_header { + u8 byte0; + u8 byte1; + u8 byte2; + u8 byte3; +}; + +static int mxs_nand_check_onfi(struct mxs_nand_info *info, void *databuf) { int ret; - u8 *cmd_buf; - struct mxs_dma_cmd *d; - int descnum = 0; - int cmd_queue_len; + struct onfi_header *onfi_head = databuf; - struct readid_data { - u8 byte0; - u8 byte1; - u8 byte2; - u8 byte3; - u8 byte4; - } id_data; + ret = mxs_nand_read_id(info, 0x20, databuf, sizeof(struct onfi_header)); + if (ret) + return ret; - memset(info->desc, 0, - sizeof(*info->desc) * MXS_NAND_DMA_DESCRIPTOR_COUNT); + pr_debug("ONFI Byte0: 0x%x\n", onfi_head->byte0); + pr_debug("ONFI Byte1: 0x%x\n", onfi_head->byte1); + pr_debug("ONFI Byte2: 0x%x\n", onfi_head->byte2); + pr_debug("ONFI Byte3: 0x%x\n", onfi_head->byte3); - /* Compile DMA descriptor - READID */ - cmd_buf = info->cmd_buf; - cmd_queue_len = 0; - d = &info->desc[descnum++]; - d->address = (dma_addr_t)(cmd_buf); - cmd_buf[cmd_queue_len++] = NAND_CMD_READID; - cmd_buf[cmd_queue_len++] = 0x00; - - d->data = DMACMD_COMMAND_DMA_READ | - DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(cmd_queue_len); + if (onfi_head->byte0 != 'O' || onfi_head->byte1 != 'N' || + onfi_head->byte2 != 'F' || onfi_head->byte3 != 'I') + return 1; - d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | - GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | - GPMI_CTRL0_ADDRESS_NAND_CLE | - GPMI_CTRL0_ADDRESS_INCREMENT | - cmd_queue_len; + return 0; +} - /* Compile DMA descriptor - read. */ - d = &info->desc[descnum++]; - d->data = DMACMD_WAIT4END | - DMACMD_PIO_WORDS(1) | - DMACMD_XFER_COUNT(sizeof(struct readid_data)) | - DMACMD_COMMAND_DMA_WRITE; - d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | - GPMI_CTRL0_WORD_LENGTH | - GPMI_CTRL0_CS(info->cs) | - GPMI_CTRL0_ADDRESS_NAND_DATA | - (sizeof(struct readid_data)); - d->address = (dma_addr_t)databuf; +struct readid_data { + u8 byte0; + u8 byte1; + u8 byte2; + u8 byte3; + u8 byte4; +}; - /* Compile DMA descriptor - de-assert the NAND lock and interrupt. */ - d = &info->desc[descnum++]; - d->data = DMACMD_IRQ | DMACMD_DEC_SEM; +static int mxs_nand_get_readid(struct mxs_nand_info *info, void *databuf) +{ + int ret; + struct readid_data *id_data = databuf; - /* Execute the DMA chain. */ - ret = mxs_dma_run(info->dma_channel, info->desc, descnum); - if (ret) { - pr_err("DMA read error\n"); + ret = mxs_nand_read_id(info, 0x0, databuf, sizeof(struct readid_data)); + if (ret) return ret; - } - - memcpy(&id_data, databuf, sizeof(struct readid_data)); - pr_debug("NAND Byte0: 0x%x\n", id_data.byte0); - pr_debug("NAND Byte1: 0x%x\n", id_data.byte1); - pr_debug("NAND Byte2: 0x%x\n", id_data.byte2); - pr_debug("NAND Byte3: 0x%x\n", id_data.byte3); - pr_debug("NAND Byte4: 0x%x\n", id_data.byte4); + pr_debug("NAND Byte0: 0x%x\n", id_data->byte0); + pr_debug("NAND Byte1: 0x%x\n", id_data->byte1); + pr_debug("NAND Byte2: 0x%x\n", id_data->byte2); + pr_debug("NAND Byte3: 0x%x\n", id_data->byte3); + pr_debug("NAND Byte4: 0x%x\n", id_data->byte4); - if (id_data.byte0 == 0xff || id_data.byte1 == 0xff || - id_data.byte2 == 0xff || id_data.byte3 == 0xff || - id_data.byte4 == 0xff) { + if (id_data->byte0 == 0xff || id_data->byte1 == 0xff || + id_data->byte2 == 0xff || id_data->byte3 == 0xff || + id_data->byte4 == 0xff) { pr_err("\"READ ID\" returned 0xff, possible error!\n"); return -EOVERFLOW; } /* Fill the NAND organization struct with data */ info->organization.bits_per_cell = - (1 << ((id_data.byte2 >> 2) & 0x3)) * 2; + (1 << ((id_data->byte2 >> 2) & 0x3)) * 2; info->organization.pagesize = - (1 << (id_data.byte3 & 0x3)) * SZ_1K; - info->organization.oobsize = id_data.byte3 & 0x4 ? + (1 << (id_data->byte3 & 0x3)) * SZ_1K; + info->organization.oobsize = id_data->byte3 & 0x4 ? info->organization.pagesize / 512 * 16 : info->organization.pagesize / 512 * 8; info->organization.pages_per_eraseblock = - (1 << ((id_data.byte3 >> 4) & 0x3)) * SZ_64K / + (1 << ((id_data->byte3 >> 4) & 0x3)) * SZ_64K / info->organization.pagesize; info->organization.planes_per_lun = - 1 << ((id_data.byte4 >> 2) & 0x3); + 1 << ((id_data->byte4 >> 2) & 0x3); info->nand_size = info->organization.planes_per_lun * - (1 << ((id_data.byte4 >> 4) & 0x7)) * SZ_8M; + (1 << ((id_data->byte4 >> 4) & 0x7)) * SZ_8M; info->organization.eraseblocks_per_lun = info->nand_size / (info->organization.pages_per_eraseblock * info->organization.pagesize); @@ -881,6 +767,10 @@ static int mxs_nand_get_info(struct mxs_nand_info *info, void *databuf) { int ret, i; + ret = mxs_nand_reset(info, databuf); + if (ret) + return ret; + ret = mxs_nand_check_onfi(info, databuf); if (ret) { if (ret != 1) @@ -958,7 +848,7 @@ static uint32_t calc_chksum(void *buf, size_t size) return ~chksum; } -static int get_fcb(struct mxs_nand_info *info, void *databuf) +static int imx6_get_fcb(struct mxs_nand_info *info, void *databuf) { int i, pagenum, ret; uint32_t checksum; @@ -966,13 +856,17 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf) /* First page read fails, this shouldn't be necessary */ mxs_nand_read_page(info, info->organization.pagesize, - info->organization.oobsize, 0, databuf, 1); + info->organization.oobsize, 0, databuf, 1, false); for (i = 0; i < 4; i++) { pagenum = info->organization.pages_per_eraseblock * i; ret = mxs_nand_read_page(info, info->organization.pagesize, - info->organization.oobsize, pagenum, databuf, 1); + info->organization.oobsize, pagenum, databuf, 1, false); + if (ret) + continue; + + ret = mxs_nand_get_ecc_status(info, databuf); if (ret) continue; @@ -994,23 +888,72 @@ static int get_fcb(struct mxs_nand_info *info, void *databuf) continue; } - pr_debug("Found FCB:\n"); - pr_debug("PageDataSize: 0x%08x\n", fcb->PageDataSize); - pr_debug("TotalPageSize: 0x%08x\n", fcb->TotalPageSize); - pr_debug("SectorsPerBlock: 0x%08x\n", fcb->SectorsPerBlock); - pr_debug("FW1_startingPage: 0x%08x\n", - fcb->Firmware1_startingPage); - pr_debug("PagesInFW1: 0x%08x\n", fcb->PagesInFirmware1); - pr_debug("FW2_startingPage: 0x%08x\n", - fcb->Firmware2_startingPage); - pr_debug("PagesInFW2: 0x%08x\n", fcb->PagesInFirmware2); - return 0; } return -EINVAL; } +static int imx7_get_fcb_n(struct mxs_nand_info *info, void *databuf, int num) +{ + int ret; + int flips = 0; + uint8_t *status; + int i; + + ret = mxs_nand_read_page(info, BCH62_WRITESIZE, BCH62_OOBSIZE, + info->organization.pages_per_eraseblock * num, databuf, 0, true); + if (ret) + return ret; + + /* Loop over status bytes, accumulating ECC status. */ + status = databuf + BCH62_WRITESIZE + 32; + + for (i = 0; i < 8; i++) { + switch (status[i]) { + case 0x0: + break; + case 0xff: + /* + * A status of 0xff means the chunk is erased, but due to + * the randomizer we see this as random data. Explicitly + * memset it. + */ + memset(databuf + 0x80 * i, 0xff, 0x80); + break; + case 0xfe: + return -EBADMSG; + default: + flips += status[0]; + break; + } + } + + return ret; +} + +static int imx7_get_fcb(struct mxs_nand_info *info, void *databuf) +{ + int i, ret; + struct fcb_block *fcb = &info->fcb; + + mxs_nand_mode_fcb_62bit(info->bch_base); + + for (i = 0; i < 4; i++) { + ret = imx7_get_fcb_n(info, databuf, i); + if (!ret) + break; + } + + if (ret) { + pr_err("Cannot find FCB\n"); + } else { + memcpy(fcb, databuf, sizeof(*fcb)); + } + + return ret; +} + static int get_dbbt(struct mxs_nand_info *info, void *databuf) { int i, ret; @@ -1022,7 +965,11 @@ static int get_dbbt(struct mxs_nand_info *info, void *databuf) page = startpage + i * info->organization.pages_per_eraseblock; ret = mxs_nand_read_page(info, info->organization.pagesize, - info->organization.oobsize, page, databuf, 0); + info->organization.oobsize, page, databuf, 0, false); + if (ret) + continue; + + ret = mxs_nand_get_ecc_status(info, databuf); if (ret) continue; @@ -1036,7 +983,11 @@ static int get_dbbt(struct mxs_nand_info *info, void *databuf) return -ENOENT; ret = mxs_nand_read_page(info, info->organization.pagesize, - info->organization.oobsize, page + 4, databuf, 0); + info->organization.oobsize, page + 4, databuf, 0, false); + if (ret) + continue; + + ret = mxs_nand_get_ecc_status(info, databuf); if (ret) continue; @@ -1107,7 +1058,7 @@ static int read_firmware(struct mxs_nand_info *info, int startpage, } ret = mxs_nand_read_page(info, pagesize, oobsize, - curpage, dest, 0); + curpage, dest, 0, false); if (ret) { pr_debug("Failed to read page %d\n", curpage); return ret; @@ -1124,49 +1075,73 @@ static int read_firmware(struct mxs_nand_info *info, int startpage, return 0; } -static int __maybe_unused imx6_nand_load_image(void *cmdbuf, void *descs, - void *databuf, void *dest, int len) +struct imx_nand_params { + struct mxs_nand_info info; + struct apbh_dma apbh; + void *sdram; + int (*get_fcb)(struct mxs_nand_info *info, void *databuf); +}; + +static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params, + void *databuf, void *dest, int len) { - struct mxs_nand_info info = { - .io_base = (void *)0x00112000, - .bch_base = (void *)0x00114000, - }; - struct apbh_dma apbh = { - .id = IMX28_DMA, - .regs = (void *)0x00110000, - }; + struct mxs_nand_info *info = ¶ms->info; struct mxs_dma_chan pchan = { .channel = 0, /* MXS: MXS_DMA_CHANNEL_AHB_APBH_GPMI0 */ - .apbh = &apbh, + .apbh = ¶ms->apbh, }; int ret; struct fcb_block *fcb; + void __iomem *bch_regs = info->bch_base; + u32 fl0, fl1; - info.dma_channel = &pchan; + info->dma_channel = &pchan; pr_debug("cmdbuf: 0x%p descs: 0x%p databuf: 0x%p dest: 0x%p\n", - cmdbuf, descs, databuf, dest); + info->cmd_buf, info->desc, databuf, dest); - /* Command buffers */ - info.cmd_buf = cmdbuf; - info.desc = descs; - - ret = mxs_nand_get_info(&info, databuf); + ret = mxs_nand_get_info(info, databuf); if (ret) return ret; - ret = get_fcb(&info, databuf); + ret = params->get_fcb(info, databuf); if (ret) return ret; - fcb = &info.fcb; - - get_dbbt(&info, databuf); - - ret = read_firmware(&info, fcb->Firmware1_startingPage, dest, len); + fcb = &info->fcb; + + pr_debug("Found FCB:\n"); + pr_debug("PageDataSize: 0x%08x\n", fcb->PageDataSize); + pr_debug("TotalPageSize: 0x%08x\n", fcb->TotalPageSize); + pr_debug("SectorsPerBlock: 0x%08x\n", fcb->SectorsPerBlock); + pr_debug("FW1_startingPage: 0x%08x\n", + fcb->Firmware1_startingPage); + pr_debug("PagesInFW1: 0x%08x\n", fcb->PagesInFirmware1); + pr_debug("FW2_startingPage: 0x%08x\n", + fcb->Firmware2_startingPage); + pr_debug("PagesInFW2: 0x%08x\n", fcb->PagesInFirmware2); + + info->organization.oobsize = fcb->TotalPageSize - fcb->PageDataSize; + info->organization.pagesize = fcb->PageDataSize; + + fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, fcb->NumEccBlocksPerPage) | + FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, fcb->MetadataBytes) | + FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, fcb->EccBlock0EccType) | + (fcb->BCHType ? BCH_FLASHLAYOUT0_GF13_0_GF14_1 : 0) | + FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, fcb->EccBlock0Size / 4); + fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, fcb->TotalPageSize) | + FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, fcb->EccBlockNEccType) | + (fcb->BCHType ? BCH_FLASHLAYOUT1_GF13_0_GF14_1 : 0) | + FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, fcb->EccBlockNSize / 4); + writel(fl0, bch_regs + BCH_FLASH0LAYOUT0); + writel(fl1, bch_regs + BCH_FLASH0LAYOUT1); + + get_dbbt(info, databuf); + + ret = read_firmware(info, fcb->Firmware1_startingPage, dest, len); if (ret) { pr_err("Failed to read firmware1, trying firmware2\n"); - ret = read_firmware(&info, fcb->Firmware2_startingPage, + ret = read_firmware(info, fcb->Firmware2_startingPage, dest, len); if (ret) { pr_err("Failed to also read firmware2\n"); @@ -1177,24 +1152,21 @@ static int __maybe_unused imx6_nand_load_image(void *cmdbuf, void *descs, return 0; } -int imx6_nand_start_image(void) +static int imx_nand_start_image(struct imx_nand_params *params) { + struct mxs_nand_info *info = ¶ms->info; int ret; - void *sdram = (void *)0x10000000; void __noreturn (*bb)(void); - void *cmdbuf, *databuf, *descs; + void *databuf; - cmdbuf = sdram; - descs = sdram + MXS_NAND_COMMAND_BUFFER_SIZE; - databuf = descs + + /* Command buffers */ + info->cmd_buf = params->sdram; + info->desc = params->sdram + MXS_NAND_COMMAND_BUFFER_SIZE; + databuf = info->desc + sizeof(struct mxs_dma_cmd) * MXS_NAND_DMA_DESCRIPTOR_COUNT; bb = (void *)PAGE_ALIGN((unsigned long)databuf + SZ_8K); - /* Apply ERR007117 workaround */ - imx6_errata_007117_enable(); - - ret = imx6_nand_load_image(cmdbuf, descs, databuf, - bb, imx_image_size()); + ret = imx6_nand_load_image(params, databuf, bb, imx_image_size()); if (ret) { pr_err("Loading image failed: %d\n", ret); return ret; @@ -1207,3 +1179,34 @@ int imx6_nand_start_image(void) bb(); } + +int imx6_nand_start_image(void) +{ + static struct imx_nand_params params = { + .info.io_base = IOMEM(MX6_GPMI_BASE_ADDR), + .info.bch_base = IOMEM(MX6_BCH_BASE_ADDR), + .apbh.regs = IOMEM(MX6_APBH_BASE_ADDR), + .apbh.id = IMX28_DMA, + .sdram = (void *)MX6_MMDC_PORT01_BASE_ADDR, + .get_fcb = imx6_get_fcb, + }; + + /* Apply ERR007117 workaround */ + imx6_errata_007117_enable(); + + return imx_nand_start_image(¶ms); +} + +int imx7_nand_start_image(void) +{ + static struct imx_nand_params params = { + .info.io_base = IOMEM(MX7_GPMI_BASE), + .info.bch_base = IOMEM(MX7_BCH_BASE), + .apbh.regs = IOMEM(MX7_APBH_BASE), + .apbh.id = IMX28_DMA, + .sdram = (void *)MX7_DDR_BASE_ADDR, + .get_fcb = imx7_get_fcb, + }; + + return imx_nand_start_image(¶ms); +} diff --git a/arch/arm/mach-mxs/include/mach/generic.h b/arch/arm/mach-mxs/include/mach/generic.h index dc1b6ed4a0..4cba591000 100644 --- a/arch/arm/mach-mxs/include/mach/generic.h +++ b/arch/arm/mach-mxs/include/mach/generic.h @@ -22,3 +22,6 @@ #define cpu_is_mx51() (0) #define cpu_is_mx53() (0) #define cpu_is_mx6() (0) +#define cpu_is_mx7() (0) +#define cpu_is_mx6ul() (0) +#define cpu_is_mx6ull() (0) diff --git a/commands/Kconfig b/commands/Kconfig index a59616ad14..ec15f4e543 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -60,6 +60,14 @@ config CMD_RISCV_CPUINFO help Show info about RISC-V CPU +config CMD_BOOTROM + bool "bootrom command" + depends on ARCH_IMX8M + help + Interact with bootrom on i.MX8M + + bootrom [-la] + config CMD_DEVINFO tristate default y @@ -326,6 +334,15 @@ config CMD_SLICE command can be used to print informations about slices and also to manipulate them on the command line for debugging purposes. +config CMD_FCB + depends on BAREBOX_UPDATE_IMX_NAND_FCB + tristate + prompt "fcb" + help + Several i.MX SoCs booting from NAND flash need a so called Flash Control Block + at the beginning of the NAND device. The fcb command prints information about + the FCB. + # end Information commands endmenu diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c index 63c81e4ed6..24b0e7592e 100644 --- a/common/imx-bbu-nand-fcb.c +++ b/common/imx-bbu-nand-fcb.c @@ -14,6 +14,8 @@ #include <linux/sizes.h> #include <bbu.h> #include <fs.h> +#include <command.h> +#include <complete.h> #include <linux/mtd/mtd-abi.h> #include <linux/mtd/nand_mxs.h> #include <linux/mtd/mtd.h> @@ -26,19 +28,14 @@ #include <mach/generic.h> #include <mtd/mtd-peb.h> #include <soc/imx/imx-nand-bcb.h> - -#ifdef CONFIG_ARCH_IMX28 -static inline int fcb_is_bch_encoded(void) -{ - return 0; -} -#else +#ifdef CONFIG_ARCH_IMX #include <mach/imx6.h> +#endif + static inline int fcb_is_bch_encoded(void) { return cpu_is_mx6ul() || cpu_is_mx6ull(); } -#endif struct imx_nand_fcb_bbu_handler { struct bbu_handler handler; @@ -284,57 +281,57 @@ static __maybe_unused void dump_fcb(void *buf) { struct fcb_block *fcb = buf; - pr_debug("Checksum: 0x%08x\n", fcb->Checksum); - pr_debug("FingerPrint: 0x%08x\n", fcb->FingerPrint); - pr_debug("Version: 0x%08x\n", fcb->Version); - pr_debug("DataSetup: 0x%02x\n", fcb->DataSetup); - pr_debug("DataHold: 0x%02x\n", fcb->DataHold); - pr_debug("AddressSetup: 0x%02x\n", fcb->AddressSetup); - pr_debug("DSAMPLE_TIME: 0x%02x\n", fcb->DSAMPLE_TIME); - pr_debug("NandTimingState: 0x%02x\n", fcb->NandTimingState); - pr_debug("REA: 0x%02x\n", fcb->REA); - pr_debug("RLOH: 0x%02x\n", fcb->RLOH); - pr_debug("RHOH: 0x%02x\n", fcb->RHOH); - pr_debug("PageDataSize: 0x%08x\n", fcb->PageDataSize); - pr_debug("TotalPageSize: 0x%08x\n", fcb->TotalPageSize); - pr_debug("SectorsPerBlock: 0x%08x\n", fcb->SectorsPerBlock); - pr_debug("NumberOfNANDs: 0x%08x\n", fcb->NumberOfNANDs); - pr_debug("TotalInternalDie: 0x%08x\n", fcb->TotalInternalDie); - pr_debug("CellType: 0x%08x\n", fcb->CellType); - pr_debug("EccBlockNEccType: 0x%08x\n", fcb->EccBlockNEccType); - pr_debug("EccBlock0Size: 0x%08x\n", fcb->EccBlock0Size); - pr_debug("EccBlockNSize: 0x%08x\n", fcb->EccBlockNSize); - pr_debug("EccBlock0EccType: 0x%08x\n", fcb->EccBlock0EccType); - pr_debug("MetadataBytes: 0x%08x\n", fcb->MetadataBytes); - pr_debug("NumEccBlocksPerPage: 0x%08x\n", fcb->NumEccBlocksPerPage); - pr_debug("EccBlockNEccLevelSDK: 0x%08x\n", fcb->EccBlockNEccLevelSDK); - pr_debug("EccBlock0SizeSDK: 0x%08x\n", fcb->EccBlock0SizeSDK); - pr_debug("EccBlockNSizeSDK: 0x%08x\n", fcb->EccBlockNSizeSDK); - pr_debug("EccBlock0EccLevelSDK: 0x%08x\n", fcb->EccBlock0EccLevelSDK); - pr_debug("NumEccBlocksPerPageSDK: 0x%08x\n", fcb->NumEccBlocksPerPageSDK); - pr_debug("MetadataBytesSDK: 0x%08x\n", fcb->MetadataBytesSDK); - pr_debug("EraseThreshold: 0x%08x\n", fcb->EraseThreshold); - pr_debug("BootPatch: 0x%08x\n", fcb->BootPatch); - pr_debug("PatchSectors: 0x%08x\n", fcb->PatchSectors); - pr_debug("Firmware1_startingPage: 0x%08x\n", fcb->Firmware1_startingPage); - pr_debug("Firmware2_startingPage: 0x%08x\n", fcb->Firmware2_startingPage); - pr_debug("PagesInFirmware1: 0x%08x\n", fcb->PagesInFirmware1); - pr_debug("PagesInFirmware2: 0x%08x\n", fcb->PagesInFirmware2); - pr_debug("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress); - pr_debug("BadBlockMarkerByte: 0x%08x\n", fcb->BadBlockMarkerByte); - pr_debug("BadBlockMarkerStartBit: 0x%08x\n", fcb->BadBlockMarkerStartBit); - pr_debug("BBMarkerPhysicalOffset: 0x%08x\n", fcb->BBMarkerPhysicalOffset); - pr_debug("BCHType: 0x%08x\n", fcb->BCHType); - pr_debug("TMTiming2_ReadLatency: 0x%08x\n", fcb->TMTiming2_ReadLatency); - pr_debug("TMTiming2_PreambleDelay: 0x%08x\n", fcb->TMTiming2_PreambleDelay); - pr_debug("TMTiming2_CEDelay: 0x%08x\n", fcb->TMTiming2_CEDelay); - pr_debug("TMTiming2_PostambleDelay: 0x%08x\n", fcb->TMTiming2_PostambleDelay); - pr_debug("TMTiming2_CmdAddPause: 0x%08x\n", fcb->TMTiming2_CmdAddPause); - pr_debug("TMTiming2_DataPause: 0x%08x\n", fcb->TMTiming2_DataPause); - pr_debug("TMSpeed: 0x%08x\n", fcb->TMSpeed); - pr_debug("TMTiming1_BusyTimeout: 0x%08x\n", fcb->TMTiming1_BusyTimeout); - pr_debug("DISBBM: 0x%08x\n", fcb->DISBBM); - pr_debug("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData); + printf("Checksum: 0x%08x\n", fcb->Checksum); + printf("FingerPrint: 0x%08x\n", fcb->FingerPrint); + printf("Version: 0x%08x\n", fcb->Version); + printf("DataSetup: 0x%02x\n", fcb->DataSetup); + printf("DataHold: 0x%02x\n", fcb->DataHold); + printf("AddressSetup: 0x%02x\n", fcb->AddressSetup); + printf("DSAMPLE_TIME: 0x%02x\n", fcb->DSAMPLE_TIME); + printf("NandTimingState: 0x%02x\n", fcb->NandTimingState); + printf("REA: 0x%02x\n", fcb->REA); + printf("RLOH: 0x%02x\n", fcb->RLOH); + printf("RHOH: 0x%02x\n", fcb->RHOH); + printf("PageDataSize: 0x%08x\n", fcb->PageDataSize); + printf("TotalPageSize: 0x%08x\n", fcb->TotalPageSize); + printf("SectorsPerBlock: 0x%08x\n", fcb->SectorsPerBlock); + printf("NumberOfNANDs: 0x%08x\n", fcb->NumberOfNANDs); + printf("TotalInternalDie: 0x%08x\n", fcb->TotalInternalDie); + printf("CellType: 0x%08x\n", fcb->CellType); + printf("EccBlockNEccType: 0x%08x\n", fcb->EccBlockNEccType); + printf("EccBlock0Size: 0x%08x\n", fcb->EccBlock0Size); + printf("EccBlockNSize: 0x%08x\n", fcb->EccBlockNSize); + printf("EccBlock0EccType: 0x%08x\n", fcb->EccBlock0EccType); + printf("MetadataBytes: 0x%08x\n", fcb->MetadataBytes); + printf("NumEccBlocksPerPage: 0x%08x\n", fcb->NumEccBlocksPerPage); + printf("EccBlockNEccLevelSDK: 0x%08x\n", fcb->EccBlockNEccLevelSDK); + printf("EccBlock0SizeSDK: 0x%08x\n", fcb->EccBlock0SizeSDK); + printf("EccBlockNSizeSDK: 0x%08x\n", fcb->EccBlockNSizeSDK); + printf("EccBlock0EccLevelSDK: 0x%08x\n", fcb->EccBlock0EccLevelSDK); + printf("NumEccBlocksPerPageSDK: 0x%08x\n", fcb->NumEccBlocksPerPageSDK); + printf("MetadataBytesSDK: 0x%08x\n", fcb->MetadataBytesSDK); + printf("EraseThreshold: 0x%08x\n", fcb->EraseThreshold); + printf("BootPatch: 0x%08x\n", fcb->BootPatch); + printf("PatchSectors: 0x%08x\n", fcb->PatchSectors); + printf("Firmware1_startingPage: 0x%08x\n", fcb->Firmware1_startingPage); + printf("Firmware2_startingPage: 0x%08x\n", fcb->Firmware2_startingPage); + printf("PagesInFirmware1: 0x%08x\n", fcb->PagesInFirmware1); + printf("PagesInFirmware2: 0x%08x\n", fcb->PagesInFirmware2); + printf("DBBTSearchAreaStartAddress: 0x%08x\n", fcb->DBBTSearchAreaStartAddress); + printf("BadBlockMarkerByte: 0x%08x\n", fcb->BadBlockMarkerByte); + printf("BadBlockMarkerStartBit: 0x%08x\n", fcb->BadBlockMarkerStartBit); + printf("BBMarkerPhysicalOffset: 0x%08x\n", fcb->BBMarkerPhysicalOffset); + printf("BCHType: 0x%08x\n", fcb->BCHType); + printf("TMTiming2_ReadLatency: 0x%08x\n", fcb->TMTiming2_ReadLatency); + printf("TMTiming2_PreambleDelay: 0x%08x\n", fcb->TMTiming2_PreambleDelay); + printf("TMTiming2_CEDelay: 0x%08x\n", fcb->TMTiming2_CEDelay); + printf("TMTiming2_PostambleDelay: 0x%08x\n", fcb->TMTiming2_PostambleDelay); + printf("TMTiming2_CmdAddPause: 0x%08x\n", fcb->TMTiming2_CmdAddPause); + printf("TMTiming2_DataPause: 0x%08x\n", fcb->TMTiming2_DataPause); + printf("TMSpeed: 0x%08x\n", fcb->TMSpeed); + printf("TMTiming1_BusyTimeout: 0x%08x\n", fcb->TMTiming1_BusyTimeout); + printf("DISBBM: 0x%08x\n", fcb->DISBBM); + printf("BBMarkerPhysOfsInSpareData: 0x%08x\n", fcb->BBMarkerPhysicalOffsetInSpareData); } static __maybe_unused ssize_t raw_read_page(struct mtd_info *mtd, void *dst, loff_t offset) @@ -1554,6 +1551,20 @@ int imx28_bbu_nand_register_handler(const char *name, unsigned long flags) } #endif +static int imx7_fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb) +{ + struct fcb_block *fcb = xzalloc(mtd->writesize); + int ret; + + ret = mxs_nand_read_fcb_bch62(block, fcb, sizeof(*fcb)); + if (ret) + free(fcb); + else + *retfcb = fcb; + + return ret; +} + #ifdef CONFIG_ARCH_IMX7 #include <mach/imx7-regs.h> @@ -1572,29 +1583,15 @@ static void imx7_fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler, fl0 = readl(bch_regs + BCH_FLASH0LAYOUT0); fcb->MetadataBytes = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE); fcb->NumEccBlocksPerPage = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS); + fcb->EccBlock0Size = 4 * BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE); + fcb->EccBlock0EccType = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0); fl1 = readl(bch_regs + BCH_FLASH0LAYOUT1); - fcb->EccBlock0Size = 4 * BF_VAL(fl1, BCH_FLASHLAYOUT0_DATA0_SIZE); - fcb->EccBlock0EccType = BF_VAL(fl1, BCH_FLASHLAYOUT0_ECC0); fcb->EccBlockNSize = 4 * BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE); fcb->EccBlockNEccType = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN); fcb->BCHType = BF_VAL(fl1, BCH_FLASHLAYOUT1_GF13_0_GF14_1); } -static int imx7_fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb) -{ - struct fcb_block *fcb = xzalloc(mtd->writesize); - int ret; - - ret = mxs_nand_read_fcb_bch62(block, fcb, sizeof(*fcb)); - if (ret) - free(fcb); - else - *retfcb = fcb; - - return ret; -} - static int imx7_fcb_write(struct mtd_info *mtd, int block, struct fcb_block *fcb) { return mxs_nand_write_fcb_bch62(block, fcb, sizeof(*fcb)); @@ -1625,3 +1622,87 @@ int imx7_bbu_nand_register_handler(const char *name, unsigned long flags) return ret; } #endif + +static void dump_fcb_n(struct fcb_block **fcbs, int n) +{ + int i; + + if (!n || !fcbs[n]) + goto skip_compare; + + for (i = 0; i < n; i++) { + if (!fcbs[i] || !fcbs[n]) + continue; + + if (!memcmp(fcbs[i], fcbs[n], sizeof(struct fcb_block))) { + printf("FCB block#%d: same as FCB block#%d\n", n, i); + return; + } + } + +skip_compare: + if (fcbs[n]) { + printf("FCB block#%d:\n", n); + dump_fcb(fcbs[n]); + } else { + printf("FCB block#%d: NULL\n", n); + } +} + +static int fcb_read(struct mtd_info *mtd, int block, struct fcb_block **retfcb) +{ + if (cpu_is_mx7()) + return imx7_fcb_read(mtd, block, retfcb); + else if (fcb_is_bch_encoded()) + return fcb_read_bch(mtd, block, retfcb); + else + return fcb_read_hamming_13_8(mtd, block, retfcb); +} + +static int cmd_fcb(int argc, char *argv[]) +{ + struct cdev *cdev; + struct mtd_info *mtd; + struct fcb_block *fcb[4] = {}; + int i, ret; + + cdev = cdev_open_by_name("nand0", O_RDONLY); + if (!cdev) { + printf("Cannot open nand0\n"); + return COMMAND_ERROR; + } + + mtd = cdev->mtd; + if (!mtd) { + ret = COMMAND_ERROR; + goto out; + } + + for (i = 0; i < 4; i++) + fcb_read(mtd, i, &fcb[i]); + + for (i = 0; i < 4; i++) + dump_fcb_n(fcb, i); + + for (i = 0; i < 4; i++) + free(fcb[i]); + + ret = 0; + +out: + cdev_close(cdev); + + return ret; +} + +BAREBOX_CMD_HELP_START(fcb) +BAREBOX_CMD_HELP_TEXT("Dump FCB as found on /dev/nand0") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(fcb) + .cmd = cmd_fcb, + BAREBOX_CMD_DESC("Dump Flash Control Block (FCB)") + BAREBOX_CMD_GROUP(CMD_GRP_MISC) + BAREBOX_CMD_HELP(cmd_fcb_help) + BAREBOX_CMD_COMPLETE(empty_complete) +BAREBOX_CMD_END diff --git a/common/ubiformat.c b/common/ubiformat.c index 1edfc5b2a3..d8399ad9d6 100644 --- a/common/ubiformat.c +++ b/common/ubiformat.c @@ -745,6 +745,7 @@ int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count, while (count) { size_t now = mtd->erasesize - offset_in_peb; + int new_len; if (now > count) now = count; @@ -780,7 +781,8 @@ int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count, } } - ret = mtd_peb_write(mtd, buf, peb, offset_in_peb, now); + new_len = drop_ffs(mtd, buf, now); + ret = mtd_peb_write(mtd, buf, peb, offset_in_peb, new_len); if (ret < 0) return ret; diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index 83bd783d34..767c095314 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -24,41 +24,12 @@ #include <init.h> #include <io.h> - -#define HW_APBHX_CTRL0 0x000 -#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29) -#define BM_APBH_CTRL0_APB_BURST_EN (1 << 28) -#define BP_APBH_CTRL0_CLKGATE_CHANNEL 8 -#define BP_APBH_CTRL0_RESET_CHANNEL 16 -#define HW_APBHX_CTRL1 0x010 -#define BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN 16 -#define HW_APBHX_CTRL2 0x020 -#define HW_APBHX_CHANNEL_CTRL 0x030 -#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16 -#define BP_APBHX_VERSION_MAJOR 24 -#define HW_APBHX_CHn_NXTCMDAR_MX23(n) (0x050 + (n) * 0x70) -#define HW_APBHX_CHn_NXTCMDAR_MX28(n) (0x110 + (n) * 0x70) -#define HW_APBHX_CHn_SEMA_MX23(n) (0x080 + (n) * 0x70) -#define HW_APBHX_CHn_SEMA_MX28(n) (0x140 + (n) * 0x70) -#define BM_APBHX_CHn_SEMA_PHORE (0xff << 16) -#define BP_APBHX_CHn_SEMA_PHORE 16 - -static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS]; - -enum mxs_dma_id { - UNKNOWN_DMA_ID, - IMX23_DMA, - IMX28_DMA, -}; - struct apbh_dma { void __iomem *regs; struct clk *clk; enum mxs_dma_id id; }; -#define apbh_dma_is_imx23(aphb) ((apbh)->id == IMX23_DMA) - static struct apbh_dma *apbh_dma; /* @@ -66,185 +37,9 @@ static struct apbh_dma *apbh_dma; */ static int mxs_dma_validate_chan(int channel) { - struct mxs_dma_chan *pchan; - if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS)) return -EINVAL; - pchan = mxs_dma_channels + channel; - if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED)) - return -EINVAL; - - return 0; -} - -/* - * Return the address of the command within a descriptor. - */ -static unsigned int mxs_dma_cmd_address(struct mxs_dma_desc *desc) -{ - return desc->address + offsetof(struct mxs_dma_desc, cmd); -} - -/* - * Read a DMA channel's hardware semaphore. - * - * As used by the MXS platform's DMA software, the DMA channel's hardware - * semaphore reflects the number of DMA commands the hardware will process, but - * has not yet finished. This is a volatile value read directly from hardware, - * so it must be be viewed as immediately stale. - * - * If the channel is not marked busy, or has finished processing all its - * commands, this value should be zero. - * - * See mxs_dma_append() for details on how DMA command blocks must be configured - * to maintain the expected behavior of the semaphore's value. - */ -static int mxs_dma_read_semaphore(int channel) -{ - struct apbh_dma *apbh = apbh_dma; - uint32_t tmp; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - if (apbh_dma_is_imx23(apbh)) - tmp = readl(apbh->regs + HW_APBHX_CHn_SEMA_MX23(channel)); - else - tmp = readl(apbh->regs + HW_APBHX_CHn_SEMA_MX28(channel)); - - tmp &= BM_APBHX_CHn_SEMA_PHORE; - tmp >>= BP_APBHX_CHn_SEMA_PHORE; - - return tmp; -} - -/* - * Enable a DMA channel. - * - * If the given channel has any DMA descriptors on its active list, this - * function causes the DMA hardware to begin processing them. - * - * This function marks the DMA channel as "busy," whether or not there are any - * descriptors to process. - */ -static int mxs_dma_enable(int channel) -{ - struct apbh_dma *apbh = apbh_dma; - unsigned int sem; - struct mxs_dma_chan *pchan; - struct mxs_dma_desc *pdesc; - int channel_bit, ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - pchan = mxs_dma_channels + channel; - - if (pchan->pending_num == 0) { - pchan->flags |= MXS_DMA_FLAGS_BUSY; - return 0; - } - - pdesc = list_first_entry(&pchan->active, struct mxs_dma_desc, node); - if (pdesc == NULL) - return -EFAULT; - - if (pchan->flags & MXS_DMA_FLAGS_BUSY) { - if (!(pdesc->cmd.data & MXS_DMA_DESC_CHAIN)) - return 0; - - sem = mxs_dma_read_semaphore(channel); - if (sem == 0) - return 0; - - if (sem == 1) { - pdesc = list_entry(pdesc->node.next, - struct mxs_dma_desc, node); - if (apbh_dma_is_imx23(apbh)) - writel(mxs_dma_cmd_address(pdesc), - apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX23(channel)); - else - writel(mxs_dma_cmd_address(pdesc), - apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX28(channel)); - } - - if (apbh_dma_is_imx23(apbh)) - writel(pchan->pending_num, - apbh->regs + HW_APBHX_CHn_SEMA_MX23(channel)); - else - writel(pchan->pending_num, - apbh->regs + HW_APBHX_CHn_SEMA_MX28(channel)); - - pchan->active_num += pchan->pending_num; - pchan->pending_num = 0; - } else { - pchan->active_num += pchan->pending_num; - pchan->pending_num = 0; - if (apbh_dma_is_imx23(apbh)) { - writel(mxs_dma_cmd_address(pdesc), - apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX23(channel)); - writel(pchan->active_num, - apbh->regs + HW_APBHX_CHn_SEMA_MX23(channel)); - channel_bit = channel + BP_APBH_CTRL0_CLKGATE_CHANNEL; - } else { - writel(mxs_dma_cmd_address(pdesc), - apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX28(channel)); - writel(pchan->active_num, - apbh->regs + HW_APBHX_CHn_SEMA_MX28(channel)); - channel_bit = channel; - } - writel(1 << channel_bit, apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR); - } - - pchan->flags |= MXS_DMA_FLAGS_BUSY; - return 0; -} - -/* - * Disable a DMA channel. - * - * This function shuts down a DMA channel and marks it as "not busy." Any - * descriptors on the active list are immediately moved to the head of the - * "done" list, whether or not they have actually been processed by the - * hardware. The "ready" flags of these descriptors are NOT cleared, so they - * still appear to be active. - * - * This function immediately shuts down a DMA channel's hardware, aborting any - * I/O that may be in progress, potentially leaving I/O hardware in an undefined - * state. It is unwise to call this function if there is ANY chance the hardware - * is still processing a command. - */ -static int mxs_dma_disable(int channel) -{ - struct mxs_dma_chan *pchan; - struct apbh_dma *apbh = apbh_dma; - int channel_bit, ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - pchan = mxs_dma_channels + channel; - - if (!(pchan->flags & MXS_DMA_FLAGS_BUSY)) - return -EINVAL; - - if (apbh_dma_is_imx23(apbh)) - channel_bit = channel + BP_APBH_CTRL0_CLKGATE_CHANNEL; - else - channel_bit = channel + 0; - - writel(1 << channel_bit, apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET); - - pchan->flags &= ~MXS_DMA_FLAGS_BUSY; - pchan->active_num = 0; - pchan->pending_num = 0; - list_splice_init(&pchan->active, &pchan->done); - return 0; } @@ -254,11 +49,6 @@ static int mxs_dma_disable(int channel) static int mxs_dma_reset(int channel) { struct apbh_dma *apbh = apbh_dma; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; if (apbh_dma_is_imx23(apbh)) writel(1 << (channel + BP_APBH_CTRL0_RESET_CHANNEL), @@ -271,30 +61,6 @@ static int mxs_dma_reset(int channel) } /* - * Enable or disable DMA interrupt. - * - * This function enables the given DMA channel to interrupt the CPU. - */ -static int mxs_dma_enable_irq(int channel, int enable) -{ - struct apbh_dma *apbh = apbh_dma; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - if (enable) - writel(1 << (channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN), - apbh->regs + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET); - else - writel(1 << (channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN), - apbh->regs + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR); - - return 0; -} - -/* * Clear DMA interrupt. * * The software that is using the DMA channel must register to receive its @@ -303,11 +69,6 @@ static int mxs_dma_enable_irq(int channel, int enable) static int mxs_dma_ack_irq(int channel) { struct apbh_dma *apbh = apbh_dma; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; writel(1 << channel, apbh->regs + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR); writel(1 << channel, apbh->regs + HW_APBHX_CTRL2 + STMP_OFFSET_REG_CLR); @@ -316,229 +77,11 @@ static int mxs_dma_ack_irq(int channel) } /* - * Request to reserve a DMA channel - */ -static int mxs_dma_request(int channel) -{ - struct mxs_dma_chan *pchan; - - if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS)) - return -EINVAL; - - pchan = mxs_dma_channels + channel; - if ((pchan->flags & MXS_DMA_FLAGS_VALID) != MXS_DMA_FLAGS_VALID) - return -ENODEV; - - if (pchan->flags & MXS_DMA_FLAGS_ALLOCATED) - return -EBUSY; - - pchan->flags |= MXS_DMA_FLAGS_ALLOCATED; - pchan->active_num = 0; - pchan->pending_num = 0; - - INIT_LIST_HEAD(&pchan->active); - INIT_LIST_HEAD(&pchan->done); - - return 0; -} - -/* - * Release a DMA channel. - * - * This function releases a DMA channel from its current owner. - * - * The channel will NOT be released if it's marked "busy" (see - * mxs_dma_enable()). - */ -static int mxs_dma_release(int channel) -{ - struct mxs_dma_chan *pchan; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - pchan = mxs_dma_channels + channel; - - if (pchan->flags & MXS_DMA_FLAGS_BUSY) - return -EBUSY; - - pchan->dev = 0; - pchan->active_num = 0; - pchan->pending_num = 0; - pchan->flags &= ~MXS_DMA_FLAGS_ALLOCATED; - - return 0; -} - -/* - * Allocate DMA descriptor - */ -struct mxs_dma_desc *mxs_dma_desc_alloc(void) -{ - struct mxs_dma_desc *pdesc; - dma_addr_t dma_address; - - pdesc = dma_alloc_coherent(sizeof(struct mxs_dma_desc), - &dma_address); - - if (pdesc == NULL) - return NULL; - - pdesc->address = dma_address; - - return pdesc; -}; - -/* - * Free DMA descriptor - */ -void mxs_dma_desc_free(struct mxs_dma_desc *pdesc) -{ - if (pdesc == NULL) - return; - - free(pdesc); -} - -/* - * Add a DMA descriptor to a channel. - * - * If the descriptor list for this channel is not empty, this function sets the - * CHAIN bit and the NEXTCMD_ADDR fields in the last descriptor's DMA command so - * it will chain to the new descriptor's command. - * - * Then, this function marks the new descriptor as "ready," adds it to the end - * of the active descriptor list, and increments the count of pending - * descriptors. - * - * The MXS platform DMA software imposes some rules on DMA commands to maintain - * important invariants. These rules are NOT checked, but they must be carefully - * applied by software that uses MXS DMA channels. - * - * Invariant: - * The DMA channel's hardware semaphore must reflect the number of DMA - * commands the hardware will process, but has not yet finished. - * - * Explanation: - * A DMA channel begins processing commands when its hardware semaphore is - * written with a value greater than zero, and it stops processing commands - * when the semaphore returns to zero. - * - * When a channel finishes a DMA command, it will decrement its semaphore if - * the DECREMENT_SEMAPHORE bit is set in that command's flags bits. - * - * In principle, it's not necessary for the DECREMENT_SEMAPHORE to be set, - * unless it suits the purposes of the software. For example, one could - * construct a series of five DMA commands, with the DECREMENT_SEMAPHORE - * bit set only in the last one. Then, setting the DMA channel's hardware - * semaphore to one would cause the entire series of five commands to be - * processed. However, this example would violate the invariant given above. - * - * Rule: - * ALL DMA commands MUST have the DECREMENT_SEMAPHORE bit set so that the DMA - * channel's hardware semaphore will be decremented EVERY time a command is - * processed. - */ -int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc) -{ - struct mxs_dma_chan *pchan; - struct mxs_dma_desc *last; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - pchan = mxs_dma_channels + channel; - - pdesc->cmd.next = mxs_dma_cmd_address(pdesc); - pdesc->flags |= MXS_DMA_DESC_FIRST | MXS_DMA_DESC_LAST; - - if (!list_empty(&pchan->active)) { - last = list_entry(pchan->active.prev, struct mxs_dma_desc, - node); - - pdesc->flags &= ~MXS_DMA_DESC_FIRST; - last->flags &= ~MXS_DMA_DESC_LAST; - - last->cmd.next = mxs_dma_cmd_address(pdesc); - last->cmd.data |= MXS_DMA_DESC_CHAIN; - } - pdesc->flags |= MXS_DMA_DESC_READY; - if (pdesc->flags & MXS_DMA_DESC_FIRST) - pchan->pending_num++; - list_add_tail(&pdesc->node, &pchan->active); - - return ret; -} - -/* - * Clean up processed DMA descriptors. - * - * This function removes processed DMA descriptors from the "active" list. Pass - * in a non-NULL list head to get the descriptors moved to your list. Pass NULL - * to get the descriptors moved to the channel's "done" list. Descriptors on - * the "done" list can be retrieved with mxs_dma_get_finished(). - * - * This function marks the DMA channel as "not busy" if no unprocessed - * descriptors remain on the "active" list. - */ -static int mxs_dma_finish(int channel, struct list_head *head) -{ - int sem; - struct mxs_dma_chan *pchan; - struct list_head *p, *q; - struct mxs_dma_desc *pdesc; - int ret; - - ret = mxs_dma_validate_chan(channel); - if (ret) - return ret; - - pchan = mxs_dma_channels + channel; - - sem = mxs_dma_read_semaphore(channel); - if (sem < 0) - return sem; - - if (sem == pchan->active_num) - return 0; - - list_for_each_safe(p, q, &pchan->active) { - if ((pchan->active_num) <= sem) - break; - - pdesc = list_entry(p, struct mxs_dma_desc, node); - pdesc->flags &= ~MXS_DMA_DESC_READY; - - if (head) - list_move_tail(p, head); - else - list_move_tail(p, &pchan->done); - - if (pdesc->flags & MXS_DMA_DESC_LAST) - pchan->active_num--; - } - - if (sem == 0) - pchan->flags &= ~MXS_DMA_FLAGS_BUSY; - - return 0; -} - -/* * Wait for DMA channel to complete */ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan) { struct apbh_dma *apbh = apbh_dma; - int ret; - - ret = mxs_dma_validate_chan(chan); - if (ret) - return ret; while (--timeout) { if (readl(apbh->regs + HW_APBHX_CTRL1) & (1 << chan)) @@ -546,38 +89,47 @@ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan) udelay(1); } - if (timeout == 0) { - ret = -ETIMEDOUT; - mxs_dma_reset(chan); - } + if (!timeout) + return -ETIMEDOUT; - return ret; + return 0; } /* * Execute the DMA channel */ -int mxs_dma_go(int chan) +int mxs_dma_go(int chan, struct mxs_dma_cmd *cmd, int ncmds) { + struct apbh_dma *apbh = apbh_dma; uint32_t timeout = 10000; - int ret; + int i, ret, channel_bit; - LIST_HEAD(tmp_desc_list); + ret = mxs_dma_validate_chan(chan); + if (ret) + return ret; + + for (i = 0; i < ncmds - 1; i++) { + cmd[i].next = (unsigned long)(&cmd[i + 1]); + cmd[i].data |= MXS_DMA_DESC_CHAIN; + } - mxs_dma_enable_irq(chan, 1); - mxs_dma_enable(chan); + if (apbh_dma_is_imx23(apbh)) { + writel(cmd, apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX23(chan)); + writel(1, apbh->regs + HW_APBHX_CHn_SEMA_MX23(chan)); + channel_bit = chan + BP_APBH_CTRL0_CLKGATE_CHANNEL; + } else { + writel(cmd, apbh->regs + HW_APBHX_CHn_NXTCMDAR_MX28(chan)); + writel(1, apbh->regs + HW_APBHX_CHn_SEMA_MX28(chan)); + channel_bit = chan; + } + writel(1 << channel_bit, apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR); /* Wait for DMA to finish. */ ret = mxs_dma_wait_complete(timeout, chan); - /* Clear out the descriptors we just ran. */ - mxs_dma_finish(chan, &tmp_desc_list); - /* Shut the DMA channel down. */ mxs_dma_ack_irq(chan); mxs_dma_reset(chan); - mxs_dma_enable_irq(chan, 0); - mxs_dma_disable(chan); return ret; } @@ -589,7 +141,6 @@ static int apbh_dma_probe(struct device_d *dev) { struct resource *iores; struct apbh_dma *apbh; - struct mxs_dma_chan *pchan; enum mxs_dma_id id; int ret, channel; @@ -627,28 +178,11 @@ static int apbh_dma_probe(struct device_d *dev) apbh->regs + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET); for (channel = 0; channel < MXS_MAX_DMA_CHANNELS; channel++) { - pchan = mxs_dma_channels + channel; - pchan->flags = MXS_DMA_FLAGS_VALID; - - ret = mxs_dma_request(channel); - - if (ret) { - printf("MXS DMA: Can't acquire DMA channel %i\n", - channel); - - goto err; - } - mxs_dma_reset(channel); mxs_dma_ack_irq(channel); } return 0; - -err: - while (--channel >= 0) - mxs_dma_release(channel); - return ret; } static struct platform_device_id apbh_ids[] = { diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index 5faa17a4bd..79a8fbdefa 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -21,6 +21,7 @@ #include <linux/types.h> #include <linux/clk.h> #include <linux/err.h> +#include <linux/bitfield.h> #include <of_mtd.h> #include <common.h> #include <dma.h> @@ -32,139 +33,10 @@ #include <dma/apbh-dma.h> #include <stmp-device.h> #include <mach/generic.h> +#include <soc/imx/gpmi-nand.h> #include "internals.h" -#define MX28_BLOCK_SFTRST (1 << 31) -#define MX28_BLOCK_CLKGATE (1 << 30) - -#define GPMI_CTRL0 0x00000000 -#define GPMI_CTRL0_RUN (1 << 29) -#define GPMI_CTRL0_DEV_IRQ_EN (1 << 28) -/* Disable for now since we don't need it and it is different on MX23. -#define GPMI_CTRL0_LOCK_CS (1 << 27) -*/ -#define GPMI_CTRL0_UDMA (1 << 26) -#define GPMI_CTRL0_COMMAND_MODE_MASK (0x3 << 24) -#define GPMI_CTRL0_COMMAND_MODE_OFFSET 24 -#define GPMI_CTRL0_COMMAND_MODE_WRITE (0x0 << 24) -#define GPMI_CTRL0_COMMAND_MODE_READ (0x1 << 24) -#define GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE (0x2 << 24) -#define GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY (0x3 << 24) -#define GPMI_CTRL0_WORD_LENGTH (1 << 23) -/* Careful: Is 0x3 on MX23 -#define GPMI_CTRL0_CS_MASK (0x7 << 20) -*/ -#define GPMI_CTRL0_CS_OFFSET 20 -#define GPMI_CTRL0_ADDRESS_MASK (0x7 << 17) -#define GPMI_CTRL0_ADDRESS_OFFSET 17 -#define GPMI_CTRL0_ADDRESS_NAND_DATA (0x0 << 17) -#define GPMI_CTRL0_ADDRESS_NAND_CLE (0x1 << 17) -#define GPMI_CTRL0_ADDRESS_NAND_ALE (0x2 << 17) -#define GPMI_CTRL0_ADDRESS_INCREMENT (1 << 16) -#define GPMI_CTRL0_XFER_COUNT_MASK 0xffff -#define GPMI_CTRL0_XFER_COUNT_OFFSET 0 - -#define GPMI_CTRL1 0x00000060 -#define GPMI_CTRL1_SET 0x00000064 -#define GPMI_CTRL1_CLR 0x00000068 -#define GPMI_CTRL1_DECOUPLE_CS (1 << 24) -#define GPMI_CTRL1_WRN_DLY(d) (((d) & 0x3) << 22) -#define GPMI_CTRL1_TIMEOUT_IRQ_EN (1 << 20) -#define GPMI_CTRL1_GANGED_RDYBUSY (1 << 19) -#define GPMI_CTRL1_BCH_MODE (1 << 18) -#define GPMI_CTRL1_DLL_ENABLE (1 << 17) -#define GPMI_CTRL1_HALF_PERIOD (1 << 16) -#define GPMI_CTRL1_RDN_DELAY(d) (((d) & 0xf) << 12) -#define GPMI_CTRL1_DMA2ECC_MODE (1 << 11) -#define GPMI_CTRL1_DEV_IRQ (1 << 10) -#define GPMI_CTRL1_TIMEOUT_IRQ (1 << 9) -#define GPMI_CTRL1_BURST_EN (1 << 8) -#define GPMI_CTRL1_ABORT_WAIT_REQUEST (1 << 7) -#define GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_MASK (0x7 << 4) -#define GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_OFFSET 4 -#define GPMI_CTRL1_DEV_RESET (1 << 3) -#define GPMI_CTRL1_ATA_IRQRDY_POLARITY (1 << 2) -#define GPMI_CTRL1_CAMERA_MODE (1 << 1) -#define GPMI_CTRL1_GPMI_MODE (1 << 0) - -#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS 0x0 -#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS 0x1 -#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS 0x2 -#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY 0x3 - -#define GPMI_TIMING0 0x00000070 - -#define GPMI_TIMING0_ADDRESS_SETUP(d) (((d) & 0xff) << 16) -#define GPMI_TIMING0_DATA_HOLD(d) (((d) & 0xff) << 8) -#define GPMI_TIMING0_DATA_SETUP(d) (((d) & 0xff) << 0) - -#define GPMI_TIMING1 0x00000080 -#define GPMI_TIMING1_BUSY_TIMEOUT(d) (((d) & 0xffff) << 16) - -#define GPMI_ECCCTRL_HANDLE_MASK (0xffff << 16) -#define GPMI_ECCCTRL_HANDLE_OFFSET 16 -#define GPMI_ECCCTRL_ECC_CMD_MASK (0x3 << 13) -#define GPMI_ECCCTRL_ECC_CMD_OFFSET 13 -#define GPMI_ECCCTRL_ECC_CMD_DECODE (0x0 << 13) -#define GPMI_ECCCTRL_ECC_CMD_ENCODE (0x1 << 13) -#define GPMI_ECCCTRL_RANDOMIZER_ENABLE (1 << 11) -#define GPMI_ECCCTRL_RANDOMIZER_TYPE0 0 -#define GPMI_ECCCTRL_RANDOMIZER_TYPE1 (1 << 9) -#define GPMI_ECCCTRL_RANDOMIZER_TYPE2 (2 << 9) -#define GPMI_ECCCTRL_ENABLE_ECC (1 << 12) -#define GPMI_ECCCTRL_BUFFER_MASK_MASK 0x1ff -#define GPMI_ECCCTRL_BUFFER_MASK_OFFSET 0 -#define GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY 0x100 -#define GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE 0x1ff - -#define GPMI_STAT 0x000000b0 -#define GPMI_STAT_READY_BUSY_OFFSET 24 - -#define GPMI_DEBUG 0x000000c0 -#define GPMI_DEBUG_READY0_OFFSET 28 - -#define GPMI_VERSION 0x000000d0 -#define GPMI_VERSION_MINOR_OFFSET 16 -#define GPMI_VERSION_TYPE_MX23 0x0300 - -#define BCH_CTRL 0x00000000 -#define BCH_CTRL_COMPLETE_IRQ (1 << 0) -#define BCH_CTRL_COMPLETE_IRQ_EN (1 << 8) - -#define BCH_LAYOUTSELECT 0x00000070 - -#define BCH_FLASH0LAYOUT0 0x00000080 -#define BCH_FLASHLAYOUT0_NBLOCKS_MASK (0xff << 24) -#define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24 -#define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16) -#define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16 -#define BCH_FLASHLAYOUT0_ECC0_MASK (0xf << 12) -#define BCH_FLASHLAYOUT0_ECC0_OFFSET 12 -#define IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET 11 -#define BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET 0 -#define BCH_FLASHLAYOUT0_GF13_0_GF14_1_MASK BIT(10) -#define BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET 10 - -#define BCH_FLASH0LAYOUT1 0x00000090 -#define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16) -#define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16 -#define BCH_FLASHLAYOUT1_ECCN_MASK (0xf << 12) -#define BCH_FLASHLAYOUT1_ECCN_OFFSET 12 -#define IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET 11 -#define BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK BIT(10) -#define BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET 10 -#define BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET 0 - -#define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 - -#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512 -#define MXS_NAND_METADATA_SIZE 10 - -#define MXS_NAND_COMMAND_BUFFER_SIZE 32 - -#define MXS_NAND_BCH_TIMEOUT 10000 - enum gpmi_type { GPMI_MXS, GPMI_IMX6, @@ -230,7 +102,7 @@ struct mxs_nand_info { loff_t to, struct mtd_oob_ops *ops); /* DMA descriptors */ - struct mxs_dma_desc **desc; + struct mxs_dma_cmd *desc; uint32_t desc_index; #define GPMI_ASYNC_EDO_ENABLED (1 << 0) @@ -246,16 +118,16 @@ static inline int mxs_nand_is_imx6(struct mxs_nand_info *info) return info->type == GPMI_IMX6; } -static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info) +static struct mxs_dma_cmd *mxs_nand_get_dma_desc(struct mxs_nand_info *info) { - struct mxs_dma_desc *desc; + struct mxs_dma_cmd *desc; if (info->desc_index >= MXS_NAND_DMA_DESCRIPTOR_COUNT) { printf("MXS NAND: Too many DMA descriptors requested\n"); return NULL; } - desc = info->desc[info->desc_index]; + desc = &info->desc[info->desc_index]; info->desc_index++; return desc; @@ -264,12 +136,11 @@ static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info) static void mxs_nand_return_dma_descs(struct mxs_nand_info *info) { int i; - struct mxs_dma_desc *desc; + struct mxs_dma_cmd *desc; for (i = 0; i < info->desc_index; i++) { - desc = info->desc[i]; - memset(desc, 0, sizeof(struct mxs_dma_desc)); - desc->address = (dma_addr_t)desc; + desc = &info->desc[i]; + memset(desc, 0, sizeof(struct mxs_dma_cmd)); } info->desc_index = 0; @@ -452,7 +323,7 @@ static int mxs_nand_wait_for_bch_complete(struct mxs_nand_info *nand_info) static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctrl) { struct mxs_nand_info *nand_info = chip->priv; - struct mxs_dma_desc *d; + struct mxs_dma_cmd *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret; @@ -492,26 +363,24 @@ static void mxs_nand_cmd_ctrl(struct nand_chip *chip, int data, unsigned int ctr /* Compile the DMA descriptor -- a descriptor that sends command. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_CHAIN | MXS_DMA_DESC_DEC_SEM | - MXS_DMA_DESC_WAIT4END | (3 << MXS_DMA_DESC_PIO_WORDS_OFFSET) | - (nand_info->cmd_queue_len << MXS_DMA_DESC_BYTES_OFFSET); + MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(3) | + MXS_DMA_DESC_XFER_COUNT(nand_info->cmd_queue_len); - d->cmd.address = (dma_addr_t)nand_info->cmd_buf; + d->address = (dma_addr_t)nand_info->cmd_buf; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_CLE | GPMI_CTRL0_ADDRESS_INCREMENT | nand_info->cmd_queue_len; - mxs_dma_desc_append(channel, d); - /* Execute the DMA chain. */ - ret = mxs_dma_go(channel); + ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index); if (ret) printf("MXS NAND: Error sending command (%d)\n", ret); @@ -607,7 +476,7 @@ static void mxs_nand_swap_block_mark(struct nand_chip *chip, static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length) { struct mxs_nand_info *nand_info = chip->priv; - struct mxs_dma_desc *d; + struct mxs_dma_cmd *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret; @@ -623,23 +492,21 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length) /* Compile the DMA descriptor - a descriptor that reads data. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_DMA_WRITE | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END | - (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET) | - (length << MXS_DMA_DESC_BYTES_OFFSET); + MXS_DMA_DESC_PIO_WORDS(1) | + MXS_DMA_DESC_XFER_COUNT(length); - d->cmd.address = (dma_addr_t)nand_info->data_buf; + d->address = (dma_addr_t)nand_info->data_buf; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA | length; - mxs_dma_desc_append(channel, d); - /* * A DMA descriptor that waits for the command to end and the chip to * become ready. @@ -649,23 +516,21 @@ static void mxs_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int length) * did that and no one has re-thought it yet. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_DEC_SEM | - MXS_DMA_DESC_WAIT4END | (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(4); - d->cmd.address = 0; + d->address = 0; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA; - mxs_dma_desc_append(channel, d); - /* Execute the DMA chain. */ - ret = mxs_dma_go(channel); + ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index); if (ret) { printf("MXS NAND: DMA read error\n"); goto rtn; @@ -684,7 +549,7 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf, int length) { struct mxs_nand_info *nand_info = chip->priv; - struct mxs_dma_desc *d; + struct mxs_dma_cmd *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret; @@ -702,25 +567,23 @@ static void mxs_nand_write_buf(struct nand_chip *chip, const uint8_t *buf, /* Compile the DMA descriptor - a descriptor that writes data. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END | - (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET) | - (length << MXS_DMA_DESC_BYTES_OFFSET); + MXS_DMA_DESC_PIO_WORDS(4) | + MXS_DMA_DESC_XFER_COUNT(length); - d->cmd.address = (dma_addr_t)nand_info->data_buf; + d->address = (dma_addr_t)nand_info->data_buf; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA | length; - mxs_dma_desc_append(channel, d); - /* Execute the DMA chain. */ - ret = mxs_dma_go(channel); + ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index); if (ret) printf("MXS NAND: DMA write error\n"); @@ -749,16 +612,22 @@ static void mxs_nand_config_bch(struct nand_chip *chip, int readlen) else chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE; - fl0 = (mxs_nand_ecc_chunk_cnt(readlen) - 1) - << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; - fl0 |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; - fl0 |= (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET; - fl0 |= chunk_size; + fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, mxs_nand_ecc_chunk_cnt(readlen) - 1); + fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, MXS_NAND_METADATA_SIZE); + if (mxs_nand_is_imx6(nand_info)) + fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, chip->ecc.strength >> 1); + else + fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_ECC0, chip->ecc.strength >> 1); + fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, chunk_size); writel(fl0, bch_regs + BCH_FLASH0LAYOUT0); - fl1 = readlen << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; - fl1 |= (chip->ecc.strength >> 1) << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET; - fl1 |= chunk_size; + fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, readlen); + if (mxs_nand_is_imx6(nand_info)) + fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, chip->ecc.strength >> 1); + else + fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_ECCN, chip->ecc.strength >> 1); + + fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, chunk_size); writel(fl1, bch_regs + BCH_FLASH0LAYOUT1); } @@ -766,89 +635,81 @@ static int mxs_nand_do_bch_read(struct nand_chip *chip, int channel, int readtot bool randomizer, int page) { struct mxs_nand_info *nand_info = chip->priv; - struct mxs_dma_desc *d; + struct mxs_dma_cmd *d; int ret; /* Compile the DMA descriptor - wait for ready. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN | MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END | - (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_PIO_WORDS(1); - d->cmd.address = 0; + d->address = 0; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA; - mxs_dma_desc_append(channel, d); - /* Compile the DMA descriptor - enable the BCH block and read. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN | - MXS_DMA_DESC_WAIT4END | (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_WAIT4END | MXS_DMA_DESC_PIO_WORDS(6); - d->cmd.address = 0; + d->address = 0; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_READ | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA | readtotal; - d->cmd.pio_words[1] = 0; - d->cmd.pio_words[2] = + d->pio_words[1] = 0; + d->pio_words[2] = GPMI_ECCCTRL_ENABLE_ECC | GPMI_ECCCTRL_ECC_CMD_DECODE | GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE; - d->cmd.pio_words[3] = readtotal; - d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; - d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; + d->pio_words[3] = readtotal; + d->pio_words[4] = (dma_addr_t)nand_info->data_buf; + d->pio_words[5] = (dma_addr_t)nand_info->oob_buf; if (randomizer) { - d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | + d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | GPMI_ECCCTRL_RANDOMIZER_TYPE2; - d->cmd.pio_words[3] |= (page % 256) << 16; + d->pio_words[3] |= (page % 256) << 16; } - mxs_dma_desc_append(channel, d); - /* Compile the DMA descriptor - disable the BCH block. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN | MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END | - (3 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_PIO_WORDS(3); - d->cmd.address = 0; + d->address = 0; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA | readtotal; - d->cmd.pio_words[1] = 0; - d->cmd.pio_words[2] = 0; - - mxs_dma_desc_append(channel, d); + d->pio_words[1] = 0; + d->pio_words[2] = 0; /* Compile the DMA descriptor - deassert the NAND lock and interrupt. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; - d->cmd.address = 0; - - mxs_dma_desc_append(channel, d); + d->address = 0; /* Execute the DMA chain. */ - ret = mxs_dma_go(channel); + ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index); if (ret) { dev_err(nand_info->dev, "MXS NAND: DMA read error (ecc)\n"); goto out; @@ -1013,7 +874,7 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf, { struct mtd_info *mtd = nand_to_mtd(chip); struct mxs_nand_info *nand_info = chip->priv; - struct mxs_dma_desc *d; + struct mxs_dma_cmd *d; uint32_t channel = nand_info->dma_channel_base + nand_info->cur_chip; int ret = 0; @@ -1027,31 +888,29 @@ static int mxs_nand_ecc_write_page(struct nand_chip *chip, const uint8_t *buf, /* Compile the DMA descriptor - write data. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END | - (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_PIO_WORDS(6); - d->cmd.address = 0; + d->address = 0; - d->cmd.pio_words[0] = + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | - (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) | + FIELD_PREP(GPMI_CTRL0_CS, nand_info->cur_chip) | GPMI_CTRL0_ADDRESS_NAND_DATA; - d->cmd.pio_words[1] = 0; - d->cmd.pio_words[2] = + d->pio_words[1] = 0; + d->pio_words[2] = GPMI_ECCCTRL_ENABLE_ECC | GPMI_ECCCTRL_ECC_CMD_ENCODE | GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE; - d->cmd.pio_words[3] = (mtd->writesize + mtd->oobsize); - d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; - d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; - - mxs_dma_desc_append(channel, d); + d->pio_words[3] = (mtd->writesize + mtd->oobsize); + d->pio_words[4] = (dma_addr_t)nand_info->data_buf; + d->pio_words[5] = (dma_addr_t)nand_info->oob_buf; /* Execute the DMA chain. */ - ret = mxs_dma_go(channel); + ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index); if (ret) { printf("MXS NAND: DMA write error\n"); goto rtn; @@ -1264,38 +1123,6 @@ static int mxs_nand_block_markbad(struct nand_chip *chip , loff_t ofs) return 0; } -#define BCH62_WRITESIZE 1024 -#define BCH62_OOBSIZE 838 -#define BCH62_PAGESIZE (BCH62_WRITESIZE + BCH62_OOBSIZE) - -static void mxs_nand_mode_fcb_62bit(struct mxs_nand_info *nand_info) -{ - void __iomem *bch_regs; - u32 fl0, fl1; - - bch_regs = nand_info->bch_base; - - /* 8 ecc_chunks */ - fl0 = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; - /* 32 bytes for metadata */ - fl0 |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; - /* using ECC62 level to be performed */ - fl0 |= 0x1F << IMX6_BCH_FLASHLAYOUT0_ECC0_OFFSET; - /* 0x20 * 4 bytes of the data0 block */ - fl0 |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET; - fl0 |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; - writel(fl0, bch_regs + BCH_FLASH0LAYOUT0); - - /* 1024 for data + 838 for OOB */ - fl1 = BCH62_PAGESIZE << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; - /* using ECC62 level to be performed */ - fl1 |= 0x1f << IMX6_BCH_FLASHLAYOUT1_ECCN_OFFSET; - /* 0x20 * 4 bytes of the data0 block */ - fl1 |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET; - fl1 |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; - writel(fl1, bch_regs + BCH_FLASH0LAYOUT1); -} - int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size) { struct nand_chip *chip; @@ -1317,7 +1144,7 @@ int mxs_nand_read_fcb_bch62(unsigned int block, void *buf, size_t size) page = block * (mtd->erasesize / mtd->writesize); - mxs_nand_mode_fcb_62bit(nand_info); + mxs_nand_mode_fcb_62bit(nand_info->bch_base); nand_read_page_op(chip, page, 0, NULL, 0); @@ -1366,7 +1193,7 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size) struct nand_chip *chip; struct mtd_info *mtd = mxs_nand_mtd; struct mxs_nand_info *nand_info; - struct mxs_dma_desc *d; + struct mxs_dma_cmd *d; uint32_t channel; int ret = 0; int page; @@ -1381,7 +1208,7 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size) nand_info = chip->priv; channel = nand_info->dma_channel_base; - mxs_nand_mode_fcb_62bit(nand_info); + mxs_nand_mode_fcb_62bit(nand_info->bch_base); nand_select_target(chip, 0); @@ -1397,24 +1224,24 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size) /* Compile the DMA descriptor - write data. */ d = mxs_nand_get_dma_desc(nand_info); - d->cmd.data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ | + d->data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END | - (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET); + MXS_DMA_DESC_PIO_WORDS(6); - d->cmd.address = 0; + d->address = 0; - d->cmd.pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | + d->pio_words[0] = GPMI_CTRL0_COMMAND_MODE_WRITE | GPMI_CTRL0_WORD_LENGTH | GPMI_CTRL0_ADDRESS_NAND_DATA; - d->cmd.pio_words[1] = 0; - d->cmd.pio_words[2] = GPMI_ECCCTRL_ENABLE_ECC | + d->pio_words[1] = 0; + d->pio_words[2] = GPMI_ECCCTRL_ENABLE_ECC | GPMI_ECCCTRL_ECC_CMD_ENCODE | GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE; - d->cmd.pio_words[3] = BCH62_PAGESIZE; - d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; - d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; + d->pio_words[3] = BCH62_PAGESIZE; + d->pio_words[4] = (dma_addr_t)nand_info->data_buf; + d->pio_words[5] = (dma_addr_t)nand_info->oob_buf; - d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | + d->pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | GPMI_ECCCTRL_RANDOMIZER_TYPE2; /* * Write NAND page number needed to be randomized @@ -1423,12 +1250,10 @@ int mxs_nand_write_fcb_bch62(unsigned int block, void *buf, size_t size) * The value is between 0-255. For additional details * check 9.6.6.4 of i.MX7D Applications Processor reference */ - d->cmd.pio_words[3] |= (page % 256) << 16; - - mxs_dma_desc_append(channel, d); + d->pio_words[3] |= (page % 256) << 16; /* Execute the DMA chain. */ - ret = mxs_dma_go(channel); + ret = mxs_dma_go(channel, nand_info->desc, nand_info->desc_index); if (ret) { dev_err(nand_info->dev, "MXS NAND: DMA write error: %d\n", ret); goto out; @@ -1540,20 +1365,13 @@ static int mxs_nand_hw_init(struct mxs_nand_info *info) { void __iomem *gpmi_regs = info->io_base; void __iomem *bch_regs = info->bch_base; - int i = 0, ret; + int ret; u32 val; - info->desc = malloc(sizeof(struct mxs_dma_desc *) * - MXS_NAND_DMA_DESCRIPTOR_COUNT); + info->desc = dma_alloc_coherent(sizeof(struct mxs_dma_cmd) * MXS_NAND_DMA_DESCRIPTOR_COUNT, + DMA_ADDRESS_BROKEN); if (!info->desc) - goto err1; - - /* Allocate the DMA descriptors. */ - for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) { - info->desc[i] = mxs_dma_desc_alloc(); - if (!info->desc[i]) - goto err2; - } + return -ENOMEM; /* Reset the GPMI block. */ ret = stmp_reset_block(gpmi_regs + GPMI_CTRL0, 0); @@ -1580,14 +1398,6 @@ static int mxs_nand_hw_init(struct mxs_nand_info *info) writel(val, gpmi_regs + GPMI_CTRL1); return 0; - -err2: - free(info->desc); -err1: - for (--i; i >= 0; i--) - mxs_dma_desc_free(info->desc[i]); - printf("MXS NAND: Unable to allocate DMA descriptors\n"); - return -ENOMEM; } static void mxs_nand_probe_dt(struct device_d *dev, struct mxs_nand_info *nand_info) diff --git a/drivers/mtd/peb.c b/drivers/mtd/peb.c index 8443ed86bc..a17d42885e 100644 --- a/drivers/mtd/peb.c +++ b/drivers/mtd/peb.c @@ -205,10 +205,12 @@ int mtd_peb_read(struct mtd_info *mtd, void *buf, int pnum, int offset, return -EINVAL; if (offset < 0 || offset + len > mtd->erasesize) return -EINVAL; - if (len <= 0) + if (len < 0) return -EINVAL; if (mtd_peb_is_bad(mtd, pnum)) return -EINVAL; + if (!len) + return 0; /* Deliberately corrupt the buffer */ *((uint8_t *)buf) ^= 0xFF; @@ -388,12 +390,14 @@ int mtd_peb_write(struct mtd_info *mtd, const void *buf, int pnum, int offset, return -EINVAL; if (offset < 0 || offset + len > mtd->erasesize) return -EINVAL; - if (len <= 0) + if (len < 0) return -EINVAL; if (len % (mtd->writesize >> mtd->subpage_sft)) return -EINVAL; if (mtd_peb_is_bad(mtd, pnum)) return -EINVAL; + if (!len) + return 0; if (mtd_peb_emulate_write_failure()) { dev_err(&mtd->dev, "Cannot write %d bytes to PEB %d:%d (emulated)\n", diff --git a/drivers/net/bcmgenet.c b/drivers/net/bcmgenet.c index 73c1590518..8df5fd5dea 100644 --- a/drivers/net/bcmgenet.c +++ b/drivers/net/bcmgenet.c @@ -215,15 +215,6 @@ static void bcmgenet_umac_reset(struct bcmgenet_eth_priv *priv) writel(1, (priv->mac_reg + RBUF_TBUF_SIZE_CTRL)); } -static int bcmgenet_set_hwaddr(struct eth_device *dev, const unsigned char *addr) -{ - struct bcmgenet_eth_priv *priv = dev->priv; - - memcpy(priv->addr, addr, 6); - - return 0; -} - static int __bcmgenet_set_hwaddr(struct bcmgenet_eth_priv *priv) { const unsigned char *addr = priv->addr; @@ -238,6 +229,17 @@ static int __bcmgenet_set_hwaddr(struct bcmgenet_eth_priv *priv) return 0; } +static int bcmgenet_set_hwaddr(struct eth_device *dev, const unsigned char *addr) +{ + struct bcmgenet_eth_priv *priv = dev->priv; + + memcpy(priv->addr, addr, 6); + + __bcmgenet_set_hwaddr(priv); + + return 0; +} + static int bcmgenet_get_hwaddr(struct eth_device *edev, unsigned char *mac) { return -1; @@ -577,6 +579,8 @@ static int bcmgenet_probe(struct device_d *dev) priv->miibus.priv = priv; priv->miibus.parent = dev; + priv->miibus.dev.device_node + = of_get_compatible_child(dev->device_node, "brcm,genet-mdio-v5"); ret = mdiobus_register(&priv->miibus); if (ret) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 8e07bdb501..fded8b6f4b 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -526,7 +526,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, int rc; rc = nvmem->bus->read(nvmem->priv, cell->offset, buf, cell->bytes); - if (rc) + if (rc < 0) return rc; /* shift bits in-place */ @@ -561,7 +561,7 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) return ERR_PTR(-ENOMEM); rc = __nvmem_cell_read(nvmem, cell, buf, len); - if (rc) { + if (rc < 0) { kfree(buf); return ERR_PTR(rc); } @@ -591,7 +591,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, /* setup the first byte with lsb bits from nvmem */ rc = nvmem->bus->read(nvmem->priv, cell->offset, &v, 1); - if (rc) + if (rc < 0) return ERR_PTR(rc); *b++ |= GENMASK(bit_offset - 1, 0) & v; @@ -612,7 +612,7 @@ static inline void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, /* setup the last byte with msb bits from nvmem */ rc = nvmem->bus->read(nvmem->priv, cell->offset + cell->bytes - 1, &v, 1); - if (rc) + if (rc < 0) return ERR_PTR(rc); *p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v; @@ -652,7 +652,7 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) if (cell->bit_offset || cell->nbits) kfree(buf); - if (rc) + if (rc < 0) return rc; return len; @@ -680,11 +680,11 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem, return -EINVAL; rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell); - if (rc) + if (rc < 0) return rc; rc = __nvmem_cell_read(nvmem, &cell, buf, &len); - if (rc) + if (rc < 0) return rc; return len; @@ -710,7 +710,7 @@ int nvmem_device_cell_write(struct nvmem_device *nvmem, return -EINVAL; rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell); - if (rc) + if (rc < 0) return rc; return nvmem_cell_write(&cell, buf, cell.bytes); @@ -744,7 +744,7 @@ int nvmem_device_read(struct nvmem_device *nvmem, return 0; rc = nvmem->bus->read(nvmem->priv, offset, buf, bytes); - if (rc) + if (rc < 0) return rc; return bytes; @@ -777,7 +777,7 @@ int nvmem_device_write(struct nvmem_device *nvmem, return 0; rc = nvmem->bus->write(nvmem->priv, offset, buf, bytes); - if (rc) + if (rc < 0) return rc; diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 39eadbd3eb..f8bc31f354 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -526,19 +526,6 @@ static struct rk_regulator_cfg rk809_reg[] = { .enable_mask = ENABLE_MASK(RK817_ID_DCDC4), .enable_val = ENABLE_MASK(RK817_ID_DCDC4), .disable_val = DISABLE_VAL(RK817_ID_DCDC4), - }}, {{ - /* .name = "DCDC_REG5", */ - .supply_name = "vcc9", - .ops = &rk809_buck5_ops_range, - .n_voltages = RK809_BUCK5_SEL_CNT, - .linear_ranges = rk809_buck5_voltage_ranges, - .n_linear_ranges = ARRAY_SIZE(rk809_buck5_voltage_ranges), - .vsel_reg = RK809_BUCK5_CONFIG(0), - .vsel_mask = RK809_BUCK5_VSEL_MASK, - .enable_reg = RK817_POWER_EN_REG(3), - .enable_mask = ENABLE_MASK(1), - .enable_val = ENABLE_MASK(1), - .disable_val = DISABLE_VAL(1), }}, RK817_DESC(/* "LDO_REG1", */ "vcc5", 600, 3400, 25, RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK, @@ -576,6 +563,20 @@ static struct rk_regulator_cfg rk809_reg[] = { RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK, RK817_POWER_EN_REG(3), ENABLE_MASK(0), DISABLE_VAL(0), 400), + {{ + /* .name = "DCDC_REG5", */ + .supply_name = "vcc9", + .ops = &rk809_buck5_ops_range, + .n_voltages = RK809_BUCK5_SEL_CNT, + .linear_ranges = rk809_buck5_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk809_buck5_voltage_ranges), + .vsel_reg = RK809_BUCK5_CONFIG(0), + .vsel_mask = RK809_BUCK5_VSEL_MASK, + .enable_reg = RK817_POWER_EN_REG(3), + .enable_mask = ENABLE_MASK(1), + .enable_val = ENABLE_MASK(1), + .disable_val = DISABLE_VAL(1), + }}, RK817_DESC_SWITCH(/* "SWITCH_REG1", */ "vcc9", RK817_POWER_EN_REG(3), ENABLE_MASK(2), DISABLE_VAL(2)), RK817_DESC_SWITCH(/* "SWITCH_REG2", */ "vcc8", diff --git a/dts/Bindings/clock/samsung,exynosautov9-clock.yaml b/dts/Bindings/clock/samsung,exynosautov9-clock.yaml index 2ab4642679..55c4f94a14 100644 --- a/dts/Bindings/clock/samsung,exynosautov9-clock.yaml +++ b/dts/Bindings/clock/samsung,exynosautov9-clock.yaml @@ -148,7 +148,7 @@ allOf: items: - const: oscclk - const: dout_clkcmu_fsys1_bus - - const: dout_clkcmu_fsys1_mmc_card + - const: gout_clkcmu_fsys1_mmc_card - const: dout_clkcmu_fsys1_usbdrd - if: diff --git a/dts/Bindings/hwlock/qcom-hwspinlock.yaml b/dts/Bindings/hwlock/qcom-hwspinlock.yaml index 1c7149f7d1..ee2726149c 100644 --- a/dts/Bindings/hwlock/qcom-hwspinlock.yaml +++ b/dts/Bindings/hwlock/qcom-hwspinlock.yaml @@ -15,9 +15,22 @@ description: properties: compatible: - enum: - - qcom,sfpb-mutex - - qcom,tcsr-mutex + oneOf: + - enum: + - qcom,sfpb-mutex + - qcom,tcsr-mutex + - items: + - enum: + - qcom,apq8084-tcsr-mutex + - qcom,ipq6018-tcsr-mutex + - qcom,msm8226-tcsr-mutex + - qcom,msm8994-tcsr-mutex + - const: qcom,tcsr-mutex + - items: + - enum: + - qcom,msm8974-tcsr-mutex + - const: qcom,tcsr-mutex + - const: syscon reg: maxItems: 1 @@ -34,9 +47,9 @@ additionalProperties: false examples: - | - tcsr_mutex: hwlock@1f40000 { - compatible = "qcom,tcsr-mutex"; - reg = <0x01f40000 0x40000>; - #hwlock-cells = <1>; - }; + hwlock@1f40000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x01f40000 0x40000>; + #hwlock-cells = <1>; + }; ... diff --git a/dts/Bindings/iio/adc/aspeed,ast2600-adc.yaml b/dts/Bindings/iio/adc/aspeed,ast2600-adc.yaml index b283c8ca2b..5c08d8b6e9 100644 --- a/dts/Bindings/iio/adc/aspeed,ast2600-adc.yaml +++ b/dts/Bindings/iio/adc/aspeed,ast2600-adc.yaml @@ -62,13 +62,6 @@ properties: description: Inform the driver that last channel will be used to sensor battery. - aspeed,trim-data-valid: - type: boolean - description: | - The ADC reference voltage can be calibrated to obtain the trimming - data which will be stored in otp. This property informs the driver that - the data store in the otp is valid. - required: - compatible - reg diff --git a/dts/Bindings/input/goodix,gt7375p.yaml b/dts/Bindings/input/goodix,gt7375p.yaml index fe1c5016f7..1c191bc5a1 100644 --- a/dts/Bindings/input/goodix,gt7375p.yaml +++ b/dts/Bindings/input/goodix,gt7375p.yaml @@ -16,8 +16,11 @@ description: properties: compatible: - items: + oneOf: - const: goodix,gt7375p + - items: + - const: goodix,gt7986u + - const: goodix,gt7375p reg: enum: diff --git a/dts/Bindings/interconnect/qcom,msm8998-bwmon.yaml b/dts/Bindings/interconnect/qcom,msm8998-bwmon.yaml index 2684562df4..be29e0b809 100644 --- a/dts/Bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/dts/Bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -24,7 +24,7 @@ properties: oneOf: - items: - enum: - - qcom,sc7280-bwmon + - qcom,sc7280-cpu-bwmon - qcom,sdm845-bwmon - const: qcom,msm8998-bwmon - const: qcom,msm8998-bwmon # BWMON v4 diff --git a/dts/Bindings/media/allwinner,sun50i-h6-vpu-g2.yaml b/dts/Bindings/media/allwinner,sun50i-h6-vpu-g2.yaml index 24d7bf2149..9d44236f2d 100644 --- a/dts/Bindings/media/allwinner,sun50i-h6-vpu-g2.yaml +++ b/dts/Bindings/media/allwinner,sun50i-h6-vpu-g2.yaml @@ -36,6 +36,9 @@ properties: resets: maxItems: 1 + iommus: + maxItems: 1 + required: - compatible - reg @@ -43,6 +46,7 @@ required: - clocks - clock-names - resets + - iommus additionalProperties: false @@ -59,6 +63,7 @@ examples: clocks = <&ccu CLK_BUS_VP9>, <&ccu CLK_VP9>; clock-names = "bus", "mod"; resets = <&ccu RST_BUS_VP9>; + iommus = <&iommu 5>; }; ... diff --git a/dts/Bindings/net/engleder,tsnep.yaml b/dts/Bindings/net/engleder,tsnep.yaml index 5bd964a46a..a6921e805e 100644 --- a/dts/Bindings/net/engleder,tsnep.yaml +++ b/dts/Bindings/net/engleder,tsnep.yaml @@ -47,7 +47,7 @@ properties: nvmem-cells: true - nvmem-cells-names: true + nvmem-cell-names: true phy-connection-type: enum: diff --git a/dts/Bindings/sound/google,cros-ec-codec.yaml b/dts/Bindings/sound/google,cros-ec-codec.yaml index c3e9f34854..dea293f403 100644 --- a/dts/Bindings/sound/google,cros-ec-codec.yaml +++ b/dts/Bindings/sound/google,cros-ec-codec.yaml @@ -8,7 +8,7 @@ title: Audio codec controlled by ChromeOS EC maintainers: - Cheng-Yi Chiang <cychiang@chromium.org> - - Tzung-Bi Shih <tzungbi@google.com> + - Tzung-Bi Shih <tzungbi@kernel.org> description: | Google's ChromeOS EC codec is a digital mic codec provided by the diff --git a/dts/Bindings/sound/realtek,rt1015p.yaml b/dts/Bindings/sound/realtek,rt1015p.yaml index 1d73204451..ea7d4900ee 100644 --- a/dts/Bindings/sound/realtek,rt1015p.yaml +++ b/dts/Bindings/sound/realtek,rt1015p.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Realtek rt1015p codec devicetree bindings maintainers: - - Tzung-Bi Shih <tzungbi@google.com> + - Tzung-Bi Shih <tzungbi@kernel.org> description: | Rt1015p is a rt1015 variant which does not support I2C and diff --git a/dts/src/arm/am335x-pcm-953.dtsi b/dts/src/arm/am335x-pcm-953.dtsi index dae448040a..9474974139 100644 --- a/dts/src/arm/am335x-pcm-953.dtsi +++ b/dts/src/arm/am335x-pcm-953.dtsi @@ -12,22 +12,20 @@ compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx"; /* Power */ - regulators { - vcc3v3: fixedregulator@1 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; + vcc3v3: fixedregulator1 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; - vcc1v8: fixedregulator@2 { - compatible = "regulator-fixed"; - regulator-name = "vcc1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - }; + vcc1v8: fixedregulator2 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; }; /* User IO */ diff --git a/dts/src/arm/at91rm9200.dtsi b/dts/src/arm/at91rm9200.dtsi index 7a113325ab..6f9004ebf4 100644 --- a/dts/src/arm/at91rm9200.dtsi +++ b/dts/src/arm/at91rm9200.dtsi @@ -666,7 +666,7 @@ compatible = "atmel,at91rm9200-udc"; reg = <0xfffb0000 0x4000>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 2>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 1>; clock-names = "pclk", "hclk"; status = "disabled"; }; diff --git a/dts/src/arm/at91sam9g20ek_common.dtsi b/dts/src/arm/at91sam9g20ek_common.dtsi index 60d61291f3..024af2db63 100644 --- a/dts/src/arm/at91sam9g20ek_common.dtsi +++ b/dts/src/arm/at91sam9g20ek_common.dtsi @@ -39,6 +39,13 @@ }; + usb1 { + pinctrl_usb1_vbus_gpio: usb1_vbus_gpio { + atmel,pins = + <AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PC5 GPIO */ + }; + }; + mmc0_slot1 { pinctrl_board_mmc0_slot1: mmc0_slot1-board { atmel,pins = @@ -84,6 +91,8 @@ }; usb1: gadget@fffa4000 { + pinctrl-0 = <&pinctrl_usb1_vbus_gpio>; + pinctrl-names = "default"; atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/dts/src/arm/imx6q-prti6q.dts b/dts/src/arm/imx6q-prti6q.dts index b4605edfd2..d8fa83effd 100644 --- a/dts/src/arm/imx6q-prti6q.dts +++ b/dts/src/arm/imx6q-prti6q.dts @@ -364,8 +364,8 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_wifi>; interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>; - ref-clock-frequency = "38400000"; - tcxo-clock-frequency = "19200000"; + ref-clock-frequency = <38400000>; + tcxo-clock-frequency = <19200000>; }; }; diff --git a/dts/src/arm/imx7s.dtsi b/dts/src/arm/imx7s.dtsi index 0fc9e6b8b0..03d2e8544a 100644 --- a/dts/src/arm/imx7s.dtsi +++ b/dts/src/arm/imx7s.dtsi @@ -1270,10 +1270,10 @@ clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; diff --git a/dts/src/arm/lan966x-pcb8291.dts b/dts/src/arm/lan966x-pcb8291.dts index f4f054cdf2..3a3d76af86 100644 --- a/dts/src/arm/lan966x-pcb8291.dts +++ b/dts/src/arm/lan966x-pcb8291.dts @@ -69,6 +69,12 @@ pins = "GPIO_35", "GPIO_36"; function = "can0_b"; }; + + sgpio_a_pins: sgpio-a-pins { + /* SCK, D0, D1, LD */ + pins = "GPIO_32", "GPIO_33", "GPIO_34", "GPIO_35"; + function = "sgpio_a"; + }; }; &can0 { @@ -118,6 +124,20 @@ status = "okay"; }; +&sgpio { + pinctrl-0 = <&sgpio_a_pins>; + pinctrl-names = "default"; + microchip,sgpio-port-ranges = <0 3>, <8 11>; + status = "okay"; + + gpio@0 { + ngpios = <64>; + }; + gpio@1 { + ngpios = <64>; + }; +}; + &switch { status = "okay"; }; diff --git a/dts/src/arm/rk3036-evb.dts b/dts/src/arm/rk3036-evb.dts index 9fd4d9db9f..becdc0b664 100644 --- a/dts/src/arm/rk3036-evb.dts +++ b/dts/src/arm/rk3036-evb.dts @@ -35,11 +35,10 @@ &i2c1 { status = "okay"; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; }; }; diff --git a/dts/src/arm/rk3066a-mk808.dts b/dts/src/arm/rk3066a-mk808.dts index cfa318a506..2db5ba7062 100644 --- a/dts/src/arm/rk3066a-mk808.dts +++ b/dts/src/arm/rk3066a-mk808.dts @@ -32,7 +32,7 @@ keyup-threshold-microvolt = <2500000>; poll-interval = <100>; - recovery { + button-recovery { label = "recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <0>; diff --git a/dts/src/arm/rk3188-radxarock.dts b/dts/src/arm/rk3188-radxarock.dts index e7cf188235..118deacd38 100644 --- a/dts/src/arm/rk3188-radxarock.dts +++ b/dts/src/arm/rk3188-radxarock.dts @@ -71,7 +71,7 @@ #sound-dai-cells = <0>; }; - ir_recv: gpio-ir-receiver { + ir_recv: ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; diff --git a/dts/src/arm/rk3188.dtsi b/dts/src/arm/rk3188.dtsi index cdd4a0bd51..44b54af0bb 100644 --- a/dts/src/arm/rk3188.dtsi +++ b/dts/src/arm/rk3188.dtsi @@ -379,7 +379,7 @@ rockchip,pins = <2 RK_PD3 1 &pcfg_pull_none>; }; - lcdc1_rgb24: ldcd1-rgb24 { + lcdc1_rgb24: lcdc1-rgb24 { rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>, <2 RK_PA1 1 &pcfg_pull_none>, <2 RK_PA2 1 &pcfg_pull_none>, @@ -607,7 +607,6 @@ &global_timer { interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; - status = "disabled"; }; &local_timer { diff --git a/dts/src/arm/rk3288-evb-act8846.dts b/dts/src/arm/rk3288-evb-act8846.dts index be695b8c1f..8a635c2431 100644 --- a/dts/src/arm/rk3288-evb-act8846.dts +++ b/dts/src/arm/rk3288-evb-act8846.dts @@ -54,7 +54,7 @@ vin-supply = <&vcc_sys>; }; - hym8563@51 { + rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; diff --git a/dts/src/arm/rk3288-evb.dtsi b/dts/src/arm/rk3288-evb.dtsi index 399d6b9c5f..382d2839cf 100644 --- a/dts/src/arm/rk3288-evb.dtsi +++ b/dts/src/arm/rk3288-evb.dtsi @@ -28,19 +28,19 @@ press-threshold-microvolt = <300000>; }; - menu { + button-menu { label = "Menu"; linux,code = <KEY_MENU>; press-threshold-microvolt = <640000>; }; - esc { + button-esc { label = "Esc"; linux,code = <KEY_ESC>; press-threshold-microvolt = <1000000>; }; - home { + button-home { label = "Home"; linux,code = <KEY_HOME>; press-threshold-microvolt = <1300000>; diff --git a/dts/src/arm/rk3288-firefly.dtsi b/dts/src/arm/rk3288-firefly.dtsi index 052afe5543..3836c61cfb 100644 --- a/dts/src/arm/rk3288-firefly.dtsi +++ b/dts/src/arm/rk3288-firefly.dtsi @@ -233,11 +233,10 @@ vin-supply = <&vcc_sys>; }; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; interrupt-parent = <&gpio7>; interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>; diff --git a/dts/src/arm/rk3288-miqi.dts b/dts/src/arm/rk3288-miqi.dts index 713f55e143..db1eb648e0 100644 --- a/dts/src/arm/rk3288-miqi.dts +++ b/dts/src/arm/rk3288-miqi.dts @@ -162,11 +162,10 @@ vin-supply = <&vcc_sys>; }; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; }; diff --git a/dts/src/arm/rk3288-rock2-square.dts b/dts/src/arm/rk3288-rock2-square.dts index 80e0f07c8e..13cfdaa95c 100644 --- a/dts/src/arm/rk3288-rock2-square.dts +++ b/dts/src/arm/rk3288-rock2-square.dts @@ -165,11 +165,10 @@ }; &i2c0 { - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; interrupt-parent = <&gpio0>; interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>; diff --git a/dts/src/arm/rk3288-vmarc-som.dtsi b/dts/src/arm/rk3288-vmarc-som.dtsi index 0ae2bd150e..793951655b 100644 --- a/dts/src/arm/rk3288-vmarc-som.dtsi +++ b/dts/src/arm/rk3288-vmarc-som.dtsi @@ -241,7 +241,6 @@ interrupt-parent = <&gpio5>; interrupts = <RK_PC3 IRQ_TYPE_LEVEL_LOW>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "hym8563"; pinctrl-names = "default"; pinctrl-0 = <&hym8563_int>; diff --git a/dts/src/arm/rk3xxx.dtsi b/dts/src/arm/rk3xxx.dtsi index bf285091a9..cb4e42ede5 100644 --- a/dts/src/arm/rk3xxx.dtsi +++ b/dts/src/arm/rk3xxx.dtsi @@ -76,6 +76,13 @@ reg = <0x1013c200 0x20>; interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>; clocks = <&cru CORE_PERI>; + status = "disabled"; + /* The clock source and the sched_clock provided by the arm_global_timer + * on Rockchip rk3066a/rk3188 are quite unstable because their rates + * depend on the CPU frequency. + * Keep the arm_global_timer disabled in order to have the + * DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default. + */ }; local_timer: local-timer@1013c600 { diff --git a/dts/src/arm/sama7g5-pinfunc.h b/dts/src/arm/sama7g5-pinfunc.h index 4eb30445d2..6e87f0d4b8 100644 --- a/dts/src/arm/sama7g5-pinfunc.h +++ b/dts/src/arm/sama7g5-pinfunc.h @@ -261,7 +261,7 @@ #define PIN_PB2__FLEXCOM6_IO0 PINMUX_PIN(PIN_PB2, 2, 1) #define PIN_PB2__ADTRG PINMUX_PIN(PIN_PB2, 3, 1) #define PIN_PB2__A20 PINMUX_PIN(PIN_PB2, 4, 1) -#define PIN_PB2__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB2, 6, 3) +#define PIN_PB2__FLEXCOM11_IO1 PINMUX_PIN(PIN_PB2, 6, 3) #define PIN_PB3 35 #define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0) #define PIN_PB3__RF1 PINMUX_PIN(PIN_PB3, 1, 1) diff --git a/dts/src/arm64/allwinner/sun50i-h6.dtsi b/dts/src/arm64/allwinner/sun50i-h6.dtsi index 53f6660656..ca1d287a0a 100644 --- a/dts/src/arm64/allwinner/sun50i-h6.dtsi +++ b/dts/src/arm64/allwinner/sun50i-h6.dtsi @@ -161,6 +161,7 @@ clocks = <&ccu CLK_BUS_VP9>, <&ccu CLK_VP9>; clock-names = "bus", "mod"; resets = <&ccu RST_BUS_VP9>; + iommus = <&iommu 5>; }; video-codec@1c0e000 { diff --git a/dts/src/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts b/dts/src/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts index 7e0aeb2db3..a0aeac6199 100644 --- a/dts/src/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts +++ b/dts/src/arm64/freescale/imx8mm-tqma8mqml-mba8mx.dts @@ -34,11 +34,25 @@ off-on-delay-us = <12000>; }; - extcon_usbotg1: extcon-usbotg1 { - compatible = "linux,extcon-usb-gpio"; + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + type = "micro"; + label = "X19"; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usb1_extcon>; - id-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pinctrl_usb1_connector>; + id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usb_dr_connector: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + }; }; }; @@ -105,13 +119,19 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg1>; dr_mode = "otg"; - extcon = <&extcon_usbotg1>; srp-disable; hnp-disable; adp-disable; power-active-high; over-current-active-low; + usb-role-switch; status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&usb_dr_connector>; + }; + }; }; &usbotg2 { @@ -231,7 +251,7 @@ <MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x84>; }; - pinctrl_usb1_extcon: usb1-extcongrp { + pinctrl_usb1_connector: usb1-connectorgrp { fsl,pins = <MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x1c0>; }; diff --git a/dts/src/arm64/freescale/imx8mm.dtsi b/dts/src/arm64/freescale/imx8mm.dtsi index dabd94dc30..50ef92915c 100644 --- a/dts/src/arm64/freescale/imx8mm.dtsi +++ b/dts/src/arm64/freescale/imx8mm.dtsi @@ -1244,10 +1244,10 @@ clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; diff --git a/dts/src/arm64/freescale/imx8mn.dtsi b/dts/src/arm64/freescale/imx8mn.dtsi index ad0b99adf6..67b554ba69 100644 --- a/dts/src/arm64/freescale/imx8mn.dtsi +++ b/dts/src/arm64/freescale/imx8mn.dtsi @@ -1102,7 +1102,7 @@ gpmi: nand-controller@33002000 { compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; diff --git a/dts/src/arm64/freescale/imx8mp-evk.dts b/dts/src/arm64/freescale/imx8mp-evk.dts index 9f1469db55..b4c1ef2559 100644 --- a/dts/src/arm64/freescale/imx8mp-evk.dts +++ b/dts/src/arm64/freescale/imx8mp-evk.dts @@ -544,14 +544,14 @@ pinctrl_pcie0: pcie0grp { fsl,pins = < - MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x61 /* open drain, pull up */ - MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x41 + MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x60 /* open drain, pull up */ + MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x40 >; }; pinctrl_pcie0_reg: pcie0reggrp { fsl,pins = < - MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x41 + MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x40 >; }; diff --git a/dts/src/arm64/freescale/imx93-pinfunc.h b/dts/src/arm64/freescale/imx93-pinfunc.h index 4298a145f8..4298a145f8 100755..100644 --- a/dts/src/arm64/freescale/imx93-pinfunc.h +++ b/dts/src/arm64/freescale/imx93-pinfunc.h diff --git a/dts/src/arm64/qcom/ipq8074.dtsi b/dts/src/arm64/qcom/ipq8074.dtsi index a47acf9bdf..a721cdd804 100644 --- a/dts/src/arm64/qcom/ipq8074.dtsi +++ b/dts/src/arm64/qcom/ipq8074.dtsi @@ -668,7 +668,7 @@ apcs_glb: mailbox@b111000 { compatible = "qcom,ipq8074-apcs-apps-global"; - reg = <0x0b111000 0x6000>; + reg = <0x0b111000 0x1000>; #clock-cells = <1>; #mbox-cells = <1>; diff --git a/dts/src/arm64/qcom/msm8996.dtsi b/dts/src/arm64/qcom/msm8996.dtsi index c0a2baffa4..aba7176443 100644 --- a/dts/src/arm64/qcom/msm8996.dtsi +++ b/dts/src/arm64/qcom/msm8996.dtsi @@ -3504,7 +3504,7 @@ }; saw3: syscon@9a10000 { - compatible = "qcom,tcsr-msm8996", "syscon"; + compatible = "syscon"; reg = <0x09a10000 0x1000>; }; diff --git a/dts/src/arm64/qcom/sa8155p-adp.dts b/dts/src/arm64/qcom/sa8155p-adp.dts index 87ab0e1ecd..4dee790f10 100644 --- a/dts/src/arm64/qcom/sa8155p-adp.dts +++ b/dts/src/arm64/qcom/sa8155p-adp.dts @@ -43,7 +43,6 @@ regulator-always-on; regulator-boot-on; - regulator-allow-set-load; vin-supply = <&vreg_3p3>; }; @@ -137,6 +136,9 @@ regulator-max-microvolt = <880000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l7a_1p8: ldo7 { @@ -152,6 +154,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l11a_0p8: ldo11 { @@ -258,6 +263,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l7c_1p8: ldo7 { @@ -273,6 +281,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l10c_3p3: ldo10 { diff --git a/dts/src/arm64/qcom/sa8295p-adp.dts b/dts/src/arm64/qcom/sa8295p-adp.dts index b608b82dff..2c62ba6a49 100644 --- a/dts/src/arm64/qcom/sa8295p-adp.dts +++ b/dts/src/arm64/qcom/sa8295p-adp.dts @@ -83,6 +83,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l4c: ldo4 { @@ -98,6 +101,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l7c: ldo7 { @@ -113,6 +119,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l17c: ldo17 { @@ -121,6 +130,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; }; diff --git a/dts/src/arm64/qcom/sc7280.dtsi b/dts/src/arm64/qcom/sc7280.dtsi index 212580316d..4cdc88d339 100644 --- a/dts/src/arm64/qcom/sc7280.dtsi +++ b/dts/src/arm64/qcom/sc7280.dtsi @@ -2296,7 +2296,8 @@ lpass_audiocc: clock-controller@3300000 { compatible = "qcom,sc7280-lpassaudiocc"; - reg = <0 0x03300000 0 0x30000>; + reg = <0 0x03300000 0 0x30000>, + <0 0x032a9000 0 0x1000>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>; clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src"; diff --git a/dts/src/arm64/qcom/sc8280xp-crd.dts b/dts/src/arm64/qcom/sc8280xp-crd.dts index fea7d8273c..5e30349efd 100644 --- a/dts/src/arm64/qcom/sc8280xp-crd.dts +++ b/dts/src/arm64/qcom/sc8280xp-crd.dts @@ -124,6 +124,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l13c: ldo13 { @@ -146,6 +149,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l4d: ldo4 { diff --git a/dts/src/arm64/qcom/sc8280xp.dtsi b/dts/src/arm64/qcom/sc8280xp.dtsi index c32bcded2a..212d63d5cb 100644 --- a/dts/src/arm64/qcom/sc8280xp.dtsi +++ b/dts/src/arm64/qcom/sc8280xp.dtsi @@ -885,13 +885,13 @@ ufs_mem_phy: phy@1d87000 { compatible = "qcom,sc8280xp-qmp-ufs-phy"; - reg = <0 0x01d87000 0 0xe10>; + reg = <0 0x01d87000 0 0x1c8>; #address-cells = <2>; #size-cells = <2>; ranges; clock-names = "ref", "ref_aux"; - clocks = <&rpmhcc RPMH_CXO_CLK>, + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; resets = <&ufs_mem_hc 0>; @@ -953,13 +953,13 @@ ufs_card_phy: phy@1da7000 { compatible = "qcom,sc8280xp-qmp-ufs-phy"; - reg = <0 0x01da7000 0 0xe10>; + reg = <0 0x01da7000 0 0x1c8>; #address-cells = <2>; #size-cells = <2>; ranges; clock-names = "ref", "ref_aux"; - clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>, + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_CARD_PHY_AUX_CLK>; resets = <&ufs_card_hc 0>; @@ -1181,26 +1181,16 @@ usb_0_ssphy: usb3-phy@88eb400 { reg = <0 0x088eb400 0 0x100>, <0 0x088eb600 0 0x3ec>, - <0 0x088ec400 0 0x1f0>, + <0 0x088ec400 0 0x364>, <0 0x088eba00 0 0x100>, <0 0x088ebc00 0 0x3ec>, - <0 0x088ec700 0 0x64>; + <0 0x088ec200 0 0x18>; #phy-cells = <0>; #clock-cells = <0>; clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; clock-names = "pipe0"; clock-output-names = "usb0_phy_pipe_clk_src"; }; - - usb_0_dpphy: dp-phy@88ed200 { - reg = <0 0x088ed200 0 0x200>, - <0 0x088ed400 0 0x200>, - <0 0x088eda00 0 0x200>, - <0 0x088ea600 0 0x200>, - <0 0x088ea800 0 0x200>; - #clock-cells = <1>; - #phy-cells = <0>; - }; }; usb_1_hsphy: phy@8902000 { @@ -1242,8 +1232,8 @@ usb_1_ssphy: usb3-phy@8903400 { reg = <0 0x08903400 0 0x100>, - <0 0x08903c00 0 0x3ec>, - <0 0x08904400 0 0x1f0>, + <0 0x08903600 0 0x3ec>, + <0 0x08904400 0 0x364>, <0 0x08903a00 0 0x100>, <0 0x08903c00 0 0x3ec>, <0 0x08904200 0 0x18>; @@ -1253,16 +1243,6 @@ clock-names = "pipe0"; clock-output-names = "usb1_phy_pipe_clk_src"; }; - - usb_1_dpphy: dp-phy@8904200 { - reg = <0 0x08904200 0 0x200>, - <0 0x08904400 0 0x200>, - <0 0x08904a00 0 0x200>, - <0 0x08904600 0 0x200>, - <0 0x08904800 0 0x200>; - #clock-cells = <1>; - #phy-cells = <0>; - }; }; system-cache-controller@9200000 { diff --git a/dts/src/arm64/qcom/sm8150-sony-xperia-kumano.dtsi b/dts/src/arm64/qcom/sm8150-sony-xperia-kumano.dtsi index 014fe3a315..fb6e5a140c 100644 --- a/dts/src/arm64/qcom/sm8150-sony-xperia-kumano.dtsi +++ b/dts/src/arm64/qcom/sm8150-sony-xperia-kumano.dtsi @@ -348,6 +348,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l7c_3p0: ldo7 { @@ -367,6 +370,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l10c_3p3: ldo10 { diff --git a/dts/src/arm64/qcom/sm8250-sony-xperia-edo.dtsi b/dts/src/arm64/qcom/sm8250-sony-xperia-edo.dtsi index 549e0a2aa9..5428aab305 100644 --- a/dts/src/arm64/qcom/sm8250-sony-xperia-edo.dtsi +++ b/dts/src/arm64/qcom/sm8250-sony-xperia-edo.dtsi @@ -317,6 +317,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l7c_2p85: ldo7 { @@ -339,6 +342,9 @@ regulator-max-microvolt = <2960000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l10c_3p3: ldo10 { diff --git a/dts/src/arm64/qcom/sm8250.dtsi b/dts/src/arm64/qcom/sm8250.dtsi index a5b62cadb1..e276eed1f8 100644 --- a/dts/src/arm64/qcom/sm8250.dtsi +++ b/dts/src/arm64/qcom/sm8250.dtsi @@ -334,6 +334,7 @@ exit-latency-us = <6562>; min-residency-us = <9987>; local-timer-stop; + status = "disabled"; }; }; }; diff --git a/dts/src/arm64/qcom/sm8350-hdk.dts b/dts/src/arm64/qcom/sm8350-hdk.dts index 0fcf5bd88f..69ae6503c2 100644 --- a/dts/src/arm64/qcom/sm8350-hdk.dts +++ b/dts/src/arm64/qcom/sm8350-hdk.dts @@ -107,6 +107,9 @@ regulator-max-microvolt = <888000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l6b_1p2: ldo6 { @@ -115,6 +118,9 @@ regulator-max-microvolt = <1208000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l7b_2p96: ldo7 { @@ -123,6 +129,9 @@ regulator-max-microvolt = <2504000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; vreg_l9b_1p2: ldo9 { @@ -131,6 +140,9 @@ regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; regulator-allow-set-load; + regulator-allowed-modes = + <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; }; }; diff --git a/dts/src/arm64/rockchip/px30-evb.dts b/dts/src/arm64/rockchip/px30-evb.dts index 07008d8443..c1bbd555f5 100644 --- a/dts/src/arm64/rockchip/px30-evb.dts +++ b/dts/src/arm64/rockchip/px30-evb.dts @@ -30,31 +30,31 @@ keyup-threshold-microvolt = <1800000>; poll-interval = <100>; - esc-key { + button-esc { label = "esc"; linux,code = <KEY_ESC>; press-threshold-microvolt = <1310000>; }; - home-key { + button-home { label = "home"; linux,code = <KEY_HOME>; press-threshold-microvolt = <624000>; }; - menu-key { + button-menu { label = "menu"; linux,code = <KEY_MENU>; press-threshold-microvolt = <987000>; }; - vol-down-key { + button-down { label = "volume down"; linux,code = <KEY_VOLUMEDOWN>; press-threshold-microvolt = <300000>; }; - vol-up-key { + button-up { label = "volume up"; linux,code = <KEY_VOLUMEUP>; press-threshold-microvolt = <17000>; diff --git a/dts/src/arm64/rockchip/rk3308-evb.dts b/dts/src/arm64/rockchip/rk3308-evb.dts index 9fe9b0d110..184b84fdde 100644 --- a/dts/src/arm64/rockchip/rk3308-evb.dts +++ b/dts/src/arm64/rockchip/rk3308-evb.dts @@ -23,7 +23,7 @@ poll-interval = <100>; keyup-threshold-microvolt = <1800000>; - func-key { + button-func { linux,code = <KEY_FN>; label = "function"; press-threshold-microvolt = <18000>; @@ -37,31 +37,31 @@ poll-interval = <100>; keyup-threshold-microvolt = <1800000>; - esc-key { + button-esc { linux,code = <KEY_MICMUTE>; label = "micmute"; press-threshold-microvolt = <1130000>; }; - home-key { + button-home { linux,code = <KEY_MODE>; label = "mode"; press-threshold-microvolt = <901000>; }; - menu-key { + button-menu { linux,code = <KEY_PLAY>; label = "play"; press-threshold-microvolt = <624000>; }; - vol-down-key { + button-down { linux,code = <KEY_VOLUMEDOWN>; label = "volume down"; press-threshold-microvolt = <300000>; }; - vol-up-key { + button-up { linux,code = <KEY_VOLUMEUP>; label = "volume up"; press-threshold-microvolt = <18000>; diff --git a/dts/src/arm64/rockchip/rk3308-roc-cc.dts b/dts/src/arm64/rockchip/rk3308-roc-cc.dts index ea6820902e..7ea4816774 100644 --- a/dts/src/arm64/rockchip/rk3308-roc-cc.dts +++ b/dts/src/arm64/rockchip/rk3308-roc-cc.dts @@ -19,7 +19,7 @@ stdout-path = "serial2:1500000n8"; }; - ir_rx { + ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; diff --git a/dts/src/arm64/rockchip/rk3318-a95x-z2.dts b/dts/src/arm64/rockchip/rk3318-a95x-z2.dts index 43c928ac98..1deef53a4c 100644 --- a/dts/src/arm64/rockchip/rk3318-a95x-z2.dts +++ b/dts/src/arm64/rockchip/rk3318-a95x-z2.dts @@ -25,7 +25,7 @@ keyup-threshold-microvolt = <1800000>; poll-interval = <100>; - recovery { + button-recovery { label = "recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <17000>; diff --git a/dts/src/arm64/rockchip/rk3368-orion-r68-meta.dts b/dts/src/arm64/rockchip/rk3368-orion-r68-meta.dts index 7f5bba0c60..81d1064fdb 100644 --- a/dts/src/arm64/rockchip/rk3368-orion-r68-meta.dts +++ b/dts/src/arm64/rockchip/rk3368-orion-r68-meta.dts @@ -208,11 +208,10 @@ vin-supply = <&vcc_sys>; }; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; /* rtc_int is not connected */ }; diff --git a/dts/src/arm64/rockchip/rk3368-r88.dts b/dts/src/arm64/rockchip/rk3368-r88.dts index 38d757c005..5589f3db6b 100644 --- a/dts/src/arm64/rockchip/rk3368-r88.dts +++ b/dts/src/arm64/rockchip/rk3368-r88.dts @@ -192,11 +192,10 @@ vin-supply = <&vcc_sys>; }; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; /* rtc_int is not connected */ }; diff --git a/dts/src/arm64/rockchip/rk3399-gru-scarlet.dtsi b/dts/src/arm64/rockchip/rk3399-gru-scarlet.dtsi index ed3348b558..a47d9f7586 100644 --- a/dts/src/arm64/rockchip/rk3399-gru-scarlet.dtsi +++ b/dts/src/arm64/rockchip/rk3399-gru-scarlet.dtsi @@ -734,10 +734,6 @@ camera: &i2c7 { }; /* PINCTRL OVERRIDES */ -&ec_ap_int_l { - rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; -}; - &ap_fw_wp { rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; }; diff --git a/dts/src/arm64/rockchip/rk3399-khadas-edge.dtsi b/dts/src/arm64/rockchip/rk3399-khadas-edge.dtsi index 2a332763c3..9d9297bc5f 100644 --- a/dts/src/arm64/rockchip/rk3399-khadas-edge.dtsi +++ b/dts/src/arm64/rockchip/rk3399-khadas-edge.dtsi @@ -123,7 +123,7 @@ keyup-threshold-microvolt = <1800000>; poll-interval = <100>; - recovery { + button-recovery { label = "Recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <18000>; diff --git a/dts/src/arm64/rockchip/rk3399-nanopc-t4.dts b/dts/src/arm64/rockchip/rk3399-nanopc-t4.dts index 452728b82e..3bf8f959e4 100644 --- a/dts/src/arm64/rockchip/rk3399-nanopc-t4.dts +++ b/dts/src/arm64/rockchip/rk3399-nanopc-t4.dts @@ -39,7 +39,7 @@ keyup-threshold-microvolt = <1800000>; poll-interval = <100>; - recovery { + button-recovery { label = "Recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <18000>; diff --git a/dts/src/arm64/rockchip/rk3399-nanopi-m4b.dts b/dts/src/arm64/rockchip/rk3399-nanopi-m4b.dts index 72182c58cc..65cb21837b 100644 --- a/dts/src/arm64/rockchip/rk3399-nanopi-m4b.dts +++ b/dts/src/arm64/rockchip/rk3399-nanopi-m4b.dts @@ -19,7 +19,7 @@ keyup-threshold-microvolt = <1500000>; poll-interval = <100>; - recovery { + button-recovery { label = "Recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <18000>; diff --git a/dts/src/arm64/rockchip/rk3399-nanopi4.dtsi b/dts/src/arm64/rockchip/rk3399-nanopi4.dtsi index 278123b4f9..b6e082f1f6 100644 --- a/dts/src/arm64/rockchip/rk3399-nanopi4.dtsi +++ b/dts/src/arm64/rockchip/rk3399-nanopi4.dtsi @@ -167,6 +167,7 @@ }; &emmc_phy { + rockchip,enable-strobe-pulldown; status = "okay"; }; diff --git a/dts/src/arm64/rockchip/rk3399-orangepi.dts b/dts/src/arm64/rockchip/rk3399-orangepi.dts index 9e2e246e0b..dba4d03bfc 100644 --- a/dts/src/arm64/rockchip/rk3399-orangepi.dts +++ b/dts/src/arm64/rockchip/rk3399-orangepi.dts @@ -52,13 +52,13 @@ press-threshold-microvolt = <300000>; }; - back { + button-back { label = "Back"; linux,code = <KEY_BACK>; press-threshold-microvolt = <985000>; }; - menu { + button-menu { label = "Menu"; linux,code = <KEY_MENU>; press-threshold-microvolt = <1314000>; diff --git a/dts/src/arm64/rockchip/rk3399-puma-haikou.dts b/dts/src/arm64/rockchip/rk3399-puma-haikou.dts index 04c752f49b..115c14c0a3 100644 --- a/dts/src/arm64/rockchip/rk3399-puma-haikou.dts +++ b/dts/src/arm64/rockchip/rk3399-puma-haikou.dts @@ -207,7 +207,7 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <150000000>; + max-frequency = <40000000>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc3v3_baseboard>; diff --git a/dts/src/arm64/rockchip/rk3399-roc-pc-plus.dts b/dts/src/arm64/rockchip/rk3399-roc-pc-plus.dts index 5a2661ae01..7ba1c28f70 100644 --- a/dts/src/arm64/rockchip/rk3399-roc-pc-plus.dts +++ b/dts/src/arm64/rockchip/rk3399-roc-pc-plus.dts @@ -98,13 +98,12 @@ }; &i2c0 { - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; interrupt-parent = <&gpio0>; interrupts = <RK_PA5 IRQ_TYPE_EDGE_FALLING>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "xin32k"; pinctrl-names = "default"; pinctrl-0 = <&hym8563_int>; diff --git a/dts/src/arm64/rockchip/rk3399-roc-pc.dtsi b/dts/src/arm64/rockchip/rk3399-roc-pc.dtsi index 2f4b1b2e3a..bbf1e3f245 100644 --- a/dts/src/arm64/rockchip/rk3399-roc-pc.dtsi +++ b/dts/src/arm64/rockchip/rk3399-roc-pc.dtsi @@ -41,7 +41,7 @@ keyup-threshold-microvolt = <1500000>; poll-interval = <100>; - recovery { + button-recovery { label = "Recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <18000>; diff --git a/dts/src/arm64/rockchip/rk3399-rock-pi-4.dtsi b/dts/src/arm64/rockchip/rk3399-rock-pi-4.dtsi index 645ced6617..1f76d3501b 100644 --- a/dts/src/arm64/rockchip/rk3399-rock-pi-4.dtsi +++ b/dts/src/arm64/rockchip/rk3399-rock-pi-4.dtsi @@ -509,7 +509,6 @@ &i2s1 { rockchip,playback-channels = <2>; rockchip,capture-channels = <2>; - status = "okay"; }; &i2s2 { diff --git a/dts/src/arm64/rockchip/rk3399-sapphire-excavator.dts b/dts/src/arm64/rockchip/rk3399-sapphire-excavator.dts index 13927e7d07..dbec2b7173 100644 --- a/dts/src/arm64/rockchip/rk3399-sapphire-excavator.dts +++ b/dts/src/arm64/rockchip/rk3399-sapphire-excavator.dts @@ -33,13 +33,13 @@ press-threshold-microvolt = <300000>; }; - back { + button-back { label = "Back"; linux,code = <KEY_BACK>; press-threshold-microvolt = <985000>; }; - menu { + button-menu { label = "Menu"; linux,code = <KEY_MENU>; press-threshold-microvolt = <1314000>; diff --git a/dts/src/arm64/rockchip/rk3399pro-vmarc-som.dtsi b/dts/src/arm64/rockchip/rk3399pro-vmarc-som.dtsi index 935b8c68a7..bf9eb0405b 100644 --- a/dts/src/arm64/rockchip/rk3399pro-vmarc-som.dtsi +++ b/dts/src/arm64/rockchip/rk3399pro-vmarc-som.dtsi @@ -297,11 +297,10 @@ clock-frequency = <400000>; status = "okay"; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "hym8563"; pinctrl-names = "default"; pinctrl-0 = <&hym8563_int>; diff --git a/dts/src/arm64/rockchip/rk3566-pinenote.dtsi b/dts/src/arm64/rockchip/rk3566-pinenote.dtsi index 0d45868132..8d61f824c1 100644 --- a/dts/src/arm64/rockchip/rk3566-pinenote.dtsi +++ b/dts/src/arm64/rockchip/rk3566-pinenote.dtsi @@ -23,7 +23,7 @@ io-channel-names = "buttons"; keyup-threshold-microvolt = <1750000>; - recovery { + button-recovery { label = "recovery"; linux,code = <KEY_VENDOR>; press-threshold-microvolt = <0>; diff --git a/dts/src/arm64/rockchip/rk3566-quartz64-a.dts b/dts/src/arm64/rockchip/rk3566-quartz64-a.dts index a05460b924..25a8c781f4 100644 --- a/dts/src/arm64/rockchip/rk3566-quartz64-a.dts +++ b/dts/src/arm64/rockchip/rk3566-quartz64-a.dts @@ -740,7 +740,7 @@ &uart1 { pinctrl-names = "default"; - pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>; + pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; status = "okay"; uart-has-rtscts; @@ -748,13 +748,14 @@ compatible = "brcm,bcm43438-bt"; clocks = <&rk817 1>; clock-names = "lpo"; - device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; - host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; vbat-supply = <&vcc_sys>; vddio-supply = <&vcca1v8_pmu>; + max-speed = <3000000>; }; }; diff --git a/dts/src/arm64/rockchip/rk3566-quartz64-b.dts b/dts/src/arm64/rockchip/rk3566-quartz64-b.dts index 77b179cd20..b276eb0810 100644 --- a/dts/src/arm64/rockchip/rk3566-quartz64-b.dts +++ b/dts/src/arm64/rockchip/rk3566-quartz64-b.dts @@ -246,7 +246,7 @@ compatible = "rockchip,rk809"; reg = <0x20>; interrupt-parent = <&gpio0>; - interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>; + interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>; assigned-clocks = <&cru I2S1_MCLKOUT_TX>; assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; clock-names = "mclk"; diff --git a/dts/src/arm64/rockchip/rk3566-roc-pc.dts b/dts/src/arm64/rockchip/rk3566-roc-pc.dts index dba648c2f5..9fd262334d 100644 --- a/dts/src/arm64/rockchip/rk3566-roc-pc.dts +++ b/dts/src/arm64/rockchip/rk3566-roc-pc.dts @@ -142,7 +142,7 @@ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>; assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>; clock_in_out = "input"; - phy-mode = "rgmii-id"; + phy-mode = "rgmii"; phy-supply = <&vcc_3v3>; pinctrl-names = "default"; pinctrl-0 = <&gmac1m0_miim @@ -432,11 +432,7 @@ &i2c3 { pinctrl-names = "default"; - pinctrl-0 = <&i2c3m1_xfer>; - status = "okay"; -}; - -&i2c5 { + pinctrl-0 = <&i2c3m0_xfer>; status = "okay"; }; diff --git a/dts/src/arm64/rockchip/rk3568-bpi-r2-pro.dts b/dts/src/arm64/rockchip/rk3568-bpi-r2-pro.dts index c282f6e799..26d7fda275 100644 --- a/dts/src/arm64/rockchip/rk3568-bpi-r2-pro.dts +++ b/dts/src/arm64/rockchip/rk3568-bpi-r2-pro.dts @@ -500,7 +500,6 @@ interrupt-parent = <&gpio0>; interrupts = <RK_PD3 IRQ_TYPE_EDGE_FALLING>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "rtcic_32kout"; pinctrl-names = "default"; pinctrl-0 = <&hym8563_int>; diff --git a/dts/src/arm64/rockchip/rk3568-rock-3a.dts b/dts/src/arm64/rockchip/rk3568-rock-3a.dts index fb87a168fe..539ef8cc77 100644 --- a/dts/src/arm64/rockchip/rk3568-rock-3a.dts +++ b/dts/src/arm64/rockchip/rk3568-rock-3a.dts @@ -509,7 +509,6 @@ interrupt-parent = <&gpio0>; interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>; #clock-cells = <0>; - clock-frequency = <32768>; clock-output-names = "rtcic_32kout"; pinctrl-names = "default"; pinctrl-0 = <&hym8563_int>; diff --git a/dts/src/riscv/sifive/hifive-unleashed-a00.dts b/dts/src/riscv/sifive/hifive-unleashed-a00.dts index ced0d4e479..900a50526d 100644 --- a/dts/src/riscv/sifive/hifive-unleashed-a00.dts +++ b/dts/src/riscv/sifive/hifive-unleashed-a00.dts @@ -3,6 +3,8 @@ #include "fu540-c000.dtsi" #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pwm/pwm.h> /* Clock frequency (in Hz) of the PCB crystal for rtcclk */ #define RTCCLK_FREQ 1000000 @@ -42,6 +44,42 @@ compatible = "gpio-restart"; gpios = <&gpio 10 GPIO_ACTIVE_LOW>; }; + + led-controller { + compatible = "pwm-leds"; + + led-d1 { + pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = <LED_COLOR_ID_GREEN>; + max-brightness = <255>; + label = "d1"; + }; + + led-d2 { + pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = <LED_COLOR_ID_GREEN>; + max-brightness = <255>; + label = "d2"; + }; + + led-d3 { + pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = <LED_COLOR_ID_GREEN>; + max-brightness = <255>; + label = "d3"; + }; + + led-d4 { + pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>; + active-low; + color = <LED_COLOR_ID_GREEN>; + max-brightness = <255>; + label = "d4"; + }; + }; }; &uart0 { diff --git a/firmware/Makefile b/firmware/Makefile index f6ff5b831b..da341871d6 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -79,11 +79,11 @@ $(obj)/%.sum: $(obj)/% FORCE clean-files += *.sha.bin *.sum # The .o files depend on the binaries directly; the .S files don't. -$(patsubst %,$(obj)/%.gen.o, $(obj-pbl-y)): $(obj)/%.gen.o: $(fwdir)/% +$(patsubst %.gen.o,$(obj)/%.gen.o, $(obj-pbl-y)): $(obj)/%.gen.o: $(fwdir)/% # The same for pbl: -$(patsubst %,$(obj)/%.gen.pbl.o, $(obj-pbl-y)): $(obj)/%.gen.pbl.o: $(fwdir)/% -$(patsubst %,$(obj)/%.extgen.pbl.o, $(pbl-y)): $(obj)/%.extgen.pbl.o: $(fwdir)/% +$(patsubst %.gen.o,$(obj)/%.gen.pbl.o, $(obj-pbl-y)): $(obj)/%.gen.pbl.o: $(fwdir)/% +$(patsubst %.gen.o,$(obj)/%.extgen.pbl.o, $(pbl-y)): $(obj)/%.extgen.pbl.o: $(fwdir)/% pbl-y := $(addsuffix .extgen.o, $(fw-external-y)) diff --git a/include/dma/apbh-dma.h b/include/dma/apbh-dma.h index f10bb6f615..4584b504c2 100644 --- a/include/dma/apbh-dma.h +++ b/include/dma/apbh-dma.h @@ -30,6 +30,31 @@ #define MXS_DMA_ALIGNMENT 32 +#define HW_APBHX_CTRL0 0x000 +#define BM_APBH_CTRL0_APB_BURST8_EN BIT(29) +#define BM_APBH_CTRL0_APB_BURST_EN BIT(28) +#define BP_APBH_CTRL0_CLKGATE_CHANNEL 8 +#define BP_APBH_CTRL0_RESET_CHANNEL 16 +#define HW_APBHX_CTRL1 0x010 +#define BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN 16 +#define HW_APBHX_CTRL2 0x020 +#define HW_APBHX_CHANNEL_CTRL 0x030 +#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16 +#define BP_APBHX_VERSION_MAJOR 24 +#define HW_APBHX_CHn_NXTCMDAR_MX23(n) (0x050 + (n) * 0x70) +#define HW_APBHX_CHn_NXTCMDAR_MX28(n) (0x110 + (n) * 0x70) +#define HW_APBHX_CHn_SEMA_MX23(n) (0x080 + (n) * 0x70) +#define HW_APBHX_CHn_SEMA_MX28(n) (0x140 + (n) * 0x70) +#define NAND_ONFI_CRC_BASE 0x4f4e + +enum mxs_dma_id { + UNKNOWN_DMA_ID, + IMX23_DMA, + IMX28_DMA, +}; + +#define apbh_dma_is_imx23(aphb) ((apbh)->id == IMX23_DMA) + /* * MXS DMA channels */ @@ -64,18 +89,16 @@ enum { #define MXS_DMA_DESC_COMMAND_DMA_WRITE 0x1 #define MXS_DMA_DESC_COMMAND_DMA_READ 0x2 #define MXS_DMA_DESC_COMMAND_DMA_SENSE 0x3 -#define MXS_DMA_DESC_CHAIN (1 << 2) -#define MXS_DMA_DESC_IRQ (1 << 3) -#define MXS_DMA_DESC_NAND_LOCK (1 << 4) -#define MXS_DMA_DESC_NAND_WAIT_4_READY (1 << 5) -#define MXS_DMA_DESC_DEC_SEM (1 << 6) -#define MXS_DMA_DESC_WAIT4END (1 << 7) -#define MXS_DMA_DESC_HALT_ON_TERMINATE (1 << 8) -#define MXS_DMA_DESC_TERMINATE_FLUSH (1 << 9) -#define MXS_DMA_DESC_PIO_WORDS_MASK (0xf << 12) -#define MXS_DMA_DESC_PIO_WORDS_OFFSET 12 -#define MXS_DMA_DESC_BYTES_MASK (0xffff << 16) -#define MXS_DMA_DESC_BYTES_OFFSET 16 +#define MXS_DMA_DESC_CHAIN BIT(2) +#define MXS_DMA_DESC_IRQ BIT(3) +#define MXS_DMA_DESC_NAND_LOCK BIT(4) +#define MXS_DMA_DESC_NAND_WAIT_4_READY BIT(5) +#define MXS_DMA_DESC_DEC_SEM BIT(6) +#define MXS_DMA_DESC_WAIT4END BIT(7) +#define MXS_DMA_DESC_HALT_ON_TERMINATE BIT(8) +#define MXS_DMA_DESC_TERMINATE_FLUSH BIT(9) +#define MXS_DMA_DESC_PIO_WORDS(words) ((words) << 12) +#define MXS_DMA_DESC_XFER_COUNT(x) ((x) << 16) struct mxs_dma_cmd { unsigned long next; @@ -88,53 +111,7 @@ struct mxs_dma_cmd { unsigned long pio_words[APBH_DMA_PIO_WORDS]; }; -/* - * MXS DMA command descriptor. - * - * This structure incorporates an MXS DMA hardware command structure, along - * with metadata. - */ -#define MXS_DMA_DESC_FIRST (1 << 0) -#define MXS_DMA_DESC_LAST (1 << 1) -#define MXS_DMA_DESC_READY (1 << 31) - -struct mxs_dma_desc { - struct mxs_dma_cmd cmd; - unsigned int flags; - dma_addr_t address; - void *buffer; - struct list_head node; -}; - -/** - * MXS DMA channel - * - * This structure represents a single DMA channel. The MXS platform code - * maintains an array of these structures to represent every DMA channel in the - * system (see mxs_dma_channels). - */ -#define MXS_DMA_FLAGS_IDLE 0 -#define MXS_DMA_FLAGS_BUSY (1 << 0) -#define MXS_DMA_FLAGS_FREE 0 -#define MXS_DMA_FLAGS_ALLOCATED (1 << 16) -#define MXS_DMA_FLAGS_VALID (1 << 31) - -struct mxs_dma_chan { - const char *name; - unsigned long dev; - struct mxs_dma_device *dma; - unsigned int flags; - unsigned int active_num; - unsigned int pending_num; - struct list_head active; - struct list_head done; -}; - -struct mxs_dma_desc *mxs_dma_desc_alloc(void); -void mxs_dma_desc_free(struct mxs_dma_desc *); -int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc); - -int mxs_dma_go(int chan); +int mxs_dma_go(int chan, struct mxs_dma_cmd *cmd, int ncmds); int mxs_dma_init(void); #endif /* __DMA_H__ */ diff --git a/include/soc/imx/gpmi-nand.h b/include/soc/imx/gpmi-nand.h new file mode 100644 index 0000000000..a552513e0d --- /dev/null +++ b/include/soc/imx/gpmi-nand.h @@ -0,0 +1,147 @@ +#ifndef __SOC_IMX_GPMI_NAND_H +#define __SOC_IMX_GPMI_NAND_H + +#include <linux/bitfield.h> + +#define GPMI_CTRL0 0x00000000 +#define GPMI_CTRL0_SFTRST BIT(31) +#define GPMI_CTRL0_RUN BIT(29) +#define GPMI_CTRL0_DEV_IRQ_EN BIT(28) +#define GPMI_CTRL0_UDMA BIT(26) +#define GPMI_CTRL0_COMMAND_MODE GENMASK(25, 24) +#define GPMI_CTRL0_COMMAND_MODE_WRITE (0x0 << 24) +#define GPMI_CTRL0_COMMAND_MODE_READ (0x1 << 24) +#define GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE (0x2 << 24) +#define GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY (0x3 << 24) +#define GPMI_CTRL0_WORD_LENGTH (1 << 23) +#define GPMI_CTRL0_CS GENMASK(22, 20) +#define GPMI_CTRL0_ADDRESS GENMASK(19, 17) +#define GPMI_CTRL0_ADDRESS_NAND_DATA (0x0 << 17) +#define GPMI_CTRL0_ADDRESS_NAND_CLE (0x1 << 17) +#define GPMI_CTRL0_ADDRESS_NAND_ALE (0x2 << 17) +#define GPMI_CTRL0_ADDRESS_INCREMENT BIT(16) +#define GPMI_CTRL0_XFER_COUNT GENMASK(15, 0) + +#define GPMI_CTRL1 0x00000060 +#define GPMI_CTRL1_SET 0x00000064 +#define GPMI_CTRL1_CLR 0x00000068 +#define GPMI_CTRL1_DECOUPLE_CS BIT(24) +#define GPMI_CTRL1_WRN_DLY(d) (((d) & 0x3) << 22) +#define GPMI_CTRL1_TIMEOUT_IRQ_EN BIT(20) +#define GPMI_CTRL1_GANGED_RDYBUSY BIT(19) +#define GPMI_CTRL1_BCH_MODE BIT(18) +#define GPMI_CTRL1_DLL_ENABLE BIT(17) +#define GPMI_CTRL1_HALF_PERIOD BIT(16) +#define GPMI_CTRL1_RDN_DELAY(d) (((d) & 0xf) << 12) +#define GPMI_CTRL1_DMA2ECC_MODE BIT(11) +#define GPMI_CTRL1_DEV_IRQ BIT(10) +#define GPMI_CTRL1_TIMEOUT_IRQ BIT(9) +#define GPMI_CTRL1_BURST_EN BIT(8) +#define GPMI_CTRL1_ABORT_WAIT_REQUEST BIT(7) +#define GPMI_CTRL1_ABORT_WAIT_FOR_READY GENMASK(6, 4) +#define GPMI_CTRL1_DEV_RESET BIT(3) +#define GPMI_CTRL1_ATA_IRQRDY_POLARITY BIT(2) +#define GPMI_CTRL1_CAMERA_MODE BIT(1) +#define GPMI_CTRL1_GPMI_MODE BIT(0) + +#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS 0x0 +#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS 0x1 +#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS 0x2 +#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY 0x3 + +#define GPMI_TIMING0 0x00000070 + +#define GPMI_TIMING0_ADDRESS_SETUP(d) (((d) & 0xff) << 16) +#define GPMI_TIMING0_DATA_HOLD(d) (((d) & 0xff) << 8) +#define GPMI_TIMING0_DATA_SETUP(d) (((d) & 0xff) << 0) + +#define GPMI_TIMING1 0x00000080 +#define GPMI_TIMING1_BUSY_TIMEOUT(d) (((d) & 0xffff) << 16) + +#define GPMI_ECCCTRL_HANDLE GENMASK(31, 16) +#define GPMI_ECCCTRL_ECC_CMD GENMASK(14, 13) +#define GPMI_ECCCTRL_ECC_CMD_DECODE (0x0 << 13) +#define GPMI_ECCCTRL_ECC_CMD_ENCODE (0x1 << 13) +#define GPMI_ECCCTRL_RANDOMIZER_ENABLE BIT(11) +#define GPMI_ECCCTRL_RANDOMIZER_TYPE0 0 +#define GPMI_ECCCTRL_RANDOMIZER_TYPE1 (1 << 9) +#define GPMI_ECCCTRL_RANDOMIZER_TYPE2 (2 << 9) +#define GPMI_ECCCTRL_ENABLE_ECC BIT(12) +#define GPMI_ECCCTRL_BUFFER_MASK GENMASK(8, 0) +#define GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY 0x100 +#define GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE 0x1ff + +#define GPMI_STAT 0x000000b0 +#define GPMI_STAT_READY_BUSY_OFFSET 24 + +#define GPMI_DEBUG 0x000000c0 +#define GPMI_DEBUG_READY0_OFFSET 28 + +#define GPMI_VERSION 0x000000d0 +#define GPMI_VERSION_MINOR_OFFSET 16 +#define GPMI_VERSION_TYPE_MX23 0x0300 + +#define BCH_CTRL 0x00000000 +#define BCH_CTRL_COMPLETE_IRQ BIT(0) +#define BCH_CTRL_COMPLETE_IRQ_EN BIT(8) + +#define BCH_LAYOUTSELECT 0x00000070 + +#define BCH_FLASH0LAYOUT0 0x00000080 +#define BCH_FLASHLAYOUT0_NBLOCKS GENMASK(31, 24) +#define BCH_FLASHLAYOUT0_META_SIZE GENMASK(23, 16) +#define BCH_FLASHLAYOUT0_ECC0 GENMASK(15, 12) +#define IMX6_BCH_FLASHLAYOUT0_ECC0 GENMASK(15, 11) +#define BCH_FLASHLAYOUT0_DATA0_SIZE GENMASK(9, 0) +#define BCH_FLASHLAYOUT0_GF13_0_GF14_1 BIT(10) + +#define BCH_FLASH0LAYOUT1 0x00000090 +#define BCH_FLASHLAYOUT1_PAGE_SIZE GENMASK(31, 16) +#define BCH_FLASHLAYOUT1_ECCN GENMASK(15, 12) +#define IMX6_BCH_FLASHLAYOUT1_ECCN GENMASK(15, 11) +#define BCH_FLASHLAYOUT1_GF13_0_GF14_1 BIT(10) +#define BCH_FLASHLAYOUT1_DATAN_SIZE GENMASK(9, 0) + +#define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 + +#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512 +#define MXS_NAND_METADATA_SIZE 10 + +#define MXS_NAND_COMMAND_BUFFER_SIZE 32 + +#define MXS_NAND_BCH_TIMEOUT 10000 + +#define BCH62_WRITESIZE 1024 +#define BCH62_OOBSIZE 838 +#define BCH62_PAGESIZE (BCH62_WRITESIZE + BCH62_OOBSIZE) + +/* + * Some SoCs like the i.MX7 use a special layout in the FCB block. + * We can read/write that by adjusting the BCH engine to that layout. + * Particularly we have pages consisting of 8 chunks with 128 bytes + * of data and 100.75 bytes of ECC data each. + */ +static void mxs_nand_mode_fcb_62bit(void __iomem *bch_regs) +{ + u32 fl0, fl1; + + /* 8 ecc_chunks */ + fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, 7); + /* 32 bytes for metadata */ + fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, 32); + /* using ECC62 level to be performed */ + fl0 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, 0x1f); + /* 0x20 * 4 bytes of the data0 block */ + fl0 |= FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, 0x20); + writel(fl0, bch_regs + BCH_FLASH0LAYOUT0); + + /* 1024 for data + 838 for OOB */ + fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, BCH62_PAGESIZE); + /* using ECC62 level to be performed */ + fl1 |= FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, 0x1f); + /* 0x20 * 4 bytes of the data0 block */ + fl1 |= FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, 0x20); + writel(fl1, bch_regs + BCH_FLASH0LAYOUT1); +} + +#endif /* __SOC_IMX_GPMI_NAND_H */ diff --git a/include/soc/imx8m/ddr.h b/include/soc/imx8m/ddr.h index 2149ae4325..0b3c4d47e3 100644 --- a/include/soc/imx8m/ddr.h +++ b/include/soc/imx8m/ddr.h @@ -389,7 +389,7 @@ extern struct dram_timing_info dram_timing; void ddr_get_firmware_lpddr4(void); void ddr_get_firmware_ddr(void); -static void ddr_get_firmware(enum dram_type dram_type) +static inline void ddr_get_firmware(enum dram_type dram_type) { if (dram_type == DRAM_TYPE_LPDDR4) ddr_get_firmware_lpddr4(); |