diff options
Diffstat (limited to 'board')
73 files changed, 2150 insertions, 238 deletions
diff --git a/board/BuR/brppt2/board.c b/board/BuR/brppt2/board.c index c0a163251b4..de206bdf1bc 100644 --- a/board/BuR/brppt2/board.c +++ b/board/BuR/brppt2/board.c @@ -7,6 +7,7 @@ * */ #include <cpu_func.h> +#include <env.h> #include <hang.h> #include <init.h> #include <spl.h> diff --git a/board/Synology/ds109/ds109.c b/board/Synology/ds109/ds109.c index 4f397578182..f3a914cc515 100644 --- a/board/Synology/ds109/ds109.c +++ b/board/Synology/ds109/ds109.c @@ -97,24 +97,6 @@ int board_init(void) return 0; } -/* Synology reset uses UART */ -#include <ns16550.h> -#define SOFTWARE_SHUTDOWN 0x31 -#define SOFTWARE_REBOOT 0x43 -#define CFG_SYS_NS16550_COM2 KW_UART1_BASE -void reset_misc(void) -{ - int b_d; - printf("Synology reset..."); - udelay(50000); - - b_d = ns16550_calc_divisor((struct ns16550 *)CFG_SYS_NS16550_COM2, - CFG_SYS_NS16550_CLK, 9600); - ns16550_init((struct ns16550 *)CFG_SYS_NS16550_COM2, b_d); - ns16550_putc((struct ns16550 *)CFG_SYS_NS16550_COM2, - SOFTWARE_REBOOT); -} - #ifdef CONFIG_RESET_PHY_R /* Configure and enable MV88E1116 PHY */ void reset_phy(void) diff --git a/board/Synology/ds414/ds414.c b/board/Synology/ds414/ds414.c index 1a4cea87e1a..02d6a4a1ea8 100644 --- a/board/Synology/ds414/ds414.c +++ b/board/Synology/ds414/ds414.c @@ -4,6 +4,7 @@ * Copyright (C) 2015 Phil Sutter <phil@nwl.cc> */ +#include <env.h> #include <init.h> #include <miiphy.h> #include <asm/global_data.h> diff --git a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c index b9f47006d61..8c9e9830876 100644 --- a/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c +++ b/board/advantech/imx8mp_rsb3720a1/imx8mp_rsb3720a1.c @@ -7,6 +7,7 @@ #include <dwc3-uboot.h> #include <efi.h> #include <efi_loader.h> +#include <env.h> #include <errno.h> #include <miiphy.h> #include <netdev.h> diff --git a/board/advantech/imx8qm_dmsse20_a1/imx8qm_dmsse20_a1.c b/board/advantech/imx8qm_dmsse20_a1/imx8qm_dmsse20_a1.c index 50b35db5f6c..accd300df04 100644 --- a/board/advantech/imx8qm_dmsse20_a1/imx8qm_dmsse20_a1.c +++ b/board/advantech/imx8qm_dmsse20_a1/imx8qm_dmsse20_a1.c @@ -4,6 +4,7 @@ * Copyright 2019-2023 Kococonnector GmbH */ +#include <env.h> #include <errno.h> #include <linux/libfdt.h> #include <asm/io.h> diff --git a/board/amlogic/jethub-j100/jethub-j100.c b/board/amlogic/jethub-j100/jethub-j100.c index b770a1f8c53..9e87fb9f9d7 100644 --- a/board/amlogic/jethub-j100/jethub-j100.c +++ b/board/amlogic/jethub-j100/jethub-j100.c @@ -5,6 +5,7 @@ */ #include <dm.h> +#include <env.h> #include <init.h> #include <net.h> #include <asm/io.h> diff --git a/board/andestech/ae350/ae350.c b/board/andestech/ae350/ae350.c index 1d9d4a929c2..9bdd2ab1780 100644 --- a/board/andestech/ae350/ae350.c +++ b/board/andestech/ae350/ae350.c @@ -6,6 +6,7 @@ #include <config.h> #include <cpu_func.h> +#include <env.h> #include <flash.h> #include <image.h> #include <init.h> diff --git a/board/armltd/total_compute/Makefile b/board/armltd/total_compute/Makefile index f1ef5a0c39a..615c7876353 100644 --- a/board/armltd/total_compute/Makefile +++ b/board/armltd/total_compute/Makefile @@ -4,4 +4,4 @@ # Usama Arif <usama.arif@arm.com> obj-y := total_compute.o -obj-y += lowlevel_init.o +obj-$(CONFIG_OF_HAS_PRIOR_STAGE) += lowlevel_init.o diff --git a/board/armltd/total_compute/total_compute.c b/board/armltd/total_compute/total_compute.c index 75ba3c33d56..75bc6b0631f 100644 --- a/board/armltd/total_compute/total_compute.c +++ b/board/armltd/total_compute/total_compute.c @@ -31,6 +31,7 @@ static struct mm_region total_compute_mem_map[TC_MEM_MAP_MAX] = { struct mm_region *mem_map = total_compute_mem_map; +#ifdef CONFIG_OF_HAS_PRIOR_STAGE /* * Push the variable into the .data section so that it * does not get cleared later. @@ -45,14 +46,16 @@ int board_fdt_blob_setup(void **fdtp) *fdtp = (void *)fw_dtb_pointer; return 0; } +#endif int misc_init_r(void) { size_t base; +#ifdef CONFIG_OF_HAS_PRIOR_STAGE if (!env_get("fdt_addr_r")) env_set_hex("fdt_addr_r", fw_dtb_pointer); - +#endif if (!env_get("kernel_addr_r")) { /* * The kernel has to be 2M aligned and the first 64K at the diff --git a/board/armltd/total_compute/total_compute.env b/board/armltd/total_compute/total_compute.env index 7924632678e..84d5a10b107 100644 --- a/board/armltd/total_compute/total_compute.env +++ b/board/armltd/total_compute/total_compute.env @@ -11,6 +11,12 @@ bootcmd= blk_dev=mmc; fi; echo block device is ${blk_dev}; + if test -n "${fdt_addr_r}"; then + echo "Custom FDT at ${fdt_addr_r}"; + else; + setenv fdt_addr_r ${fdtcontroladdr}; + echo "FDT address is now set to ${fdt_addr_r}"; + fi; if part number ${blk_dev} 0 vbmeta is_avb; then echo '${blk_dev} with vbmeta partition detected.'; echo 'Starting Android Verified boot...'; diff --git a/board/bsh/imx6ulz_smm_m2/Kconfig b/board/bsh/imx6ulz_smm_m2/Kconfig index e38df7ce5cb..20971aa4fe1 100644 --- a/board/bsh/imx6ulz_smm_m2/Kconfig +++ b/board/bsh/imx6ulz_smm_m2/Kconfig @@ -9,4 +9,25 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "imx6ulz_smm_m2" +choice + prompt "Memory Type (M2/M2B) board" + default BSH_M2_MEMORY + help + Memory type setup. + Please choose correct memory model here. + +config BSH_M2_MEMORY + bool "Enable for bsh m2 variant" + help + If this option is enabled, U-Boot will be configured to support + imx6ulz bsh m2 revision memories. + +config BSH_M2B_MEMORY + bool "Enable for bsh m2b variant" + help + If this option is enabled, U-Boot will be configured to support + imx6ulz bsh m2b revision memories. + +endchoice + endif diff --git a/board/bsh/imx6ulz_smm_m2/MAINTAINERS b/board/bsh/imx6ulz_smm_m2/MAINTAINERS index 77a033c6cbb..a75cddd72f8 100644 --- a/board/bsh/imx6ulz_smm_m2/MAINTAINERS +++ b/board/bsh/imx6ulz_smm_m2/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/bsh/imx6ulz_smm_m2/ F: include/configs/imx6ulz_smm_m2.h F: configs/imx6ulz_smm_m2_defconfig +F: configs/imx6ulz_smm_m2b_defconfig diff --git a/board/bsh/imx6ulz_smm_m2/Makefile b/board/bsh/imx6ulz_smm_m2/Makefile index 59870419bdd..233bbff4c16 100644 --- a/board/bsh/imx6ulz_smm_m2/Makefile +++ b/board/bsh/imx6ulz_smm_m2/Makefile @@ -3,4 +3,5 @@ obj-y := imx6ulz_smm_m2.o obj-$(CONFIG_XPL_BUILD) += spl.o - +obj-$(CONFIG_BSH_M2_MEMORY) += ddr3l_timing_512m.o ddr3l_timing_256m.o ddr3l_timing_128m.o +obj-$(CONFIG_BSH_M2B_MEMORY) += ddr3l_timing_256m_m2b.o ddr3l_timing_128m_m2b.o diff --git a/board/bsh/imx6ulz_smm_m2/ddr3l_timing_128m.c b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_128m.c new file mode 100644 index 00000000000..f11654a8ceb --- /dev/null +++ b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_128m.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "spl_mtypes.h" + +static const struct dram_cfg_param ddr_ddrc_cfg_128mb[] = { + /* IOMUX */ + + /* DDR IO Type: */ + {0x020e04b4, 0x000C0000}, /* IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE */ + {0x020e04ac, 0x00000000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRPKE */ + + /* Clock: */ + {0x020e027c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 */ + + /* Address: */ + {0x020e0250, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS */ + {0x020e024c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS */ + {0x020e0490, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_ADDDS */ + + /* Control: */ + {0x020e0288, 0x000C0028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET */ + {0x020e0270, 0x00000000}, /* + * IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured + * using Group Control Register IOMUXC_SW_PAD_CTL_GRP_CTLDS + */ + + {0x020e0260, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 */ + {0x020e0264, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 */ + {0x020e04a0, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */ + + /* Data Strobes: */ + {0x020e0494, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL */ + {0x020e0280, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 */ + {0x020e0284, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 */ + + /* Data: */ + {0x020e04b0, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE */ + {0x020e0498, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B0DS */ + {0x020e04a4, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B1DS */ + + {0x020e0244, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 */ + {0x020e0248, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 */ + + /* + * ============================================================================= + * DDR Controller Registers + * ============================================================================= + * Manufacturer:ISSI + * Device Part Number:IS43TR16640BL-125JBLI + * Clock Freq.: 400MHz + * Density per CS in Gb: 1 + * Chip Selects used:1 + * Number of Banks:8 + * Row address: 13 + * Column address: 10 + * Data bus width16 + * ============================================================================= + */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit + * during MMDC set up + */ + + /* + * ============================================================================= + * Calibration setup. + * ============================================================================= + */ + {0x021b0800, 0xA1390003}, /* + * DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic + * HW ZQ calibration. + */ + + /* + * For target board, may need to run write leveling calibration to fine tune + * these settings. + */ + {0x021b080c, 0x00000000}, + + /* Read DQS Gating calibration */ + {0x021b083c, 0x41480148}, /* MPDGCTRL0 PHY0 */ + + /* Read calibration */ + {0x021b0848, 0x40403A3E}, /* MPRDDLCTL PHY0 */ + + /* Write calibration */ + {0x021b0850, 0x4040362E}, /* MPWRDLCTL PHY0 */ + + /* + * Read data bit delay: 3 is the recommended default value, although out of reset + * value is 0. + */ + {0x021b081c, 0x33333333}, /* MMDC_MPRDDQBY0DL */ + {0x021b0820, 0x33333333}, /* MMDC_MPRDDQBY1DL */ + + /* Write data bit delay: */ + {0x021b082c, 0xF3333333}, /* MMDC_MPWRDQBY0DL */ + {0x021b0830, 0xF3333333}, /* MMDC_MPWRDQBY1DL */ + + /* DQS&CLK Duty Cycle */ + {0x021b08c0, 0x00944009}, /* [MMDC_MPDCCR] MMDC Duty Cycle Control Register */ + + /* Complete calibration by forced measurement: */ + {0x021b08b8, 0x00000800}, /* DDR_PHY_P0_MPMUR0, frc_msr */ + + /* + * ============================================================================= + * Calibration setup end + * ============================================================================= + */ + + /* MMDC init: */ + {0x021b0004, 0x0002002D}, /* MMDC0_MDPDC */ + {0x021b0008, 0x1B333030}, /* MMDC0_MDOTC */ + {0x021b000c, 0x2B2F52F3}, /* MMDC0_MDCFG0 */ + {0x021b0010, 0xB66D0B63}, /* MMDC0_MDCFG1 */ + {0x021b0014, 0x01FF00DB}, /* MMDC0_MDCFG2 */ + + /* + * MDMISC: RALAT kept to the high level of 5. + * MDMISC: consider reducing RALAT if your 528MHz board design allow that. + * Lower RALAT benefits: + * a. better operation at low frequency, for LPDDR2 freq < 100MHz, change RALAT to 3 + * b. Small performance improvement + */ + {0x021b0018, 0x00211740}, /* MMDC0_MDMISC */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit during + * MMDC set up + */ + {0x021b002c, 0x000026D2}, /* MMDC0_MDRWD */ + {0x021b0030, 0x002F1023}, /* MMDC0_MDOR */ + {0x021b0040, 0x00000043}, /* Chan0 CS0_END */ + {0x021b0000, 0x82180000}, /* MMDC0_MDCTL */ + + {0x021b0890, 0x00400000}, /* MPPDCMPR2 */ + + /* Mode register writes */ + {0x021b001c, 0x02808032}, /* MMDC0_MDSCR, MR2 write, CS0 */ + {0x021b001c, 0x00008033}, /* MMDC0_MDSCR, MR3 write, CS0 */ + {0x021b001c, 0x00048031}, /* MMDC0_MDSCR, MR1 write, CS0 */ + {0x021b001c, 0x15208030}, /* MMDC0_MDSCR, MR0write, CS0 */ + {0x021b001c, 0x04008040}, /* + * MMDC0_MDSCR, ZQ calibration command sent to device + * on CS0 + */ + + {0x021b0020, 0x00007800}, /* MMDC0_MDREF */ + + {0x021b0818, 0x00000227}, /* DDR_PHY_P0_MPODTCTRL */ + + {0x021b0004, 0x0002552D}, /* MMDC0_MDPDC now SDCTL power down enabled */ + + {0x021b0404, 0x00011006}, /* + * MMDC0_MAPSR ADOPT power down enabled, + * MMDC will enter automatically to self-refresh + * while the number of idle cycle reached. + */ + + {0x021b001c, 0x00000000}, /* + * MMDC0_MDSCR, clear this register (especially the + * configuration bit as initialization is complete) + */ +}; + +struct dram_timing_info bsh_dram_timing_128mb = { + .ddrc_cfg = ddr_ddrc_cfg_128mb, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_128mb), + .dram_size = SZ_128M, +}; diff --git a/board/bsh/imx6ulz_smm_m2/ddr3l_timing_128m_m2b.c b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_128m_m2b.c new file mode 100644 index 00000000000..f989e24f567 --- /dev/null +++ b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_128m_m2b.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "spl_mtypes.h" + +static const struct dram_cfg_param ddr_ddrc_cfg_128mb[] = { + /* IOMUX */ + + /* DDR IO Type: */ + {0x020e04b4, 0x000C0000}, /* IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE */ + {0x020e04ac, 0x00000000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRPKE */ + + /* Clock: */ + {0x020e027c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 */ + + /* Address: */ + {0x020e0250, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS */ + {0x020e024c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS */ + {0x020e0490, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_ADDDS */ + + /* Control: */ + {0x020e0288, 0x000C0028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET */ + {0x020e0270, 0x00000000}, /* + * IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured + * using Group Control Register IOMUXC_SW_PAD_CTL_GRP_CTLDS + */ + + {0x020e0260, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 */ + {0x020e0264, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 */ + {0x020e04a0, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */ + + /* Data Strobes: */ + {0x020e0494, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL */ + {0x020e0280, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 */ + {0x020e0284, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 */ + + /* Data: */ + {0x020e04b0, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE */ + {0x020e0498, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B0DS */ + {0x020e04a4, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B1DS */ + + {0x020e0244, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 */ + {0x020e0248, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 */ + + /* + * ============================================================================= + * DDR Controller Registers + * ============================================================================= + * Manufacturer:WINBOND + * Device Part Number:W631GU6RB-11 + * Clock Freq.: 400MHz + * Density per CS in Gb: 1 + * Chip Selects used:1 + * Total DRAM density (Gb)1 + * Number of Banks:8 + * Row address: 13 + * Column address: 10 + * Data bus width16 + * ============================================================================= + */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit + * during MMDC set up + */ + + /* + * ============================================================================= + * Calibration setup. + * ============================================================================= + */ + {0x021b0800, 0xA1390003}, /* + * DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic + * HW ZQ calibration. + */ + + /* + * For target board, may need to run write leveling calibration to fine tune + * these settings. + */ + {0x021b080c, 0x00060002}, + + /* Read DQS Gating calibration */ + {0x021b083c, 0x414c0150}, /* MPDGCTRL0 PHY0 */ + + /* Read calibration */ + {0x021b0848, 0x4040363e}, /* MPRDDLCTL PHY0 */ + + /* Write calibration */ + {0x021b0850, 0x40402a28}, /* MPWRDLCTL PHY0 */ + + /* + * Read data bit delay: 3 is the recommended default value, although out of reset + * value is 0. + */ + {0x021b081c, 0x33333333}, /* MMDC_MPRDDQBY0DL */ + {0x021b0820, 0x33333333}, /* MMDC_MPRDDQBY1DL */ + + /* Write data bit delay: */ + {0x021b082c, 0xf3333333}, /* MMDC_MPWRDQBY0DL */ + {0x021b0830, 0xf3333333}, /* MMDC_MPWRDQBY1DL */ + + /* DQS&CLK Duty Cycle */ + {0x021b08c0, 0x00944009}, /* [MMDC_MPDCCR] MMDC Duty Cycle Control Register */ + + /* Complete calibration by forced measurement: */ + {0x021b08b8, 0x00000800}, /* DDR_PHY_P0_MPMUR0, frc_msr */ + + /* MMDC init: */ + {0x021b0004, 0x0002002D}, /* MMDC0_MDPDC */ + {0x021b0008, 0x1B333030}, /* MMDC0_MDOTC */ + {0x021b000c, 0x2B2F52F3}, /* MMDC0_MDCFG0 */ + {0x021b0010, 0xB66D0A63}, /* MMDC0_MDCFG1 */ + {0x021b0014, 0x01FF00DB}, /* MMDC0_MDCFG2 */ + {0x021b0018, 0x00201740}, /* MMDC0_MDMISC */ + {0x021b002C, 0x000026D2}, /* MMDC0_MDRWD */ + {0x021b0030, 0x002F1023}, /* MMDC0_MDOR */ + {0x021b0040, 0x00000043}, /* CS0_END */ + {0x021b0000, 0x82180000}, /* MMDC0_MDCTL */ + + /* Mode register writes for CS0 */ + {0x021B001C, 0x02808032}, /* MMDC0_MDSCR, MR2 write, CS0 */ + {0x021B001C, 0x00008033}, /* MMDC0_MDSCR, MR3 write, CS0 */ + {0x021B001C, 0x00048031}, /* MMDC0_MDSCR, MR1 write, CS0 */ + {0x021B001C, 0x15208030}, /* MMDC0_MDSCR, MR0 write, CS0 */ + {0x021B001C, 0x04008040}, /* + * MMDC0_MDSCR, ZQ calibration + * command sent to device on CS0 + */ + + /* final DDR setup, before operation start: */ + {0x021b0020, 0x00000800}, /* MMDC0_MDREF */ + + {0x021b0818, 0x00000227}, /* DDR_PHY_P0_MPODTCTRL */ + + {0x021b0004, 0x0002556D}, /* MMDC0_MDPDC now SDCTL power down enabled */ + + {0x021b0404, 0x00011006}, /* + * MMDC0_MAPSR ADOPT power down enabled, + * MMDC will enter automatically to self-refresh + * while the number of idle cycle reached. + */ + + {0x021b001c, 0x00000000}, /* + * MMDC0_MDSCR, clear this register (especially the + * configuration bit as initialization is complete) + */ +}; + +struct dram_timing_info bsh_dram_timing_128mb = { + .ddrc_cfg = ddr_ddrc_cfg_128mb, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_128mb), + .dram_size = SZ_128M, +}; diff --git a/board/bsh/imx6ulz_smm_m2/ddr3l_timing_256m.c b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_256m.c new file mode 100644 index 00000000000..5dfc9f5c70d --- /dev/null +++ b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_256m.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "spl_mtypes.h" + +static const struct dram_cfg_param ddr_ddrc_cfg_256mb[] = { + /* IOMUX */ + + /* DDR IO Type: */ + {0x020e04b4, 0x000C0000}, /* IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE */ + {0x020e04ac, 0x00000000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRPKE */ + + /* Clock: */ + {0x020e027c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 */ + + /* Address: */ + {0x020e0250, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS */ + {0x020e024c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS */ + {0x020e0490, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_ADDDS */ + + /* Control: */ + {0x020e0288, 0x000C0028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET */ + {0x020e0270, 0x00000000}, /* + * IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured + * using Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS + */ + + {0x020e0260, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 */ + {0x020e0264, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 */ + {0x020e04a0, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */ + + /* Data Strobes: */ + {0x020e0494, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL */ + {0x020e0280, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 */ + {0x020e0284, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 */ + + /* Data: */ + {0x020e04b0, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE */ + {0x020e0498, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B0DS */ + {0x020e04a4, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B1DS */ + + {0x020e0244, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 */ + {0x020e0248, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 */ + + /* + * ============================================================================= + * DDR Controller Registers + * ============================================================================= + * Manufacturer:ISSI + * Device Part Number:IS43TR16640BL-125JBLI + * Clock Freq.: 400MHz + * Density per CS in Gb: 2 + * Chip Selects used:1 + * Number of Banks:8 + * Row address: 14 + * Column address: 10 + * Data bus width16 + * ============================================================================= + */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit during + * MMDC set up + */ + + /* + * ============================================================================= + * Calibration setup. + * ============================================================================= + */ + {0x021b0800, 0xA1390003}, /* + * DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic + * HW ZQ calibration + */ + + /* + * For target board, may need to run write leveling calibration to fine tune these settings + */ + {0x021b080c, 0x00050005}, + + /* Read DQS Gating calibration */ + {0x021b083c, 0x01480144}, /* MPDGCTRL0 PHY0 */ + + /* Read calibration */ + {0x021b0848, 0x4040363A}, /* MPRDDLCTL PHY0 */ + + /* Write calibration */ + {0x021b0850, 0x40402E2C}, /* MPWRDLCTL PHY0 */ + + /* + * Read data bit delay: 3 is the reccommended default value, although out of reset value + * is 0 + */ + {0x021b081c, 0x33333333}, /* MMDC_MPRDDQBY0DL */ + {0x021b0820, 0x33333333}, /* MMDC_MPRDDQBY1DL */ + + /* Write data bit delay: */ + {0x021b082c, 0xF3333333}, /* MMDC_MPWRDQBY0DL */ + {0x021b0830, 0xF3333333}, /* MMDC_MPWRDQBY1DL */ + + /* DQS&CLK Duty Cycle */ + {0x021b08c0, 0x00944009}, /* [MMDC_MPDCCR] MMDC Duty Cycle Control Register */ + + /* Complete calibration by forced measurement: */ + {0x021b08b8, 0x00000800}, /* DDR_PHY_P0_MPMUR0, frc_msr */ + + /* + * ============================================================================= + * Calibration setup end + * ============================================================================= + */ + + /* MMDC init: */ + {0x021b0004, 0x0002002D}, /* MMDC0_MDPDC */ + {0x021b0008, 0x1B333030}, /* MMDC0_MDOTC */ + {0x021b000c, 0x3F435333}, /* MMDC0_MDCFG0 */ + {0x021b0010, 0xB68E0B63}, /* MMDC0_MDCFG1 */ + {0x021b0014, 0x01FF00DB}, /* MMDC0_MDCFG2 */ + + /* + * MDMISC: RALAT kept to the high level of 5. + * MDMISC: consider reducing RALAT if your 528MHz board design allow that. + * Lower RALAT benefits: + * a. better operation at low frequency, for LPDDR2 freq < 100MHz, change RALAT to 3 + * b. Small performence improvment + */ + {0x021b0018, 0x00211740}, /* MMDC0_MDMISC */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit during + * MMDC set up + */ + {0x021b002c, 0x000026D2}, /* MMDC0_MDRWD */ + {0x021b0030, 0x00431023}, /* MMDC0_MDOR */ + {0x021b0040, 0x00000047}, /* Chan0 CS0_END */ + {0x021b0000, 0x83180000}, /* MMDC0_MDCTL */ + + {0x021b0890, 0x00400000}, /* MPPDCMPR2 */ + + /* Mode register writes */ + {0x021b001c, 0x02808032}, /* MMDC0_MDSCR, MR2 write, CS0 */ + {0x021b001c, 0x00008033}, /* MMDC0_MDSCR, MR3 write, CS0 */ + {0x021b001c, 0x00048031}, /* MMDC0_MDSCR, MR1 write, CS0 */ + {0x021b001c, 0x15208030}, /* MMDC0_MDSCR, MR0write, CS0 */ + {0x021b001c, 0x04008040}, /* + * MMDC0_MDSCR, ZQ calibration command sent to device + * on CS0 + */ + + {0x021b0020, 0x00007800}, /* MMDC0_MDREF */ + + {0x021b0818, 0x00000227}, /* DDR_PHY_P0_MPODTCTRL */ + + {0x021b0004, 0x0002552D}, /* MMDC0_MDPDC now SDCTL power down enabled */ + + {0x021b0404, 0x00011006}, /* + * MMDC0_MAPSR ADOPT power down enabled, MMDC will enter + * automatically to self-refresh while the number of idle + * cycle reached + */ + + {0x021b001c, 0x00000000}, /* + * MMDC0_MDSCR, clear this register (especially the + * configuration bit as initialization is complete) + */ +}; + +struct dram_timing_info bsh_dram_timing_256mb = { + .ddrc_cfg = ddr_ddrc_cfg_256mb, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_256mb), + .dram_size = SZ_256M, +}; diff --git a/board/bsh/imx6ulz_smm_m2/ddr3l_timing_256m_m2b.c b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_256m_m2b.c new file mode 100644 index 00000000000..c44f632b928 --- /dev/null +++ b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_256m_m2b.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "spl_mtypes.h" + +static const struct dram_cfg_param ddr_ddrc_cfg_256mb[] = { + /* IOMUX */ + + /* DDR IO Type: */ + {0x020e04b4, 0x000C0000}, /* IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE */ + {0x020e04ac, 0x00000000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRPKE */ + + /* Clock: */ + {0x020e027c, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK0_P */ + + /* Address: */ + {0x020e0250, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS */ + {0x020e024c, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS */ + {0x020e0490, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_ADDDS */ + + /* Control: */ + {0x020e0288, 0x000C0030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET */ + {0x020e0270, 0x00000000}, /* + * IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be + * configured using Group Control Register: + * IOMUXC_SW_PAD_CTL_GRP_CTLDS + */ + + {0x020e0260, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT0 */ + {0x020e0264, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT1 */ + {0x020e04a0, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */ + + /* Data Strobes: */ + {0x020e0494, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL */ + {0x020e0280, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P */ + {0x020e0284, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P */ + + /* Data: */ + {0x020e04b0, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE */ + {0x020e0498, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_B0DS */ + {0x020e04a4, 0x00000030}, /* IOMUXC_SW_PAD_CTL_GRP_B1DS */ + + {0x020e0244, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 */ + {0x020e0248, 0x00000030}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 */ + + /* + * ============================================================================= + * DDR Controller Registers + * ============================================================================= + * Manufacturer:WINBOND + * Device Part Number:W632GU6RB-11 + * Clock Freq.: 400MHz + * Density per CS in Gb: 2 + * Chip Selects used:1 + * Total DRAM density (Gb)2 + * Number of Banks:8 + * Row address: 14 + * Column address: 10 + * Data bus width16 + * ============================================================================= + */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit + * during MMDC set up + */ + + /* + * ============================================================================= + * Calibration setup. + * ============================================================================= + */ + {0x021b0800, 0xA1390003}, /* + * DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic + * HW ZQ calibration. + */ + + /* + * For target board, may need to run write leveling calibration to fine tune + * these settings. + */ + {0x021b080c, 0x00070005}, + + /* Read DQS Gating calibration */ + {0x021b083c, 0x414c0150}, /* MPDGCTRL0 PHY0 */ + + /* Read calibration */ + {0x021b0848, 0x4040383e}, /* MMDC_MPRDDLCTL */ + + /* Write calibration */ + {0x021b0850, 0x40402e2a}, /* MMDC_MPWRDLCTL */ + + {0x021B081C, 0x33333333}, /* MMDC_MPRDDQBY0DL */ + {0x021B0820, 0x33333333}, /* MMDC_MPRDDQBY1DL */ + + {0x021B082C, 0xf3333333}, /* MMDC_MPWRDQBY0DL */ + {0x021B0830, 0xf3333333}, /* MMDC_MPWRDQBY1DL */ + + {0x021B08C0, 0x00944009}, /* MMDC_MPDCCR */ + + /* Complete calibration by forced measurement: */ + {0x021B08B8, 0x00000800}, /* DDR_PHY_P0_MPMUR0, frc_msr */ + + /* MMDC init: */ + {0x021b0004, 0x00020024}, /* MMDC0_MDPDC */ + {0x021b0008, 0x1B333030}, /* MMDC0_MDOTC */ + {0x021b000c, 0x3F4352D3}, /* MMDC0_MDCFG0 */ + {0x021b0010, 0xB66D0A63}, /* MMDC0_MDCFG1 */ + {0x021b0014, 0x01FF00DB}, /* MMDC0_MDCFG2 */ + {0x021b0018, 0x00201740}, /* MMDC0_MDMISC */ + {0x021b002C, 0x000026D2}, /* MMDC0_MDRWD */ + {0x021b0030, 0x00431023}, /* MMDC0_MDOR */ + {0x021b0040, 0x00000047}, /* CS0_END */ + {0x021b0000, 0x83180000}, /* MMDC0_MDCTL */ + + /* Mode register writes for CS0 */ + {0x021B001C, 0x02808032}, /* MMDC0_MDSCR, MR2 write, CS0 */ + {0x021B001C, 0x00008033}, /* MMDC0_MDSCR, MR3 write, CS0 */ + {0x021B001C, 0x00048031}, /* MMDC0_MDSCR, MR1 write, CS0 */ + {0x021B001C, 0x15208030}, /* MMDC0_MDSCR, MR0 write, CS0 */ + {0x021B001C, 0x04008040}, /* MMDC0_MDSCR, ZQ calibration */ + + /* final DDR setup, before operation start: */ + {0x021b0020, 0x00000800}, /* MMDC0_MDREF */ + + {0x021b0818, 0x00000227}, /* DDR_PHY_P0_MPODTCTRL */ + {0x021b0004, 0x00025564}, /* MMDC0_MDPDC now SDCTL power down enabled */ + {0x021b0404, 0x00011006}, /* MMDC0_MAPSR ADOPT power down enabled */ + {0x021b001c, 0x00000000}, /* + * MMDC0_MDSCR, clear this register (especially + * the configuration bit as initialization is complete) + */ +}; + +struct dram_timing_info bsh_dram_timing_256mb = { + .ddrc_cfg = ddr_ddrc_cfg_256mb, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_256mb), + .dram_size = SZ_256M, +}; diff --git a/board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m.c b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m.c new file mode 100644 index 00000000000..4c2ffcd429d --- /dev/null +++ b/board/bsh/imx6ulz_smm_m2/ddr3l_timing_512m.c @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "spl_mtypes.h" + +static const struct dram_cfg_param ddr_ddrc_cfg_512mb[] = { + /* + * ============================================================================= + * IOMUX + * ============================================================================= + */ + + /* DDR IO Type: */ + {0x020e04b4, 0x000C0000}, /* IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE */ + {0x020e04ac, 0x00000000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRPKE */ + + /* Clock: */ + {0x020e027c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 */ + + /* Address: */ + {0x020e0250, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS */ + {0x020e024c, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS */ + {0x020e0490, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_ADDDS */ + + /* Control: */ + {0x020e0288, 0x000C0028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET */ + {0x020e0270, 0x00000000}, /* + * IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured using + * Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS + */ + {0x020e0260, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 */ + {0x020e0264, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 */ + {0x020e04a0, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_CTLDS */ + + /* Data Strobes: */ + {0x020e0494, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL */ + {0x020e0280, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 */ + {0x020e0284, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 */ + + /* Data: */ + {0x020e04b0, 0x00020000}, /* IOMUXC_SW_PAD_CTL_GRP_DDRMODE */ + {0x020e0498, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B0DS */ + {0x020e04a4, 0x00000028}, /* IOMUXC_SW_PAD_CTL_GRP_B1DS */ + + {0x020e0244, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 */ + {0x020e0248, 0x00000028}, /* IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 */ + + /* + * ============================================================================= + * DDR Controller Registers + * ============================================================================= + * Manufacturer:ISSI + * Device Part Number:IS43TR16640BL-125JBLI + * Clock Freq.: 400MHz + * Density per CS in Gb: 2 + * Chip Selects used:1 + * Number of Banks:8 + * Row address: 14 + * Column address: 10 + * Data bus width16 + * ============================================================================= + */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR, set the Configuration request bit during + * MMDC set up + */ + + /* + * ============================================================================= + * Calibration setup. + * ============================================================================= + */ + {0x021b0800, 0xA1390003}, /* + * DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic + * HW ZQ calibration + */ + + /* + * For target board may need to run write leveling calibration to fine tune these settings + */ + {0x021b080c, 0x00000000}, + + /* Read DQS Gating calibration */ + {0x021b083c, 0x01440140}, /* MPDGCTRL0 PHY0 */ + + /* Read calibration */ + {0x021b0848, 0x40403A3E}, /* MPRDDLCTL PHY0 */ + + /* Write calibration */ + {0x021b0850, 0x4040322A}, /* MPWRDLCTL PHY0 */ + + /* + * Read data bit delay: 3 is the reccommended default value, although out of reset value + * is 0 + */ + {0x021b081c, 0x33333333}, /* MMDC_MPRDDQBY0DL */ + {0x021b0820, 0x33333333}, /* MMDC_MPRDDQBY1DL */ + + /* Write data bit delay: */ + {0x021b082c, 0xF3333333}, /* MMDC_MPWRDQBY0DL */ + {0x021b0830, 0xF3333333}, /* MMDC_MPWRDQBY1DL */ + + /* DQS&CLK Duty Cycle */ + {0x021b08c0, 0x00944009}, /* [MMDC_MPDCCR] MMDC Duty Cycle Control Register */ + + /* Complete calibration by forced measurement: */ + {0x021b08b8, 0x00000800}, /* DDR_PHY_P0_MPMUR0, frc_msr */ + + /* + * ============================================================================= + * Calibration setup end + * ============================================================================= + */ + + /* MMDC init: */ + {0x021b0004, 0x0002002D}, /* MMDC0_MDPDC */ + {0x021b0008, 0x1B333030}, /* MMDC0_MDOTC */ + {0x021b000c, 0x3F435333}, /* MMDC0_MDCFG0 */ + {0x021b0010, 0xB68E0B63}, /* MMDC0_MDCFG1 */ + {0x021b0014, 0x01FF00DB}, /* MMDC0_MDCFG2 */ + + /* + * MDMISC: RALAT kept to the high level of 5. + * MDMISC: consider reducing RALAT if your 528MHz board design allow that. + * Lower RALAT benefits: + * a. better operation at low frequency, for LPDDR2 freq < 100MHz, change RALAT to 3 + * b. Small performence improvment + */ + {0x021b0018, 0x00211740}, /* MMDC0_MDMISC */ + {0x021b001c, 0x00008000}, /* + * MMDC0_MDSCR set the Configuration request bit during + * MMDC set up + */ + {0x021b002c, 0x000026D2}, /* MMDC0_MDRWD */ + {0x021b0030, 0x00431023}, /* MMDC0_MDOR */ + {0x021b0040, 0x0000004F}, /* Chan0 CS0_END */ + {0x021b0000, 0x84180000}, /* MMDC0_MDCTL */ + + {0x021b0890, 0x00400000}, /* MPPDCMPR2 */ + + /* Mode register writes */ + {0x021b001c, 0x02808032}, /* MMDC0_MDSCR, MR2 write, CS0 */ + {0x021b001c, 0x00008033}, /* MMDC0_MDSCR, MR3 write, CS0 */ + {0x021b001c, 0x00048031}, /* MMDC0_MDSCR, MR1 write, CS0 */ + {0x021b001c, 0x15208030}, /* MMDC0_MDSCR, MR0write, CS0 */ + {0x021b001c, 0x04008040}, /* MMDC0_MDSCR, ZQ calibration command sent to device on CS0 */ + + {0x021b0020, 0x00007800}, /* MMDC0_MDREF */ + + {0x021b0818, 0x00000227}, /* DDR_PHY_P0_MPODTCTRL */ + + {0x021b0004, 0x0002552D}, /* MMDC0_MDPDC now SDCTL power down enabled */ + + {0x021b0404, 0x00011006}, /* + * MMDC0_MAPSR ADOPT power down enabled, MMDC will enter + * automatically to self-refresh while the number of idle + * cycle reached + */ + + {0x021b001c, 0x00000000}, /* + * MMDC0_MDSCR, clear this register (especially the configuration + * bit as initialization is complete) + */ +}; + +struct dram_timing_info bsh_dram_timing_512mb = { + .ddrc_cfg = ddr_ddrc_cfg_512mb, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_512mb), + .dram_size = SZ_512M, +}; diff --git a/board/bsh/imx6ulz_smm_m2/spl.c b/board/bsh/imx6ulz_smm_m2/spl.c index 724841b5745..7aea73f0f5d 100644 --- a/board/bsh/imx6ulz_smm_m2/spl.c +++ b/board/bsh/imx6ulz_smm_m2/spl.c @@ -13,10 +13,13 @@ #include <asm/gpio.h> #include <asm/mach-imx/iomux-v3.h> #include <asm/mach-imx/boot_mode.h> +#include <linux/delay.h> #include <linux/libfdt.h> #include <spl.h> #include <asm/arch/mx6-ddr.h> +#include "spl_mtypes.h" + #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) @@ -31,69 +34,51 @@ static void setup_iomux_uart(void) imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads)); } -static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = { - .grp_addds = 0x00000028, - .grp_ddrmode_ctl = 0x00020000, - .grp_b0ds = 0x00000028, - .grp_ctlds = 0x00000028, - .grp_b1ds = 0x00000028, - .grp_ddrpke = 0x00000000, - .grp_ddrmode = 0x00020000, - .grp_ddr_type = 0x000c0000, -}; +static void ddr_cfg_write(const struct dram_timing_info *dram_timing_info) +{ + int i; + const struct dram_cfg_param *ddrc_cfg = dram_timing_info->ddrc_cfg; + const int ddrc_cfg_num = dram_timing_info->ddrc_cfg_num; + struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; -static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = { - .dram_dqm0 = 0x00000028, - .dram_dqm1 = 0x00000028, - .dram_ras = 0x00000028, - .dram_cas = 0x00000028, - .dram_odt0 = 0x00000028, - .dram_odt1 = 0x00000028, - .dram_sdba2 = 0x00000000, - .dram_sdclk_0 = 0x00000028, - .dram_sdqs0 = 0x00000028, - .dram_sdqs1 = 0x00000028, - .dram_reset = 0x000c0028, -}; + clrbits_le32(&mmdc0->mdctl, 1 << 31); /* clear SDE_0 */ + clrbits_le32(&mmdc0->mdctl, 1 << 30); /* clear SDE_1 */ -static struct mx6_mmdc_calibration mx6_mmcd_calib = { - .p0_mpwldectrl0 = 0x00000000, - .p0_mpwldectrl1 = 0x00100010, - .p0_mpdgctrl0 = 0x414c014c, - .p0_mpdgctrl1 = 0x00000000, - .p0_mprddlctl = 0x40403a42, - .p0_mpwrdlctl = 0x4040342e, -}; + for (i = 0; i < ddrc_cfg_num; i++) { + debug("Writing 0x%x to register 0x%x\n", ddrc_cfg->val, + ddrc_cfg->reg); + writel(ddrc_cfg->val, ddrc_cfg->reg); + ddrc_cfg++; + } +} -static struct mx6_ddr_sysinfo ddr_sysinfo = { - .dsize = 0, - .cs1_mirror = 0, - .cs_density = 32, - .ncs = 1, - .bi_on = 1, - .rtt_nom = 1, - .rtt_wr = 0, - .ralat = 5, - .walat = 1, - .mif3_mode = 3, - .rst_to_cke = 0x23, /* 33 cycles (JEDEC value for DDR3) - total of 500 us */ - .sde_to_rst = 0x10, /* 14 cycles (JEDEC value for DDR3) - total of 200 us */ - .refsel = 1, - .refr = 3, +static const struct dram_timing_info *board_dram_timing[] = { +#if defined(CONFIG_M2_MEMORY) + &bsh_dram_timing_512mb, +#endif + &bsh_dram_timing_256mb, + &bsh_dram_timing_128mb, }; -static struct mx6_ddr3_cfg mem_ddr = { - .mem_speed = 1333, - .density = 2, - .width = 16, - .banks = 8, - .rowaddr = 13, - .coladdr = 10, - .pagesz = 2, - .trcd = 1350, - .trcmin = 4950, - .trasmin = 3600, -}; +static void spl_dram_init(void) +{ + /* Configure memory to maximum supported size for detection */ + ddr_cfg_write(board_dram_timing[0]); + + /* Detect memory physically present */ + gd->ram_size = get_ram_size((void *)CFG_SYS_SDRAM_BASE, board_dram_timing[0]->dram_size); + + if (board_dram_timing[0]->dram_size == gd->ram_size) + return; + + for (size_t index = 1; index < ARRAY_SIZE(board_dram_timing); index++) { + if (board_dram_timing[index]->dram_size == gd->ram_size) { + udelay(1); + ddr_cfg_write(board_dram_timing[index]); + break; + } + } +} static void ccgr_init(void) { @@ -108,20 +93,17 @@ static void ccgr_init(void) writel(0xFFFFFFFF, &ccm->CCGR6); } -static void imx6ul_spl_dram_cfg(void) -{ - mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs); - mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr); -} - void board_init_f(ulong dummy) { ccgr_init(); + + /* DDR initialization */ + spl_dram_init(); + arch_cpu_init(); timer_init(); setup_iomux_uart(); preloader_console_init(); - imx6ul_spl_dram_cfg(); } void reset_cpu(void) diff --git a/board/bsh/imx6ulz_smm_m2/spl_mtypes.h b/board/bsh/imx6ulz_smm_m2/spl_mtypes.h new file mode 100644 index 00000000000..06d6f2d76d8 --- /dev/null +++ b/board/bsh/imx6ulz_smm_m2/spl_mtypes.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2025 BSH Hausgeraete GmbH + * + * Written by: Simon Holesch <simon.holesch@bshg.com> + */ + +#ifndef SPL_MTYPES_H +#define SPL_MTYPES_H + +#include <spl.h> + +struct dram_cfg_param { + unsigned int reg; + unsigned int val; +}; + +struct dram_timing_info { + const struct dram_cfg_param *ddrc_cfg; + unsigned int ddrc_cfg_num; + size_t dram_size; +}; + +extern struct dram_timing_info bsh_dram_timing_128mb; +extern struct dram_timing_info bsh_dram_timing_256mb; +extern struct dram_timing_info bsh_dram_timing_512mb; + +#endif /* SPL_MTYPES_H */ diff --git a/board/bsh/imx8mn_smm_s2/spl.c b/board/bsh/imx8mn_smm_s2/spl.c index 5a77d28cb7e..d36ddd24c63 100644 --- a/board/bsh/imx8mn_smm_s2/spl.c +++ b/board/bsh/imx8mn_smm_s2/spl.c @@ -43,8 +43,6 @@ void spl_board_init(void) int board_early_init_f(void) { - init_uart_clk(3); - if (IS_ENABLED(CONFIG_NAND_MXS)) { init_nand_clk(); } diff --git a/board/congatec/cgtqmx8/cgtqmx8.c b/board/congatec/cgtqmx8/cgtqmx8.c index 054e4e10867..03be02a2884 100644 --- a/board/congatec/cgtqmx8/cgtqmx8.c +++ b/board/congatec/cgtqmx8/cgtqmx8.c @@ -4,6 +4,7 @@ * Copyright (C) 2019 Oliver Graute <oliver.graute@kococonnector.com> */ #include <config.h> +#include <env.h> #include <errno.h> #include <linux/libfdt.h> #include <fsl_esdhc.h> diff --git a/board/data_modul/common/common.c b/board/data_modul/common/common.c index 9e35dc5d6cb..7d344792937 100644 --- a/board/data_modul/common/common.c +++ b/board/data_modul/common/common.c @@ -12,6 +12,7 @@ #include <asm/mach-imx/boot_mode.h> #include <asm/mach-imx/iomux-v3.h> #include <dm/uclass.h> +#include <env.h> #include <hang.h> #include <i2c_eeprom.h> #include <image.h> diff --git a/board/dhelectronics/common/dh_common.c b/board/dhelectronics/common/dh_common.c index 71010803f55..8c052c45007 100644 --- a/board/dhelectronics/common/dh_common.c +++ b/board/dhelectronics/common/dh_common.c @@ -5,6 +5,7 @@ */ #include <dm.h> +#include <env.h> #include <i2c_eeprom.h> #include <net.h> #include <u-boot/crc.h> diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig index b2a4e0891a4..c1564fba7cd 100644 --- a/board/emulation/qemu-x86/Kconfig +++ b/board/emulation/qemu-x86/Kconfig @@ -23,5 +23,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply VIRTIO_PCI imply VIRTIO_NET imply VIRTIO_BLK + imply CMD_SMBIOS endif diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c index 7815ba2dbce..04cad48f033 100644 --- a/board/freescale/common/qixis.c +++ b/board/freescale/common/qixis.c @@ -12,6 +12,7 @@ #include <asm/io.h> #include <linux/compiler.h> #include <linux/time.h> +#include <linux/string.h> #include <i2c.h> #include "qixis.h" diff --git a/board/freescale/imx8mn_evk/spl.c b/board/freescale/imx8mn_evk/spl.c index 231b9289eea..f96f5c45789 100644 --- a/board/freescale/imx8mn_evk/spl.c +++ b/board/freescale/imx8mn_evk/spl.c @@ -115,8 +115,6 @@ void board_init_f(ulong dummy) arch_cpu_init(); - init_uart_clk(1); - timer_init(); /* Clear the BSS. */ diff --git a/board/freescale/imx8ulp_evk/imx8ulp_evk.c b/board/freescale/imx8ulp_evk/imx8ulp_evk.c index 0af61067263..4bf77a488cc 100644 --- a/board/freescale/imx8ulp_evk/imx8ulp_evk.c +++ b/board/freescale/imx8ulp_evk/imx8ulp_evk.c @@ -3,6 +3,7 @@ * Copyright 2020 NXP */ +#include <env.h> #include <miiphy.h> #include <netdev.h> #include <asm/arch/imx8ulp-pins.h> diff --git a/board/freescale/ls1043ardb/cpld.c b/board/freescale/ls1043ardb/cpld.c index bda2f3ac3a6..39b6c6449cf 100644 --- a/board/freescale/ls1043ardb/cpld.c +++ b/board/freescale/ls1043ardb/cpld.c @@ -7,6 +7,7 @@ #include <config.h> #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/freescale/ls1046ardb/cpld.c b/board/freescale/ls1046ardb/cpld.c index 7f8ca2e857f..26a5962bd6e 100644 --- a/board/freescale/ls1046ardb/cpld.c +++ b/board/freescale/ls1046ardb/cpld.c @@ -7,6 +7,7 @@ #include <config.h> #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c index 3db167c0dad..bef4f901ff7 100644 --- a/board/freescale/mx7dsabresd/mx7dsabresd.c +++ b/board/freescale/mx7dsabresd/mx7dsabresd.c @@ -3,6 +3,7 @@ * Copyright (C) 2015 Freescale Semiconductor, Inc. */ +#include <env.h> #include <init.h> #include <net.h> #include <asm/arch/clock.h> diff --git a/board/freescale/p2041rdb/cpld.c b/board/freescale/p2041rdb/cpld.c index 915a8b994d5..2bba377d4d4 100644 --- a/board/freescale/p2041rdb/cpld.c +++ b/board/freescale/p2041rdb/cpld.c @@ -12,6 +12,7 @@ */ #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/freescale/t102xrdb/cpld.c b/board/freescale/t102xrdb/cpld.c index cc933ccd544..00ea9d8f503 100644 --- a/board/freescale/t102xrdb/cpld.c +++ b/board/freescale/t102xrdb/cpld.c @@ -9,6 +9,7 @@ #include <config.h> #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/freescale/t104xrdb/cpld.c b/board/freescale/t104xrdb/cpld.c index c2d526ae15a..038e40e2fae 100644 --- a/board/freescale/t104xrdb/cpld.c +++ b/board/freescale/t104xrdb/cpld.c @@ -12,6 +12,7 @@ #include <config.h> #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/freescale/t208xrdb/cpld.c b/board/freescale/t208xrdb/cpld.c index d2226af6278..838d88d977e 100644 --- a/board/freescale/t208xrdb/cpld.c +++ b/board/freescale/t208xrdb/cpld.c @@ -7,6 +7,7 @@ #include <config.h> #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/freescale/t4rdb/cpld.c b/board/freescale/t4rdb/cpld.c index f076350c1c5..258581eee96 100644 --- a/board/freescale/t4rdb/cpld.c +++ b/board/freescale/t4rdb/cpld.c @@ -16,6 +16,7 @@ #include <config.h> #include <command.h> +#include <linux/string.h> #include <asm/io.h> #include "cpld.h" diff --git a/board/gateworks/fsa.c b/board/gateworks/fsa.c new file mode 100644 index 00000000000..1af8021057c --- /dev/null +++ b/board/gateworks/fsa.c @@ -0,0 +1,736 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2025 Gateworks Corporation + */ + +#include <command.h> +#include <hexdump.h> +#include <i2c.h> +#include <dm.h> +#include <dm/device.h> +#include <dm/device_compat.h> +#include <dm/device-internal.h> // device_remove/device_unbind +#include <asm-generic/gpio.h> +#include <fdt_support.h> +#include <linux/delay.h> + +#include "fsa.h" + +static int fsa; +static struct udevice *fsa_gpiodevs[FSA_MAX] = { NULL }; + +/* find the ofnode of the FSA i2c bus */ +static ofnode fsa_get_ofnode(int fsa) +{ + char str[32]; + + /* by alias */ + snprintf(str, sizeof(str), "fsa%d", fsa); + return ofnode_get_aliases_node(str); +} + +static int fsa_get_dtnode(void *fdt, int fsa) +{ + char str[32]; + + /* by alias */ + snprintf(str, sizeof(str), "fsa%d", fsa); + return fdt_path_offset(fdt, fdt_get_alias(fdt, str)); +} + +static const char * const fsa_gpio_config_names[] = { "NC", "", "input", "output-low", + "output-high" }; + +static const char *fsa_gpio_config_name(struct fsa_gpio_desc *desc) +{ + if (desc->config < ARRAY_SIZE(fsa_gpio_config_names)) + return fsa_gpio_config_names[desc->config]; + return NULL; +}; + +static char *fsa_get_gpio_desc(struct fsa_gpio_desc *desc, char *str, int sz) +{ + str[0] = 0; + if (desc->source == 0xff) { + snprintf(str, sz, "fsa_gpio%d : %s %s", + desc->offset + 1, + desc->name, + fsa_gpio_config_name(desc)); + } else if (desc->config) { + snprintf(str, sz, "gpio@%02x_%02d: %s %s", + desc->source, + desc->offset, + desc->name, + fsa_gpio_config_name(desc)); + } + return str; +} + +static void fsa_show_gpio_descs(const char *prefix, int fsa, struct fsa_board_info *board_info, + struct fsa_user_info *user_info) +{ + char str[128]; + int i; + + /* display slot specific gpios */ + for (i = 0; i < board_info->sockgpios; i++) { + fsa_get_gpio_desc(&user_info->gpios[i], str, sizeof(str)); + printf("%s%-2d: %s\n", prefix, i, str); + } + /* display io-expander specific gpios */ + if (fsa_gpiodevs[fsa]) { + for (i = board_info->sockgpios; + i < (board_info->sockgpios + board_info->ioexpgpios); + i++) { + fsa_get_gpio_desc(&user_info->gpios[i], str, sizeof(str)); + printf("%s%-2d: %s\n", prefix, i, str); + } + } +} + +/* detect gpio expander by address and deal with enabling/disabling/adding gpio expander to dt */ +static int fsa_get_gpiodev(int fsa, int addr, struct udevice **devp) +{ + struct udevice *bus, *dev; + char gpio_name[32]; + int ret; + + ret = device_get_global_by_ofnode(fsa_get_ofnode(fsa), &bus); + if (ret) + return ret; + + sprintf(gpio_name, "gpio@%02x", addr); + + /* probe device on i2c bus */ + ret = dm_i2c_probe(bus, addr, 0, &dev); + switch (ret) { + case -EREMOTEIO: /* chip is not present on i2c bus */ + /* if device is in dt remove/unbind/disable it */ + ret = device_find_child_by_name(bus, gpio_name, &dev); + if (ret) + return ret; + ret = ofnode_set_enabled(dev_ofnode(dev), false); + if (ret) + return ret; + ret = device_unbind(dev); + if (ret) + return ret; + ret = device_remove(dev, DM_REMOVE_NORMAL); + if (ret) + return ret; + return ret; + case -ENOSYS: /* chip found but driver invalid */ + /* if device is in not in dt add/bind it */ + return ret; + case 0: /* chip responded and driver bound */ + break; + } + + if (devp) + *devp = dev; + return 0; +} + +/* add gpio's to gpio device: GPIO device must be probed before you can manipulate it */ +static int fsa_config_gpios(int fsa, struct fsa_user_info *info, int gpios, struct udevice *dev) +{ + struct fsa_gpio_desc *desc; + struct gpio_desc gdesc; + struct udevice *gdev; + int i, ret, flags; + char name[32]; + + /* configure GPIO's */ + for (i = 0; i < gpios; i++) { + desc = &info->gpios[i]; + if (desc->config < FSA_GPIO_INPUT) + continue; + memset(&gdesc, 0, sizeof(gdesc)); + + if (desc->source == 0xff) { + /* Board specific IMX8M GPIO's: find dev of controller by line-name */ + sprintf(name, "fsa%d_gpio%d", fsa, desc->offset + 1); + uclass_foreach_dev_probe(UCLASS_GPIO, gdev) { + ret = dev_read_stringlist_search(gdev, "gpio-line-names", name); + if (ret >= 0) { + gdesc.dev = gdev; + gdesc.offset = ret; + break; + } + } + } else { + /* port expander GPIOs */ + gdesc.dev = dev; + gdesc.offset = desc->offset; + } + + if (!gdesc.dev) + continue; + + sprintf(name, "fsa%d_%s", fsa, desc->name); + switch (desc->config) { + case FSA_GPIO_INPUT: + flags = GPIOD_IS_IN; + break; + case FSA_GPIO_OUTPUT_LOW: + flags = GPIOD_IS_OUT; + break; + case FSA_GPIO_OUTPUT_HIGH: + flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE; + break; + } + if (!dm_gpio_request(&gdesc, name)) + dm_gpio_clrset_flags(&gdesc, GPIOD_MASK_DIR, flags); + } + + return 0; +} + +static int fsa_read_board_config(int fsa, struct fsa_board_info *info) +{ + struct udevice *dev; + int chksum; + int i, ret; + ofnode node; + + /* find eeprom dev */ + node = ofnode_find_subnode(fsa_get_ofnode(fsa), "eeprom@54"); + if (!ofnode_valid(node)) + return -EINVAL; + ret = device_get_global_by_ofnode(node, &dev); + if (ret) + return ret; + + /* read eeprom */ + ret = dm_i2c_read(dev, 0, (uint8_t *)info, sizeof(*info)); + if (ret) { + dev_err(dev, "read failed: %d\n", ret); + return ret; + } + + /* validate checksum */ + for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) + chksum += ((unsigned char *)info)[i]; + if ((info->chksum[0] != ((chksum >> 8) & 0xff)) || + (info->chksum[1] != (chksum & 0xff))) { + dev_err(dev, "FSA%d EEPROM: Invalid User Config Checksum\n", fsa); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, info, sizeof(*info)); + memset(info, 0, sizeof(*info)); + return -EINVAL; + } + + return 0; +} + +static int fsa_read_user_config(int fsa, struct fsa_user_info *info) +{ + struct udevice *dev; + int chksum; + int i, ret; + ofnode node; + + /* find eeprom dev */ + node = ofnode_find_subnode(fsa_get_ofnode(fsa), "eeprom@55"); + if (!ofnode_valid(node)) + return -EINVAL; + ret = device_get_global_by_ofnode(node, &dev); + if (ret) + return ret; + + /* read eeprom */ + ret = dm_i2c_read(dev, 0, (uint8_t *)info, sizeof(*info)); + if (ret) { + dev_err(dev, "read failed: %d\n", ret); + return ret; + } + + /* validate checksum */ + for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) + chksum += ((unsigned char *)info)[i]; + if ((info->chksum[0] != ((chksum >> 8) & 0xff)) || + (info->chksum[1] != (chksum & 0xff))) { + dev_err(dev, "FSA%d EEPROM: Invalid User Config Checksum\n", fsa); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, info, sizeof(*info)); + memset(info, 0, sizeof(*info)); + return -EINVAL; + } + + return 0; +} + +static int fsa_write_user_config(int fsa, struct fsa_user_info *info) +{ + struct udevice *bus, *dev; + int i, n, chunk, slave, base, ret; + ofnode node; + int chksum; + + /* create checksum */ + for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) + chksum += ((unsigned char *)info)[i]; + info->chksum[0] = chksum >> 8; + info->chksum[1] = chksum & 0xff; + + /* find eeprom dev */ + node = ofnode_find_subnode(fsa_get_ofnode(fsa), "eeprom@55"); + ret = device_get_global_by_ofnode(node, &dev); + if (ret) + return ret; + bus = dev->parent; + base = dev_read_addr(dev); + + /* write in 16byte chunks (multi-byte writes fail larger than that) */ + chunk = 16; + slave = -1; + for (i = 0; i < sizeof(*info); i += chunk) { + /* select device based on offset */ + if ((base + (i / 256)) != slave) { + slave = base + (i / 256); + ret = i2c_get_chip(bus, slave, 1, &dev); + if (ret) { + dev_err(bus, "failed to get eeprom@0x%02x: %d\n", slave, ret); + return ret; + } + } + /* select byte count */ + n = sizeof(*info) - i; + if (n > chunk) + n = chunk; + ret = dm_i2c_write(dev, i % 256, (uint8_t *)info + i, n); + if (ret) { + dev_err(dev, "write failed: %d\n", ret); + return ret; + } + mdelay(11); + } + + return ret; +} + +static int fsa_detect(int fsa, struct fsa_board_info *board_info, struct fsa_user_info *user_info, + bool gpio) +{ + int ret; + + ret = fsa_read_board_config(fsa, board_info); + if (ret) + return ret; + if (user_info) { + ret = fsa_read_user_config(fsa, user_info); + if (ret) + return ret; + /* detect port expander */ + if (gpio && !fsa_get_gpiodev(fsa, 0x20, &fsa_gpiodevs[fsa])) + fsa_config_gpios(fsa, user_info, + board_info->sockgpios + board_info->ioexpgpios, + fsa_gpiodevs[fsa]); + } + + return ret; +} + +static int ft_fixup_stringlist_elem(void *fdt, int offset, const char *prop, int elem, + const char *val) +{ + const char *list, *end; + char *new, *buf; + int length; + int sz = 0; + int i = 0; + int ret; + + if (offset < 0 || elem < 0 || !val) { + printf("%s -EINVAL\n", __func__); + return -EINVAL; + } + + list = fdt_getprop(fdt, offset, prop, &length); + + /* no property or invalid params */ + if (!list || length < 0) { + printf("%s failed - no property\n", __func__); + return -EINVAL; + } + + /* create new buffer with enough space */ + buf = calloc(1, length + strlen(val)); + new = buf; + + /* iterate over current stringlist and build new list into buf */ + end = list + length; + while (list < end) { + length = strnlen(list, end - list) + 1; + sz += length; + /* insert new value into buf */ + if (elem == i) { + strcpy(new, val); + new += strlen(val) + 1; + } else { + strcpy(new, list); + new += length; + } + list += length; + i++; + } + length = new - buf; + ret = fdt_setprop(fdt, offset, prop, buf, length); + free(buf); + if (ret) + printf("%s failed %d\n", __func__, ret); + + return ret; +} + +static int ft_fixup_fsa_gpio_name(void *fdt, int offset, int fsa, int gpio, const char *name) +{ + const char *prop = "gpio-line-names"; + char str[32]; + + sprintf(str, "fsa%d_%s", fsa, name); + + if (!fdt_getprop(fdt, offset, prop, NULL)) { + char buf[16] = { 0 }; + + fdt_setprop(fdt, offset, prop, &buf, sizeof(buf)); + } + + return ft_fixup_stringlist_elem(fdt, offset, prop, gpio, str); +} + +static void fsa_show_details(int fsa, struct fsa_board_info *board, struct fsa_user_info *user) +{ + printf("FSA%d: %s\n", fsa, board->model); + printf("description: %s\n", user->desc); + printf("overlay: %s\n", user->overlay); + fsa_show_gpio_descs("\t", fsa, board, user); +} + +int fsa_init(void) +{ + struct fsa_board_info board_info; + struct fsa_user_info user_info; + int fsa, ret; + + for (fsa = 1; fsa < FSA_MAX; fsa++) { + ret = fsa_detect(fsa, &board_info, &user_info, true); + if (!ret) + printf("FSA%d: %s %s\n", fsa, board_info.model, user_info.desc); + } + + return 0; +} + +int fsa_show(void) +{ + struct fsa_board_info board_info; + int fsa, ret; + + for (fsa = 1; fsa < FSA_MAX; fsa++) { + ret = fsa_detect(fsa, &board_info, NULL, false); + if (!ret) { + printf("FSA%d : %s %d %02x-%02x-%02x%02x\n", fsa, + board_info.model, board_info.serial, + board_info.mfgdate[0], board_info.mfgdate[1], + board_info.mfgdate[2], board_info.mfgdate[3]); + } + } + return 0; +} + +/* fixup gpio line names for fsa gpios */ +int fsa_ft_fixup(void *fdt) +{ + struct fsa_board_info board_info; + struct fsa_user_info user_info; + int fsa, i, ret; + char path[128]; + char str[32]; + ofnode node; + int off; + + /* iterate over FSA's and rename gpio's */ + for (fsa = 1; fsa < FSA_MAX; fsa++) { + /* disable FSA ioexp node if disabled in controlling dt */ + off = fdt_subnode_offset(fdt, fsa_get_dtnode(fdt, fsa), "gpio@20"); + if (off >= 0) { + if (!fdt_get_path(fdt, off, path, sizeof(path))) { + node = ofnode_path(path); + if (ofnode_valid(node) && !ofnode_is_enabled(node)) + fdt_setprop_string(fdt, off, "status", "disabled"); + } + } + + /* detect FSA eeprom */ + if (fsa_detect(fsa, &board_info, &user_info, false)) + continue; + + /* configure GPIO's */ + for (i = 0; i < board_info.sockgpios + board_info.ioexpgpios; i++) { + if (user_info.gpios[i].config < FSA_GPIO_INPUT) + continue; + + if (user_info.gpios[i].source == 0xff) { + /* Board specific IMX8M GPIO's */ + for (off = fdt_node_offset_by_prop_value(fdt, 0, + "gpio-controller", NULL, + 0); + off >= 0; + off = fdt_node_offset_by_prop_value(fdt, off, + "gpio-controller", NULL, + 0) + ) { + sprintf(str, "fsa%d_gpio%d", fsa, + user_info.gpios[i].offset + 1); + ret = fdt_stringlist_search(fdt, off, "gpio-line-names", + str); + if (ret >= 0) { + ft_fixup_fsa_gpio_name(fdt, off, fsa, ret, + user_info.gpios[i].name); + break; + } + } + } else { + /* port expander GPIOs */ + off = fdt_subnode_offset(fdt, fsa_get_dtnode(fdt, fsa), "gpio@20"); + ft_fixup_fsa_gpio_name(fdt, off, fsa, user_info.gpios[i].offset, + user_info.gpios[i].name); + } + } + } + + return 0; +} + +static int do_fsa_dev(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct fsa_board_info board_info; + struct fsa_user_info user_info; + int i; + + if (argc < 2) { + /* list FSAs */ + printf("detecting FSA Adapters:\n"); + for (i = 1; i < FSA_MAX; i++) { + if (!fsa_read_board_config(i, &board_info) && + !fsa_read_user_config(i, &user_info)) + printf("FSA%d : %s %s\n", i, board_info.model, user_info.desc); + } + } else { + /* select FSA */ + fsa = simple_strtoul(argv[1], NULL, 10); + } + + if (fsa) { + /* read FSA */ + if (!fsa_read_board_config(fsa, &board_info) && + !fsa_read_user_config(fsa, &user_info)) { + printf("selected:\n"); + fsa_show_details(fsa, &board_info, &user_info); + } else { + printf("FSA%d not detected\n", fsa); + fsa = 0; + } + } else { + printf("no FSA currently selected\n"); + } + + return 0; +} + +static int do_fsa_desc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct fsa_board_info board_info; + struct fsa_user_info user_info; + + /* strip off leading cmd arg */ + argc--; + argv++; + + if (!fsa) { + printf("No FSA selected\n"); + return CMD_RET_USAGE; + } + + if (fsa_read_board_config(fsa, &board_info) || fsa_read_user_config(fsa, &user_info)) { + printf("can't detect FSA%d\n", fsa); + return CMD_RET_USAGE; + } + + /* set */ + if (argc) { + strlcpy(user_info.desc, argv[0], sizeof(user_info.desc)); + if (fsa_write_user_config(fsa, &user_info)) + return CMD_RET_FAILURE; + } + + /* show */ + fsa_show_details(fsa, &board_info, &user_info); + + return CMD_RET_SUCCESS; +} + +static int do_fsa_overlay(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct fsa_board_info board_info; + struct fsa_user_info user_info; + + /* strip off leading cmd arg */ + argc--; + argv++; + + if (!fsa) { + printf("No FSA selected\n"); + return CMD_RET_USAGE; + } + + if (fsa_read_board_config(fsa, &board_info) || fsa_read_user_config(fsa, &user_info)) { + printf("can't detect FSA%d\n", fsa); + return CMD_RET_USAGE; + } + + /* set */ + if (argc) { + strlcpy(user_info.overlay, argv[0], sizeof(user_info.overlay)); + if (fsa_write_user_config(fsa, &user_info)) + return CMD_RET_FAILURE; + } + + /* show */ + fsa_show_details(fsa, &board_info, &user_info); + + return CMD_RET_SUCCESS; +} + +static int do_fsa_gpio(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct fsa_board_info board_info; + struct fsa_user_info user_info; + struct fsa_gpio_desc desc; + char str[64]; + int i, j; + + /* strip off leading cmd arg */ + argc--; + argv++; + + if (!fsa) { + printf("No FSA selected\n"); + return CMD_RET_USAGE; + } + + if (fsa_read_board_config(fsa, &board_info) || fsa_read_user_config(fsa, &user_info)) { + printf("can't detect FSA%d\n", fsa); + return CMD_RET_USAGE; + } + + if (!argc) { + /* show all gpios */ + fsa_show_gpio_descs("\t", fsa, &board_info, &user_info); + return CMD_RET_SUCCESS; + } + + if (!isdigit(argv[0][0])) { + printf("invalid gpio offset: %s\n", argv[0]); + return CMD_RET_USAGE; + } + + memset(&desc, 0, sizeof(desc)); + i = simple_strtoul(argv[0], NULL, 10); + + if (i >= 0 && i < board_info.sockgpios) { + desc.offset = i; + desc.source = 0xff; + } else if (i >= board_info.sockgpios && + i < (board_info.sockgpios + board_info.ioexpgpios) && + fsa_gpiodevs[fsa]) { + desc.offset = i - board_info.sockgpios; + desc.source = 0x20; + } else { + printf("invalid index %d", i); + return CMD_RET_FAILURE; + } + + if (argc > 1) { + if (user_info.gpios[i].config == FSA_GPIO_NC) { + printf("can not alter NC gpio\n"); + return CMD_RET_FAILURE; + } + strlcpy(desc.name, argv[1], sizeof(desc.name)); + if (!*desc.name) { + printf("FSA%d %s erasing gpio %d\n", fsa, board_info.model, i); + memset(&user_info.gpios[i], 0, sizeof(desc)); + if (fsa_write_user_config(fsa, &user_info)) + return CMD_RET_FAILURE; + return CMD_RET_SUCCESS; + } + } + if (argc > 2) { + if (user_info.gpios[i].config == FSA_GPIO_NC) { + printf("can not alter NC gpio\n"); + return CMD_RET_FAILURE; + } + for (j = 1; j < ARRAY_SIZE(fsa_gpio_config_names); j++) { + if (!strcasecmp(argv[2], fsa_gpio_config_names[j])) { + desc.config = j; + break; + } + }; + if (j >= ARRAY_SIZE(fsa_gpio_config_names)) { + printf("invalid config type '%s\n", argv[2]); + return CMD_RET_FAILURE; + } + } + + /* show a specific gpio */ + if (argc == 1) { + printf("FSA%d %s showing gpio %d\n", fsa, board_info.model, i); + printf("%s\n", fsa_get_gpio_desc(&user_info.gpios[i], str, sizeof(str))); + return CMD_RET_SUCCESS; + } + + /* set a specific gpio */ + else if (argc == 3) { + printf("FSA%d %s updating gpio %d\n", fsa, board_info.model, i); + memcpy(&user_info.gpios[i], &desc, sizeof(desc)); + if (fsa_write_user_config(fsa, &user_info)) + return CMD_RET_FAILURE; + return CMD_RET_SUCCESS; + } + + return CMD_RET_USAGE; +} + +static struct cmd_tbl cmd_fsa_sub[] = { + U_BOOT_CMD_MKENT(dev, 1, 1, do_fsa_dev, "", ""), + U_BOOT_CMD_MKENT(gpio, 4, 1, do_fsa_gpio, "", ""), + U_BOOT_CMD_MKENT(description, 1, 1, do_fsa_desc, "", ""), + U_BOOT_CMD_MKENT(overlay, 1, 1, do_fsa_overlay, "", ""), +}; + +static int do_fsa(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct cmd_tbl *c; + + /* strip off leading fsa arg */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], cmd_fsa_sub, ARRAY_SIZE(cmd_fsa_sub)); + if (c) + return c->cmd(cmdtp, flag, argc, argv); + return CMD_RET_USAGE; +} + +U_BOOT_LONGHELP(fsa, + "dev [dev] - show or set current FSA adapter\n" + "fsa gpio - show current gpio descriptors\n" + "fsa gpio [<offset>]|[<offset> <source>] - show a specific gpio descriptor\n" + "fsa gpio [<offset> <name> <input|output-low|output-high> [source]] - set a gpio descriptor\n" + "fsa description [description] - show or set the FSA user description string\n" + "fsa overlay [overlay] - show or set the FSA overlay string\n" +); + +U_BOOT_CMD(fsa, 6, 1, do_fsa, + "Flexible Socket Adapter", + fsa_help_text +); diff --git a/board/gateworks/fsa.h b/board/gateworks/fsa.h new file mode 100644 index 00000000000..ddb64499d78 --- /dev/null +++ b/board/gateworks/fsa.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2025 Gateworks Corporation + */ + +#ifndef _FSA_H_ +#define _FSA_H_ + +#define FSA_MAX 5 + +enum fsa_gpio_cfg { + FSA_GPIO_NC, + FSA_GPIO_UNCONFIGURED, + FSA_GPIO_INPUT, + FSA_GPIO_OUTPUT_LOW, + FSA_GPIO_OUTPUT_HIGH, +}; + +struct fsa_gpio_desc { + u8 offset; + u8 config; + u8 source; + char name[13]; +}; + +struct fsa_board_info { + char model[16]; /* 0x00: model string */ + u8 mac[6]; /* 0x10: MAC base */ + u8 macno; /* 0x16: number of mac addrs */ + u8 resv1; /* 0x17: reserved */ + u32 serial; /* 0x18: Serial Number */ + u8 mfgdate[4]; /* 0x1c: MFG date */ + u8 sockgpios; /* 0x20: number of socket gpio descriptors */ + u8 ioexpgpios; /* 0x21: number of io expander gpio descriptors */ + u8 resv2[220]; /* 0x22: reserved */ + u8 chksum[2]; /* 0xfe: */ +}; + +struct fsa_user_info { + char desc[32]; /* 0x000: user description */ + char overlay[16]; /* 0x020: dt-overlay suffice */ + struct fsa_gpio_desc gpios[20]; /* 0x030: gpio descriptors */ + u8 reserved[398]; /* 0x170: reserved */ + u8 chksum[2]; /* 0x2fe: */ +}; + +int fsa_init(void); +int fsa_show(void); +int fsa_ft_fixup(void *fdt); + +#endif // _FSA_H_ diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 21a908c20dd..457d8281a66 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -6,6 +6,7 @@ */ #include <command.h> +#include <env.h> #include <fdt_support.h> #include <gsc.h> #include <hwconfig.h> diff --git a/board/gateworks/venice/Makefile b/board/gateworks/venice/Makefile index ab69e07ba7b..1aaf0295d5c 100644 --- a/board/gateworks/venice/Makefile +++ b/board/gateworks/venice/Makefile @@ -5,6 +5,7 @@ # obj-y += venice.o eeprom.o +obj-y += ../fsa.o ifdef CONFIG_XPL_BUILD obj-y += spl.o diff --git a/board/gateworks/venice/eeprom.c b/board/gateworks/venice/eeprom.c index afaabf34879..d9a87193434 100644 --- a/board/gateworks/venice/eeprom.c +++ b/board/gateworks/venice/eeprom.c @@ -6,9 +6,11 @@ #include <gsc.h> #include <hexdump.h> #include <i2c.h> +#include <dm/device.h> #include <dm/uclass.h> #include "eeprom.h" +#include "../fsa.h" /* I2C */ #define SOM_EEPROM_BUSNO 0 @@ -18,7 +20,8 @@ struct venice_board_info som_info; struct venice_board_info base_info; -char venice_model[32]; +char venice_model[64]; +char venice_som_model[32]; char venice_baseboard_model[32]; u32 venice_serial; @@ -107,7 +110,7 @@ static int eeprom_read(int busno, int slave, int alen, struct venice_board_info /* validate checksum */ for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) chksum += buf[i]; - if ((info->chksum[0] != chksum >> 8) || + if ((info->chksum[0] != ((chksum >> 8) & 0xff)) || (info->chksum[1] != (chksum & 0xff))) { printf("EEPROM: I2C%d@0x%02x: Invalid Checksum\n", busno, slave); print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, sizeof(*info)); @@ -126,6 +129,54 @@ static int eeprom_read(int busno, int slave, int alen, struct venice_board_info return 0; } +static int fsa_eeprom_read(const char *base, int fsa, struct fsa_board_info *info) +{ + int i; + int chksum; + unsigned char *buf = (unsigned char *)info; + struct udevice *dev, *bus; + int ret; + u8 reg; + + /* probe mux */ + ret = uclass_get_device_by_seq(UCLASS_I2C, 2, &bus); + if (!ret) + ret = dm_i2c_probe(bus, 0x70, 0, &dev); + if (ret) + return ret; + /* steer mux */ + if (!strncmp(base, "GW82", 4)) { + if (fsa < 3) + reg = (fsa == 1) ? BIT(1) : BIT(0); + else + return -EINVAL; + } + dm_i2c_write(dev, 0x00, ®, 1); + + /* get eeprom */ + ret = dm_i2c_probe(bus, 0x54, 0, &dev); + if (ret) + return ret; + + /* read eeprom config section */ + ret = dm_i2c_read(dev, 0x00, buf, sizeof(*info)); + if (ret) + return ret; + + /* validate checksum */ + for (chksum = 0, i = 0; i < (int)sizeof(*info) - 2; i++) + chksum += buf[i]; + if ((info->chksum[0] != ((chksum >> 8) & 0xff)) || + (info->chksum[1] != (chksum & 0xff))) { + printf("FSA%d EEPROM (board): %s: Invalid Checksum\n", fsa, dev->name); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, sizeof(*info)); + memset(info, 0, sizeof(*info)); + return -EINVAL; + } + + return 0; +} + /* determine BOM revision from model */ int get_bom_rev(const char *str) { @@ -299,6 +350,8 @@ static int eeprom_info(bool verbose) base_info.mfgdate[0], base_info.mfgdate[1], base_info.mfgdate[2], base_info.mfgdate[3]); } + if (verbose) + fsa_show(); return 0; } @@ -315,6 +368,7 @@ int venice_eeprom_init(int quiet) memset(&som_info, 0, sizeof(som_info)); return 0; } + strlcpy(venice_som_model, som_info.model, sizeof(venice_som_model)); /* read optional baseboard EEPROM */ eeprom_read(BASEBOARD_EEPROM_BUSNO, BASEBOARD_EEPROM_ADDR, 2, &base_info); @@ -322,7 +376,7 @@ int venice_eeprom_init(int quiet) /* create model strings */ if (base_info.model[0]) { sprintf(venice_model, "GW%c%c%c%c-%c%c-", - som_info.model[2], /* family */ + base_info.model[2], /* family */ base_info.model[3], /* baseboard */ base_info.model[4], base_info.model[5], /* subload of baseboard */ som_info.model[4], som_info.model[5]); /* last 2digits of SOM */ @@ -347,9 +401,74 @@ int venice_eeprom_init(int quiet) } venice_serial = som_info.serial; + /* GW8xxx product family naming scheme */ + if (venice_model[2] == '8') { + struct fsa_board_info fsa_info; + int i = 0; + int fsa; + + /* baseboard */ + if (base_info.model[0]) { + rev_pcb = get_pcb_rev(base_info.model); + rev_bom = get_bom_rev(base_info.model); + venice_model[i++] = 'G'; + venice_model[i++] = 'W'; + venice_model[i++] = base_info.model[2]; /* baseboard */ + venice_model[i++] = base_info.model[3]; + venice_model[i++] = base_info.model[4]; /* subload */ + venice_model[i++] = base_info.model[5]; + venice_model[i++] = rev_pcb; + if (rev_bom) + venice_model[i++] = rev_bom; + venice_model[i++] = '-'; + venice_model[i++] = 'S'; + } else { + venice_model[i++] = 'G'; + venice_model[i++] = 'W'; + } + + /* som */ + rev_pcb = get_pcb_rev(som_info.model); + rev_bom = get_bom_rev(som_info.model); + venice_model[i++] = som_info.model[4]; + venice_model[i++] = som_info.model[5]; + venice_model[i++] = rev_pcb; + if (rev_bom) + venice_model[i++] = rev_bom; + + /* fsa */ + for (fsa = 1; fsa < FSA_MAX; fsa++) { + if (!fsa_eeprom_read(venice_model, fsa, &fsa_info)) { + venice_model[i++] = '-'; + venice_model[i++] = 'F'; + venice_model[i++] = '0' + fsa; + venice_model[i++] = fsa_info.model[5]; + venice_model[i++] = fsa_info.model[6]; + venice_model[i++] = fsa_info.model[8]; + if (fsa_info.model[9]) + venice_model[i++] = fsa_info.model[9]; + } + } + + /* append extra model info */ + if (som_info.config[0] >= 32 && som_info.config[0] < 0x7f) { + venice_model[i++] = '-'; + strlcpy(venice_model + i, som_info.config, (sizeof(venice_model) - i) - 1); + i += strlen(som_info.config); + if (i >= sizeof(venice_model)) + i = sizeof(venice_model) - 1; + } + venice_model[i++] = 0; + } + if (!quiet) eeprom_info(false); + if (!strncmp(venice_model, "GW7901-SP486", 12) && + strcmp(venice_model, "GW7901-SP486-C")) { + return 2048; + } + return (16 << som_info.sdram_size); } @@ -363,6 +482,11 @@ const char *eeprom_get_model(void) return venice_model; } +const char *eeprom_get_som_model(void) +{ + return venice_som_model; +} + const char *eeprom_get_baseboard_model(void) { return venice_baseboard_model; diff --git a/board/gateworks/venice/eeprom.h b/board/gateworks/venice/eeprom.h index bb7a5fa9ad1..a0f449299aa 100644 --- a/board/gateworks/venice/eeprom.h +++ b/board/gateworks/venice/eeprom.h @@ -20,12 +20,13 @@ struct venice_board_info { u8 sdram_width; /* 0x2D: (8 << n) bit */ u8 res3[2]; /* 0x2E */ char model[16]; /* 0x30: model string */ - u8 res4[14]; /* 0x40 */ + u8 config[14]; /* 0x40: model config */ u8 chksum[2]; /* 0x4E */ }; int venice_eeprom_init(int quiet); const char *eeprom_get_model(void); +const char *eeprom_get_som_model(void); const char *eeprom_get_baseboard_model(void); const char *eeprom_get_dtb_name(int level, char *buf, int len); int eeprom_getmac(int index, uint8_t *enetaddr); diff --git a/board/gateworks/venice/lpddr4_timing.h b/board/gateworks/venice/lpddr4_timing.h index d19902f10ec..21997f6fb2a 100644 --- a/board/gateworks/venice/lpddr4_timing.h +++ b/board/gateworks/venice/lpddr4_timing.h @@ -6,18 +6,6 @@ #ifndef __LPDDR4_TIMING_H__ #define __LPDDR4_TIMING_H__ -#ifdef CONFIG_IMX8MM -extern struct dram_timing_info dram_timing_512mb; -extern struct dram_timing_info dram_timing_1gb; -extern struct dram_timing_info dram_timing_2gb; -extern struct dram_timing_info dram_timing_4gb; -#elif CONFIG_IMX8MN -extern struct dram_timing_info dram_timing_1gb_single_die; -extern struct dram_timing_info dram_timing_2gb_single_die; -extern struct dram_timing_info dram_timing_2gb_dual_die; -#elif CONFIG_IMX8MP -extern struct dram_timing_info dram_timing_1gb_single_die; -extern struct dram_timing_info dram_timing_4gb_dual_die; -#endif +extern struct dram_timing_info *spl_dram_init(const char *model, int sizemb); #endif /* __LPDDR4_TIMING_H__ */ diff --git a/board/gateworks/venice/lpddr4_timing_imx8mm.c b/board/gateworks/venice/lpddr4_timing_imx8mm.c index 3f2c090a94f..956071c5125 100644 --- a/board/gateworks/venice/lpddr4_timing_imx8mm.c +++ b/board/gateworks/venice/lpddr4_timing_imx8mm.c @@ -6,6 +6,7 @@ */ #include <linux/kernel.h> +#include <string.h> #include <asm/arch/ddr.h> #include <asm/arch/lpddr4_define.h> @@ -1333,7 +1334,7 @@ static struct dram_cfg_param ddr_ddrc_cfg_512mb[] = { { 0x3d400304, 0x1 }, { 0x3d400030, 0x1 }, { 0x3d400000, 0xa1080020 }, - { 0x3d400020, 0x203 }, + { 0x3d400020, 0x223 }, { 0x3d400024, 0x3a980 }, { 0x3d400064, 0x5b0062 }, { 0x3d4000d0, 0xc00305ba }, @@ -1385,7 +1386,7 @@ static struct dram_cfg_param ddr_ddrc_cfg_512mb[] = { { 0x3d400498, 0x620096 }, { 0x3d40049c, 0x1100e07 }, { 0x3d4004a0, 0xc8012c }, - { 0x3d402020, 0x1 }, + { 0x3d402020, 0x21 }, { 0x3d402024, 0x7d00 }, { 0x3d402050, 0x20d040 }, { 0x3d402064, 0xc000d }, @@ -1410,7 +1411,7 @@ static struct dram_cfg_param ddr_ddrc_cfg_512mb[] = { { 0x3d402194, 0x80303 }, { 0x3d4021b4, 0x100 }, { 0x3d4020f4, 0xc99 }, - { 0x3d403020, 0x1 }, + { 0x3d403020, 0x21 }, { 0x3d403024, 0x1f40 }, { 0x3d403050, 0x20d040 }, { 0x3d403064, 0x30004 }, @@ -1459,9 +1460,9 @@ static struct dram_cfg_param ddr_ddrphy_cfg_512mb[] = { { 0x120a0, 0x0 }, { 0x120a1, 0x1 }, { 0x120a2, 0x3 }, - { 0x120a3, 0x4 }, + { 0x120a3, 0x2 }, { 0x120a4, 0x5 }, - { 0x120a5, 0x2 }, + { 0x120a5, 0x4 }, { 0x120a6, 0x7 }, { 0x120a7, 0x6 }, { 0x130a0, 0x0 }, @@ -1830,7 +1831,7 @@ static struct dram_fsp_msg ddr_dram_fsp_msg_512mb[] = { }; /* ddr timing config params */ -struct dram_timing_info dram_timing_512mb = { +static struct dram_timing_info dram_timing_512mb = { .ddrc_cfg = ddr_ddrc_cfg_512mb, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_512mb), .ddrphy_cfg = ddr_ddrphy_cfg_512mb, @@ -2489,7 +2490,7 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg_1gb[] = { }; /* lpddr4 timing config params */ -struct dram_timing_info dram_timing_1gb = { +static struct dram_timing_info dram_timing_1gb = { .ddrc_cfg = lpddr4_ddrc_cfg_1gb, .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg_1gb), .ddrphy_cfg = lpddr4_ddrphy_cfg_1gb, @@ -3005,7 +3006,7 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg_4gb[] = { }; /* lpddr4 timing config params */ -struct dram_timing_info dram_timing_4gb = { +static struct dram_timing_info dram_timing_4gb = { .ddrc_cfg = lpddr4_ddrc_cfg_4gb, .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg_4gb), .ddrphy_cfg = lpddr4_ddrphy_cfg_4gb, @@ -3140,12 +3141,12 @@ static struct dram_cfg_param lpddr4_ddrphy_cfg_2gb[] = { { 0x100a7, 0x7 }, { 0x110a0, 0x0 }, { 0x110a1, 0x1 }, - { 0x110a2, 0x2 }, - { 0x110a3, 0x3 }, - { 0x110a4, 0x4 }, - { 0x110a5, 0x5 }, - { 0x110a6, 0x6 }, - { 0x110a7, 0x7 }, + { 0x110a2, 0x3 }, + { 0x110a3, 0x4 }, + { 0x110a4, 0x5 }, + { 0x110a5, 0x2 }, + { 0x110a6, 0x7 }, + { 0x110a7, 0x6 }, { 0x120a0, 0x0 }, { 0x120a1, 0x1 }, { 0x120a2, 0x3 }, @@ -3156,12 +3157,12 @@ static struct dram_cfg_param lpddr4_ddrphy_cfg_2gb[] = { { 0x120a7, 0x6 }, { 0x130a0, 0x0 }, { 0x130a1, 0x1 }, - { 0x130a2, 0x5 }, - { 0x130a3, 0x2 }, - { 0x130a4, 0x3 }, - { 0x130a5, 0x4 }, - { 0x130a6, 0x7 }, - { 0x130a7, 0x6 }, + { 0x130a2, 0x2 }, + { 0x130a3, 0x3 }, + { 0x130a4, 0x4 }, + { 0x130a5, 0x5 }, + { 0x130a6, 0x6 }, + { 0x130a7, 0x7 }, { 0x1005f, 0x1ff }, { 0x1015f, 0x1ff }, { 0x1105f, 0x1ff }, @@ -3521,7 +3522,7 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg_2gb[] = { }; /* lpddr4 timing config params */ -struct dram_timing_info dram_timing_2gb = { +static struct dram_timing_info dram_timing_2gb = { .ddrc_cfg = lpddr4_ddrc_cfg_2gb, .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg_2gb), .ddrphy_cfg = lpddr4_ddrphy_cfg_2gb, @@ -3534,3 +3535,63 @@ struct dram_timing_info dram_timing_2gb = { .ddrphy_pie_num = ARRAY_SIZE(lpddr4_phy_pie), .fsp_table = { 3000, 400, 100, }, }; + +static void apply_cfg_patch(struct dram_cfg_param *cfg, int cfg_sz, + struct dram_cfg_param *patch, int patch_sz) +{ + int i, j; + + for (i = 0; i < cfg_sz; i++) + for (j = 0; j < patch_sz; j++) + if (cfg[i].reg == patch[j].reg) + cfg[i].val = patch[j].val; +} + +static struct dram_cfg_param ddr_ddrc_cfg_alt_patch[] = { + { 0x3d400020, 0x203}, + { 0x3d402020, 0x1}, + { 0x3d403020, 0x1} +}; + +static struct dram_cfg_param ddr_ddrphy_cfg_alt_patch[] = { + { 0x120a3, 0x4 }, + { 0x120a5, 0x2 }, +}; + +struct dram_timing_info *spl_dram_init(const char *model, int sizemb) +{ + struct dram_timing_info *dram_timing; + + switch (sizemb) { + case 512: + dram_timing = &dram_timing_512mb; + break; + case 1024: + dram_timing = &dram_timing_1gb; + break; + case 2048: + dram_timing = &dram_timing_2gb; + break; + case 4096: + dram_timing = &dram_timing_4gb; + break; + default: + printf("unsupported"); + dram_timing = &dram_timing_1gb; + } + + /* apply ddrc/phy register changes for alternate dram bus layout */ + if (!strncmp(model, "GW7902", 6) || + !strncmp(model, "GW7903", 6) || + !strncmp(model, "GW7904", 6)) { + apply_cfg_patch(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num, + ddr_ddrc_cfg_alt_patch, + ARRAY_SIZE(ddr_ddrc_cfg_alt_patch)); + + apply_cfg_patch(dram_timing->ddrphy_cfg, dram_timing->ddrphy_cfg_num, + ddr_ddrphy_cfg_alt_patch, + ARRAY_SIZE(ddr_ddrphy_cfg_alt_patch)); + } + + return dram_timing; +} diff --git a/board/gateworks/venice/lpddr4_timing_imx8mn.c b/board/gateworks/venice/lpddr4_timing_imx8mn.c index 9ba2d2571ce..e7d04822c9c 100644 --- a/board/gateworks/venice/lpddr4_timing_imx8mn.c +++ b/board/gateworks/venice/lpddr4_timing_imx8mn.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include <linux/kernel.h> +#include <string.h> #include <asm/arch/ddr.h> /* @@ -1425,7 +1426,7 @@ static struct dram_fsp_msg ddr_dram_fsp_msg_1gb_single_die[] = { }; /* ddr timing config params */ -struct dram_timing_info dram_timing_1gb_single_die = { +static struct dram_timing_info dram_timing_1gb_single_die = { .ddrc_cfg = ddr_ddrc_cfg_1gb_single_die, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_1gb_single_die), .ddrphy_cfg = ddr_ddrphy_cfg_1gb_single_die, @@ -1890,7 +1891,7 @@ static struct dram_fsp_msg ddr_dram_fsp_msg_2gb_single_die[] = { }; /* ddr timing config params */ -struct dram_timing_info dram_timing_2gb_single_die = { +static struct dram_timing_info dram_timing_2gb_single_die = { .ddrc_cfg = ddr_ddrc_cfg_2gb_single_die, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_2gb_single_die), .ddrphy_cfg = ddr_ddrphy_cfg_2gb_single_die, @@ -2354,7 +2355,7 @@ static struct dram_fsp_msg ddr_dram_fsp_msg_2gb_dual_die[] = { }; /* ddr timing config params */ -struct dram_timing_info dram_timing_2gb_dual_die = { +static struct dram_timing_info dram_timing_2gb_dual_die = { .ddrc_cfg = ddr_ddrc_cfg_2gb_dual_die, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_2gb_dual_die), .ddrphy_cfg = ddr_ddrphy_cfg_2gb_dual_die, @@ -2367,3 +2368,27 @@ struct dram_timing_info dram_timing_2gb_dual_die = { .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), .fsp_table = { 3200, 400, 100, }, }; + +struct dram_timing_info *spl_dram_init(const char *model, int sizemb) +{ + struct dram_timing_info *dram_timing; + + switch (sizemb) { + case 1024: + dram_timing = &dram_timing_1gb_single_die; + break; + case 2048: + if (!strcmp(model, "GW7902-SP466-A") || + !strcmp(model, "GW7902-SP466-B")) { + dram_timing = &dram_timing_2gb_dual_die; + } else { + dram_timing = &dram_timing_2gb_single_die; + } + break; + default: + printf("unsupported"); + dram_timing = &dram_timing_2gb_dual_die; + } + + return dram_timing; +} diff --git a/board/gateworks/venice/lpddr4_timing_imx8mp.c b/board/gateworks/venice/lpddr4_timing_imx8mp.c index 56c6e2b5cff..36c4cb147e8 100644 --- a/board/gateworks/venice/lpddr4_timing_imx8mp.c +++ b/board/gateworks/venice/lpddr4_timing_imx8mp.c @@ -1832,7 +1832,7 @@ struct dram_fsp_msg ddr_dram_fsp_msg_1gb_single_die[] = { }; /* ddr timing config params */ -struct dram_timing_info dram_timing_1gb_single_die = { +static struct dram_timing_info dram_timing_1gb_single_die = { .ddrc_cfg = ddr_ddrc_cfg_1gb_single_die, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_1gb_single_die), .ddrphy_cfg = ddr_ddrphy_cfg_1gb_single_die, @@ -2364,7 +2364,7 @@ static struct dram_fsp_msg ddr_dram_fsp_msg_4gb_dual_die[] = { }; /* ddr timing config params */ -struct dram_timing_info dram_timing_4gb_dual_die = { +static struct dram_timing_info dram_timing_4gb_dual_die = { .ddrc_cfg = ddr_ddrc_cfg_4gb_dual_die, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg_4gb_dual_die), .ddrphy_cfg = ddr_ddrphy_cfg_4gb_dual_die, @@ -2377,3 +2377,22 @@ struct dram_timing_info dram_timing_4gb_dual_die = { .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), .fsp_table = { 4000, 400, 100, }, }; + +struct dram_timing_info *spl_dram_init(const char *model, int sizemb) +{ + struct dram_timing_info *dram_timing; + + switch (sizemb) { + case 1024: + dram_timing = &dram_timing_1gb_single_die; + break; + case 4096: + dram_timing = &dram_timing_4gb_dual_die; + break; + default: + printf("unsupported"); + dram_timing = &dram_timing_4gb_dual_die; + } + + return dram_timing; +} diff --git a/board/gateworks/venice/spl.c b/board/gateworks/venice/spl.c index bcdc1a2a468..e813f3e763e 100644 --- a/board/gateworks/venice/spl.c +++ b/board/gateworks/venice/spl.c @@ -32,69 +32,6 @@ #define PCIE_RSTN IMX_GPIO_NR(4, 6) -static void spl_dram_init(int size) -{ - struct dram_timing_info *dram_timing; - - switch (size) { -#ifdef CONFIG_IMX8MM - case 512: - dram_timing = &dram_timing_512mb; - break; - case 1024: - dram_timing = &dram_timing_1gb; - break; - case 2048: - dram_timing = &dram_timing_2gb; - break; - case 4096: - dram_timing = &dram_timing_4gb; - break; - default: - printf("Unknown DDR configuration: %d MiB\n", size); - dram_timing = &dram_timing_1gb; - size = 1024; -#elif CONFIG_IMX8MN - case 1024: - dram_timing = &dram_timing_1gb_single_die; - break; - case 2048: - if (!strcmp(eeprom_get_model(), "GW7902-SP466-A") || - !strcmp(eeprom_get_model(), "GW7902-SP466-B")) { - dram_timing = &dram_timing_2gb_dual_die; - } else { - dram_timing = &dram_timing_2gb_single_die; - } - break; - default: - printf("Unknown DDR configuration: %d MiB\n", size); - dram_timing = &dram_timing_2gb_dual_die; - size = 2048; -#elif CONFIG_IMX8MP - case 1024: - dram_timing = &dram_timing_1gb_single_die; - break; - case 4096: - dram_timing = &dram_timing_4gb_dual_die; - break; - default: - printf("Unknown DDR configuration: %d GiB\n", size); - dram_timing = &dram_timing_4gb_dual_die; - size = 4096; -#endif - } - - printf("DRAM : LPDDR4 "); - if (size > 512) - printf("%d GiB", size / 1024); - else - printf("%d MiB", size); - printf(" %dMT/s %dMHz\n", - dram_timing->fsp_msg[0].drate, - dram_timing->fsp_msg[0].drate / 2); - ddr_init(dram_timing); -} - /* * Model specific PMIC adjustments necessary prior to DRAM init * @@ -118,21 +55,23 @@ static int dm_i2c_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set) return dm_i2c_write(dev, reg, &val, 1); } -static int power_init_board(struct udevice *gsc) +static int power_init_board(const char *model, struct udevice *gsc) { - const char *model = eeprom_get_model(); + const char *som = eeprom_get_som_model(); struct udevice *bus; struct udevice *dev; int ret; - /* Enable GSC voltage supervisor for new board models */ - if ((!strncmp(model, "GW7100", 6) && model[10] > 'D') || - (!strncmp(model, "GW7101", 6) && model[10] > 'D') || - (!strncmp(model, "GW7200", 6) && model[10] > 'E') || - (!strncmp(model, "GW7201", 6) && model[10] > 'E') || - (!strncmp(model, "GW7300", 6) && model[10] > 'E') || - (!strncmp(model, "GW7301", 6) && model[10] > 'E') || - (!strncmp(model, "GW740", 5) && model[7] > 'B')) { + /* Enable GSC voltage supervisor only for newew board models */ + if ((!strncmp(model, "GW7100", 6) && model[10] < 'E') || + (!strncmp(model, "GW7101", 6) && model[10] < 'E') || + (!strncmp(model, "GW7200", 6) && model[10] < 'F') || + (!strncmp(model, "GW7201", 6) && model[10] < 'F') || + (!strncmp(model, "GW7300", 6) && model[10] < 'F') || + (!strncmp(model, "GW7301", 6) && model[10] < 'F') || + (!strncmp(model, "GW740", 5) && model[7] < 'C')) { + printf("GSC : voltage supervisor disabled\n"); + } else { u8 ver; if (!dm_i2c_read(gsc, 14, &ver, 1) && ver > 62) { @@ -141,10 +80,7 @@ static int power_init_board(struct udevice *gsc) } } - if ((!strncmp(model, "GW71", 4)) || - (!strncmp(model, "GW72", 4)) || - (!strncmp(model, "GW73", 4)) || - (!strncmp(model, "GW75", 4))) { + if (!strncmp(som, "GW70", 4)) { ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus); if (ret) { printf("PMIC : failed I2C1 probe: %d\n", ret); @@ -251,9 +187,11 @@ static int power_init_board(struct udevice *gsc) void board_init_f(ulong dummy) { + struct dram_timing_info *dram_timing; struct udevice *bus, *dev; + const char *model; + int dram_szmb; int i, ret; - int dram_sz; arch_cpu_init(); @@ -311,13 +249,23 @@ void board_init_f(ulong dummy) break; mdelay(1); } - dram_sz = venice_eeprom_init(0); + dram_szmb = venice_eeprom_init(0); + model = eeprom_get_model(); /* PMIC */ - power_init_board(dev); + power_init_board(model, dev); /* DDR initialization */ - spl_dram_init(dram_sz); + printf("DRAM : LPDDR4 "); + if (dram_szmb > 512) + printf("%d GiB", dram_szmb / 1024); + else + printf("%d MiB", dram_szmb); + dram_timing = spl_dram_init(model, dram_szmb); + printf(" %dMT/s %dMHz\n", + dram_timing->fsp_msg[0].drate, + dram_timing->fsp_msg[0].drate / 2); + ddr_init(dram_timing); board_init_r(NULL, 0); } diff --git a/board/gateworks/venice/venice.c b/board/gateworks/venice/venice.c index 98b33624f04..6a24f618ae2 100644 --- a/board/gateworks/venice/venice.c +++ b/board/gateworks/venice/venice.c @@ -3,6 +3,7 @@ * Copyright 2021 Gateworks Corporation */ +#include <env.h> #include <fdt_support.h> #include <init.h> #include <led.h> @@ -14,6 +15,7 @@ #include <asm/mach-imx/boot_mode.h> #include "eeprom.h" +#include "../fsa.h" int board_phys_sdram_size(phys_size_t *size) { @@ -75,6 +77,9 @@ int board_init(void) { venice_eeprom_init(1); + /* detect and configure FSA adapters */ + fsa_init(); + return 0; } @@ -221,6 +226,9 @@ int ft_board_setup(void *fdt, struct bd_info *bd) /* set board model dt prop */ fdt_setprop_string(fdt, 0, "board", eeprom_get_model()); + /* fixups for FSA adapters */ + fsa_ft_fixup(fdt); + if (!strncmp(base_model, "GW73", 4)) { pcbrev = get_pcb_rev(base_model); path = fdt_get_alias(fdt, "ethernet1"); diff --git a/board/ge/b1x5v2/b1x5v2.c b/board/ge/b1x5v2/b1x5v2.c index c1aacd1458b..ddb7304d493 100644 --- a/board/ge/b1x5v2/b1x5v2.c +++ b/board/ge/b1x5v2/b1x5v2.c @@ -17,6 +17,7 @@ #include <asm/io.h> #include <asm/mach-imx/video.h> #include <command.h> +#include <env.h> #include <i2c.h> #include <input.h> #include <ipu_pixfmt.h> diff --git a/board/google/chameleonv3/board.c b/board/google/chameleonv3/board.c index 4d3049689d3..d8ffdd25b38 100644 --- a/board/google/chameleonv3/board.c +++ b/board/google/chameleonv3/board.c @@ -2,6 +2,8 @@ /* * Copyright 2022 Google LLC */ + +#include <env.h> #include <net.h> #include <errno.h> #include "mercury_aa1.h" diff --git a/board/keymile/kmcent2/kmcent2.c b/board/keymile/kmcent2/kmcent2.c index 783853d5c6f..0f43ebfec4d 100644 --- a/board/keymile/kmcent2/kmcent2.c +++ b/board/keymile/kmcent2/kmcent2.c @@ -6,6 +6,7 @@ * Copyright 2013 Freescale Semiconductor, Inc. */ +#include <env.h> #include <event.h> #include <asm/cache.h> #include <asm/fsl_fdt.h> diff --git a/board/liebherr/mccmon6/spl.c b/board/liebherr/mccmon6/spl.c index b1f6881275d..e612d9e9ce0 100644 --- a/board/liebherr/mccmon6/spl.c +++ b/board/liebherr/mccmon6/spl.c @@ -5,6 +5,7 @@ * Richard Hu <hakahu@gmail.com> */ +#include <env.h> #include <image.h> #include <init.h> #include <asm/arch/clock.h> diff --git a/board/liebherr/xea/xea.c b/board/liebherr/xea/xea.c index 1d4f165fd13..9630e7f576b 100644 --- a/board/liebherr/xea/xea.c +++ b/board/liebherr/xea/xea.c @@ -13,6 +13,7 @@ * */ +#include <env.h> #include <fdt_support.h> #include <init.h> #include <log.h> diff --git a/board/phytec/common/k3/board.c b/board/phytec/common/k3/board.c index 828973a8e28..d9aec16b090 100644 --- a/board/phytec/common/k3/board.c +++ b/board/phytec/common/k3/board.c @@ -121,24 +121,37 @@ enum env_location env_get_location(enum env_operation op, int prio) } #if IS_ENABLED(CONFIG_BOARD_LATE_INIT) -int board_late_init(void) +/** + * Ensure the boot order favors the device we just booted from. + * If boot_targets is still at its default value, move the current + * boot device to the front of the list. Otherwise, leave any customized + * order untouched. + */ +static void boot_targets_setup(void) { u32 boot_device = get_boot_device(); + const char *boot_targets = NULL; + char boot_targets_default[100]; + int ret; switch (boot_device) { case BOOT_DEVICE_MMC1: env_set_ulong("mmcdev", 0); env_set("boot", "mmc"); + boot_targets = "mmc0 mmc1 spi_flash dhcp"; break; case BOOT_DEVICE_MMC2: env_set_ulong("mmcdev", 1); env_set("boot", "mmc"); + boot_targets = "mmc1 mmc0 spi_flash dhcp"; break; case BOOT_DEVICE_SPI: env_set("boot", "spi"); + boot_targets = "spi_flash mmc0 mmc1 dhcp"; break; case BOOT_DEVICE_ETHERNET: env_set("boot", "net"); + boot_targets = "dhcp mmc0 mmc1 spi_flash"; break; case BOOT_DEVICE_UART: env_set("boot", "uart"); @@ -148,26 +161,49 @@ int board_late_init(void) break; }; - if (IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION_BLOCKS)) { - struct phytec_api3_element *block_element; - struct phytec_eeprom_data data; - int ret; - - ret = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR); - if (ret || !data.valid) - return 0; - - PHYTEC_API3_FOREACH_BLOCK(block_element, &data) { - switch (block_element->block_type) { - case PHYTEC_API3_BLOCK_MAC: - phytec_blocks_add_mac_to_env(block_element); - break; - default: - debug("%s: Unknown block type %i\n", __func__, - block_element->block_type); - } + if (!boot_targets) + return; + + ret = env_get_default_into("boot_targets", boot_targets_default, sizeof(boot_targets_default)); + if (ret < 0) + boot_targets_default[0] = '\0'; + + if (strcmp(boot_targets_default, env_get("boot_targets"))) { + debug("boot_targets not default, don't change it\n"); + return; + } + + env_set("boot_targets", boot_targets); +} + +static void setup_mac_from_eeprom(void) +{ + struct phytec_api3_element *block_element; + struct phytec_eeprom_data data; + int ret; + + ret = phytec_eeprom_data_setup(&data, 0, EEPROM_ADDR); + if (ret || !data.valid) + return; + + PHYTEC_API3_FOREACH_BLOCK(block_element, &data) { + switch (block_element->block_type) { + case PHYTEC_API3_BLOCK_MAC: + phytec_blocks_add_mac_to_env(block_element); + break; + default: + debug("%s: Unknown block type %i\n", __func__, + block_element->block_type); } } +} + +int board_late_init(void) +{ + boot_targets_setup(); + + if (IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION_BLOCKS)) + setup_mac_from_eeprom(); #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) configure_capsule_updates(); diff --git a/board/phytec/common/phytec_som_detection_blocks.c b/board/phytec/common/phytec_som_detection_blocks.c index 5f3c27ef0c2..b44ff85972f 100644 --- a/board/phytec/common/phytec_som_detection_blocks.c +++ b/board/phytec/common/phytec_som_detection_blocks.c @@ -4,6 +4,7 @@ * Author: Daniel Schultz <d.schultz@phytec.de> */ +#include <env.h> #include <malloc.h> #include <u-boot/crc.h> #include <net.h> diff --git a/board/phytec/phycore_am62ax/phycore_am62ax.env b/board/phytec/phycore_am62ax/phycore_am62ax.env index 40787b0cbcb..797904013dc 100644 --- a/board/phytec/phycore_am62ax/phycore_am62ax.env +++ b/board/phytec/phycore_am62ax/phycore_am62ax.env @@ -24,3 +24,6 @@ get_cmd=tftp spi_fdt_addr=0x700000 spi_image_addr=0x800000 spi_ramdisk_addr=0x2200000 + +bootmeths=script efi extlinux pxe +boot_targets=mmc1 mmc0 spi_flash dhcp diff --git a/board/phytec/phycore_am62x/phycore_am62x.env b/board/phytec/phycore_am62x/phycore_am62x.env index 5c48e856685..797904013dc 100644 --- a/board/phytec/phycore_am62x/phycore_am62x.env +++ b/board/phytec/phycore_am62x/phycore_am62x.env @@ -10,6 +10,7 @@ fdt_addr_r=0x88000000 kernel_addr_r=0x82000000 ramdisk_addr_r=0x88080000 fdtoverlay_addr_r=0x89000000 +fit_addr_r=0x90000000 fdtfile=CONFIG_DEFAULT_FDT_FILE mmcdev=1 @@ -23,3 +24,6 @@ get_cmd=tftp spi_fdt_addr=0x700000 spi_image_addr=0x800000 spi_ramdisk_addr=0x2200000 + +bootmeths=script efi extlinux pxe +boot_targets=mmc1 mmc0 spi_flash dhcp diff --git a/board/phytec/phycore_am64x/phycore_am64x.env b/board/phytec/phycore_am64x/phycore_am64x.env index d69dfe75674..36ab16e2f7a 100644 --- a/board/phytec/phycore_am64x/phycore_am64x.env +++ b/board/phytec/phycore_am64x/phycore_am64x.env @@ -9,6 +9,7 @@ fdt_addr_r=0x88000000 kernel_addr_r=0x82000000 ramdisk_addr_r=0x88080000 fdtoverlay_addr_r=0x89000000 +fit_addr_r=0x90000000 fdtfile=CONFIG_DEFAULT_FDT_FILE mmcdev=1 @@ -22,3 +23,6 @@ get_cmd=tftp spi_fdt_addr=0x700000 spi_image_addr=0x800000 spi_ramdisk_addr=0x2200000 + +bootmeths=script efi extlinux pxe +boot_targets=mmc1 mmc0 spi_flash dhcp diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index 718f89a084a..7393061707d 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -3,8 +3,6 @@ M: Mathieu Othacehe <m.othacehe@gmail.com> R: Christoph Stoidner <c.stoidner@phytec.de> W: https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/ S: Maintained -F: arch/arm/dts/imx93-phyboard-segin.dts -F: arch/arm/dts/imx93-phycore-som.dtsi F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ F: board/phytec/common/imx93_som_detection.c diff --git a/board/purism/librem5/librem5.c b/board/purism/librem5/librem5.c index 8ca8792fa42..5178ee6929d 100644 --- a/board/purism/librem5/librem5.c +++ b/board/purism/librem5/librem5.c @@ -6,6 +6,7 @@ #include <malloc.h> #include <errno.h> +#include <env.h> #include <asm/io.h> #include <miiphy.h> #include <asm/mach-imx/iomux-v3.h> diff --git a/board/ronetix/imx8mq-cm/imx8mq_cm.c b/board/ronetix/imx8mq-cm/imx8mq_cm.c index fbee2c39771..602216854ba 100644 --- a/board/ronetix/imx8mq-cm/imx8mq_cm.c +++ b/board/ronetix/imx8mq-cm/imx8mq_cm.c @@ -3,6 +3,7 @@ * Copyright 2018 NXP */ +#include <env.h> #include <miiphy.h> #include <asm-generic/gpio.h> #include <asm/arch/imx8mq_pins.h> diff --git a/board/siemens/common/board_am335x.c b/board/siemens/common/board_am335x.c index daf0bb930ec..939ff81797d 100644 --- a/board/siemens/common/board_am335x.c +++ b/board/siemens/common/board_am335x.c @@ -10,6 +10,7 @@ */ #include <command.h> +#include <env.h> #include <serial.h> #include <watchdog.h> #include <asm/arch/clock.h> diff --git a/board/siemens/iot2050/board.c b/board/siemens/iot2050/board.c index d827f728a08..161210c60a9 100644 --- a/board/siemens/iot2050/board.c +++ b/board/siemens/iot2050/board.c @@ -11,6 +11,7 @@ #include <config.h> #include <bootstage.h> #include <dm.h> +#include <env.h> #include <fdt_support.h> #include <i2c.h> #include <led.h> diff --git a/board/socionext/developerbox/fwu_plat.c b/board/socionext/developerbox/fwu_plat.c index a8b111477ef..5d2f40f241c 100644 --- a/board/socionext/developerbox/fwu_plat.c +++ b/board/socionext/developerbox/fwu_plat.c @@ -4,6 +4,7 @@ */ #include <efi_loader.h> +#include <env.h> #include <fwu.h> #include <fwu_mdata.h> #include <memalign.h> diff --git a/board/technexion/pico-imx7d/pico-imx7d.c b/board/technexion/pico-imx7d/pico-imx7d.c index d0f739c624a..cf6b7fcbd95 100644 --- a/board/technexion/pico-imx7d/pico-imx7d.c +++ b/board/technexion/pico-imx7d/pico-imx7d.c @@ -3,6 +3,7 @@ * Copyright (C) 2017 NXP Semiconductors */ +#include <env.h> #include <init.h> #include <net.h> #include <asm/arch/clock.h> diff --git a/board/thead/th1520_lpi4a/Kconfig b/board/thead/th1520_lpi4a/Kconfig index 622246127c1..f139d5ff2bb 100644 --- a/board/thead/th1520_lpi4a/Kconfig +++ b/board/thead/th1520_lpi4a/Kconfig @@ -11,7 +11,7 @@ config SYS_VENDOR default "thead" config SYS_CPU - default "generic" + default "th1520" config SYS_CONFIG_NAME default "th1520_lpi4a" @@ -22,7 +22,7 @@ config TEXT_BASE default 0x01c00000 if RISCV_SMODE config SPL_TEXT_BASE - default 0x08000000 + default 0xffe0000000 config SPL_OPENSBI_LOAD_ADDR default 0x80000000 @@ -30,6 +30,7 @@ config SPL_OPENSBI_LOAD_ADDR config BOARD_SPECIFIC_OPTIONS def_bool y select ARCH_EARLY_INIT_R + select THEAD_TH1520 imply CPU imply CPU_RISCV imply RISCV_TIMER if RISCV_SMODE diff --git a/board/thead/th1520_lpi4a/Makefile b/board/thead/th1520_lpi4a/Makefile index 9671b3bbb0b..a7ddfc48d40 100644 --- a/board/thead/th1520_lpi4a/Makefile +++ b/board/thead/th1520_lpi4a/Makefile @@ -3,3 +3,4 @@ # Copyright (c) 2023, Yixun Lan <dlan@gentoo.org> obj-y += board.o +obj-$(CONFIG_XPL_BUILD) += spl.o diff --git a/board/thead/th1520_lpi4a/spl.c b/board/thead/th1520_lpi4a/spl.c new file mode 100644 index 00000000000..25dfa387c36 --- /dev/null +++ b/board/thead/th1520_lpi4a/spl.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025, Yao Zi <ziyao@disroot.org> + */ + +#include <asm/io.h> +#include <asm/spl.h> +#include <asm/arch/cpu.h> +#include <asm/arch/spl.h> +#include <cpu_func.h> +#include <dm.h> +#include <hang.h> +#include <spl.h> + +u32 spl_boot_device(void) +{ + /* + * We don't bother to load proper U-Boot from an external device as + * it fits in the integrated SRAM nicely. + */ + return BOOT_DEVICE_RAM; +} + +void board_init_f(ulong dummy) +{ + int ret = spl_early_init(); + struct udevice *dev; + + if (ret) + panic("spl_early_init() failed %d\n", ret); + + preloader_console_init(); + + /* + * Manually bind CPU ahead of time to make sure in-core timers are + * available in SPL. + */ + ret = uclass_get_device(UCLASS_CPU, 0, &dev); + if (ret) + panic("failed to bind CPU: %d\n", ret); + + spl_dram_init(); + + icache_enable(); + dcache_enable(); + + th1520_invalidate_pmp(); +} diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c index 0525f6e6f97..b1ed29af001 100644 --- a/board/ti/j721e/evm.c +++ b/board/ti/j721e/evm.c @@ -8,6 +8,7 @@ */ #include <efi_loader.h> +#include <env.h> #include <generic-phy.h> #include <image.h> #include <net.h> diff --git a/board/toradex/apalis_imx6/do_fuse.c b/board/toradex/apalis_imx6/do_fuse.c index 698b05bc5ad..8721276bed8 100644 --- a/board/toradex/apalis_imx6/do_fuse.c +++ b/board/toradex/apalis_imx6/do_fuse.c @@ -11,6 +11,7 @@ #include <command.h> #include <console.h> #include <fuse.h> +#include <linux/string.h> static int mfgr_fuse(void) { diff --git a/board/toradex/colibri_imx6/do_fuse.c b/board/toradex/colibri_imx6/do_fuse.c index 698b05bc5ad..8721276bed8 100644 --- a/board/toradex/colibri_imx6/do_fuse.c +++ b/board/toradex/colibri_imx6/do_fuse.c @@ -11,6 +11,7 @@ #include <command.h> #include <console.h> #include <fuse.h> +#include <linux/string.h> static int mfgr_fuse(void) { diff --git a/board/toradex/colibri_imx7/colibri_imx7.c b/board/toradex/colibri_imx7/colibri_imx7.c index 7de29e3abfb..69a8a18d3a7 100644 --- a/board/toradex/colibri_imx7/colibri_imx7.c +++ b/board/toradex/colibri_imx7/colibri_imx7.c @@ -4,6 +4,7 @@ */ #include <cpu_func.h> +#include <env.h> #include <init.h> #include <net.h> #include <asm/arch/clock.h> diff --git a/board/toradex/verdin-imx8mm/verdin-imx8mm.c b/board/toradex/verdin-imx8mm/verdin-imx8mm.c index 9359e0ac6bf..066e8db678f 100644 --- a/board/toradex/verdin-imx8mm/verdin-imx8mm.c +++ b/board/toradex/verdin-imx8mm/verdin-imx8mm.c @@ -3,7 +3,7 @@ * Copyright 2020-2021 Toradex */ -#include <config.h> +#include <env.h> #include <init.h> #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> |