From ac24244ba4fd0c125c901f00094095ec19c5f7bb Mon Sep 17 00:00:00 2001 From: Christoph Niedermaier Date: Wed, 5 May 2021 18:23:09 +0200 Subject: [PATCH 01/53] ARM: imx6: Update dhelectronics/dh_imx6/MAINTAINERS file Adding new DH electronics mailing list and update list of maintainers. Signed-off-by: Christoph Niedermaier --- board/dhelectronics/dh_imx6/MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/board/dhelectronics/dh_imx6/MAINTAINERS b/board/dhelectronics/dh_imx6/MAINTAINERS index ab4e16bd5d..8f9b5ff2dc 100644 --- a/board/dhelectronics/dh_imx6/MAINTAINERS +++ b/board/dhelectronics/dh_imx6/MAINTAINERS @@ -1,6 +1,7 @@ DH_IMX6 BOARD M: Andreas Geisreiter -M: Ludwig Zenz +M: Christoph Niedermaier +L: u-boot@dh-electronics.com S: Maintained F: board/dhelectronics/dh_imx6/ F: include/configs/dh_imx6.h From 2a7977506915dba43c4dfe56b3054041881bfc2f Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Mon, 7 Jun 2021 14:36:41 +0200 Subject: [PATCH 02/53] mtd: spi-nor-ids: Add support for Macronix MX25V8035F and MX25R1635F The MX25V8035F is a 8Mb SPI NOR flash and the MX25R1635F is very similar, but has twice the size (16Mb) and supports a wider supply voltage range. They were tested on the Kontron Electronics i.MX6UL and i.MX8MM SoMs. Signed-off-by: Frieder Schrempf --- drivers/mtd/spi/spi-nor-ids.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 1af1c86486..6f84c54a47 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -160,6 +160,8 @@ const struct flash_info spi_nor_ids[] = { { INFO("mx25l12855e", 0xc22618, 0, 64 * 1024, 256, 0) }, { INFO("mx25l25635e", 0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("mx25u25635f", 0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) }, + { INFO("mx25v8035f", 0xc22314, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("mx25r1635f", 0xc22815, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0) }, { INFO("mx66l51235l", 0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, From ef62fff2698a425cc6628a9696e8ee1cae725f32 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Mon, 7 Jun 2021 14:36:43 +0200 Subject: [PATCH 03/53] clk: imx8mm: Add SPI clocks Add the clocks for the ECSPI controllers. This is ported from Linux v5.13-rc4. Signed-off-by: Frieder Schrempf --- drivers/clk/imx/clk-imx8mm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index d32ff8409a..3aa8c641f9 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -131,6 +131,15 @@ static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", " static const char *imx8mm_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; +static const char *imx8mm_ecspi1_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + +static const char *imx8mm_ecspi2_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + +static const char *imx8mm_ecspi3_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + static ulong imx8mm_clk_get_rate(struct clk *clk) { struct clk *c; @@ -393,7 +402,19 @@ static int imx8mm_clk_probe(struct udevice *dev) imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100)); clk_dm(IMX8MM_CLK_USB_PHY_REF, imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180)); + clk_dm(IMX8MM_CLK_ECSPI1, + imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280)); + clk_dm(IMX8MM_CLK_ECSPI2, + imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300)); + clk_dm(IMX8MM_CLK_ECSPI3, + imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180)); + clk_dm(IMX8MM_CLK_ECSPI1_ROOT, + imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0)); + clk_dm(IMX8MM_CLK_ECSPI2_ROOT, + imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0)); + clk_dm(IMX8MM_CLK_ECSPI3_ROOT, + imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); clk_dm(IMX8MM_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); clk_dm(IMX8MM_CLK_I2C2_ROOT, From e27bddff4b97598baaa7186196ebfb28075f702c Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Mon, 7 Jun 2021 14:36:44 +0200 Subject: [PATCH 04/53] imx8m: Restrict usable memory to space below 4G boundary Some IPs have their accessible address space restricted by the interconnect. Let's make sure U-Boot only ever uses the space below the 4G address boundary (which is 3GiB big), even when the effective available memory is bigger. We implement board_get_usable_ram_top() for all i.MX8M SoCs, as the whole family is affected by this. Signed-off-by: Frieder Schrempf --- arch/arm/mach-imx/imx8m/soc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 0c44022a6d..f5983320c7 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -296,6 +296,20 @@ phys_size_t get_effective_memsize(void) #endif } +ulong board_get_usable_ram_top(ulong total_size) +{ + /* + * Some IPs have their accessible address space restricted by + * the interconnect. Let's make sure U-Boot only ever uses the + * space below the 4G address boundary (which is 3GiB big), + * even when the effective available memory is bigger. + */ + if (PHYS_SDRAM + gd->ram_size > 0x80000000) + return 0x80000000; + + return PHYS_SDRAM + gd->ram_size; +} + static u32 get_cpu_variant_type(u32 type) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; From ca942ca1d83282ece414fcf5735c0917570c06d7 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:18 -0700 Subject: [PATCH 05/53] imx: ventana: remove USB_KEYBOARD support For some time now having USB_KEYBOARD support has caused usb to be initialized on boot. To allow for a quicker bootup we don't want this for Ventana and don't really need USB keyboard support so remove it. Signed-off-by: Tim Harvey --- configs/gwventana_emmc_defconfig | 1 - configs/gwventana_gw5904_defconfig | 1 - configs/gwventana_nand_defconfig | 1 - 3 files changed, 3 deletions(-) diff --git a/configs/gwventana_emmc_defconfig b/configs/gwventana_emmc_defconfig index 68f4fe8566..5da50c8417 100644 --- a/configs/gwventana_emmc_defconfig +++ b/configs/gwventana_emmc_defconfig @@ -108,7 +108,6 @@ CONFIG_IMX_THERMAL=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y -CONFIG_USB_KEYBOARD=y CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Gateworks" diff --git a/configs/gwventana_gw5904_defconfig b/configs/gwventana_gw5904_defconfig index b6e4cba3ba..8999ac32a6 100644 --- a/configs/gwventana_gw5904_defconfig +++ b/configs/gwventana_gw5904_defconfig @@ -112,7 +112,6 @@ CONFIG_IMX_THERMAL=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y -CONFIG_USB_KEYBOARD=y CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Gateworks" diff --git a/configs/gwventana_nand_defconfig b/configs/gwventana_nand_defconfig index 5d022b63ad..7588395c98 100644 --- a/configs/gwventana_nand_defconfig +++ b/configs/gwventana_nand_defconfig @@ -114,7 +114,6 @@ CONFIG_IMX_THERMAL=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y -CONFIG_USB_KEYBOARD=y CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Gateworks" From 729fd990c90f49953d918b132c7543e540dc5eb9 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:19 -0700 Subject: [PATCH 06/53] imx: ventana: remove unneeded includes remove unnecessary includes Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 1ed9c1a39f..4a6b1dc461 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -6,37 +6,23 @@ */ #include -#include -#include -#include #include #include -#include #include #include #include #include #include #include -#include #include -#include #include -#include #include #include -#include -#include -#include #include #include #include -#include #include -#include #include -#include -#include #include #include From 32328065b573e155497bcf80086fdf1fad90b9f8 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:20 -0700 Subject: [PATCH 07/53] imx: ventana: increase SYS_BOOTM_LEN Increase SYS_BOOM_LEN from the default 16M in imx6_common to 64M. Signed-off-by: Tim Harvey --- include/configs/gw_ventana.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h index 4f2f323b77..f80a3094a1 100644 --- a/include/configs/gw_ventana.h +++ b/include/configs/gw_ventana.h @@ -38,6 +38,9 @@ /* NAND */ #define CONFIG_SYS_MAX_NAND_DEVICE 1 +#undef CONFIG_SYS_BOOTM_LEN +#define CONFIG_SYS_BOOTM_LEN (64 << 20) + /* I2C Configs */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC From 6a4c67859cbea8be251720fe8d99729f63b1ff13 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:21 -0700 Subject: [PATCH 08/53] imx: ventana: add legacy uboot image support Add Legacy U-Boot image support needed to boot a uImage. Signed-off-by: Tim Harvey --- configs/gwventana_emmc_defconfig | 1 - configs/gwventana_gw5904_defconfig | 1 - configs/gwventana_nand_defconfig | 1 - 3 files changed, 3 deletions(-) diff --git a/configs/gwventana_emmc_defconfig b/configs/gwventana_emmc_defconfig index 5da50c8417..2fa30d470a 100644 --- a/configs/gwventana_emmc_defconfig +++ b/configs/gwventana_emmc_defconfig @@ -24,7 +24,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_SPL_LOAD_FIT=y # CONFIG_USE_SPL_FIT_GENERATOR is not set -# CONFIG_LEGACY_IMAGE_FORMAT is not set CONFIG_SUPPORT_RAW_INITRD=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" diff --git a/configs/gwventana_gw5904_defconfig b/configs/gwventana_gw5904_defconfig index 8999ac32a6..5b75fca9f2 100644 --- a/configs/gwventana_gw5904_defconfig +++ b/configs/gwventana_gw5904_defconfig @@ -24,7 +24,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_SPL_LOAD_FIT=y # CONFIG_USE_SPL_FIT_GENERATOR is not set -# CONFIG_LEGACY_IMAGE_FORMAT is not set CONFIG_SUPPORT_RAW_INITRD=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" diff --git a/configs/gwventana_nand_defconfig b/configs/gwventana_nand_defconfig index 7588395c98..16c0374804 100644 --- a/configs/gwventana_nand_defconfig +++ b/configs/gwventana_nand_defconfig @@ -24,7 +24,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_SPL_LOAD_FIT=y # CONFIG_USE_SPL_FIT_GENERATOR is not set -# CONFIG_LEGACY_IMAGE_FORMAT is not set CONFIG_SUPPORT_RAW_INITRD=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" From a32be88da0b2908f464ba6263ef82630b851df59 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:22 -0700 Subject: [PATCH 09/53] imx: ventana: add PMIC fix for GW54xx-G Substitutions in EOL parts changes the VDD_2P5 voltage rail such that the previously unused VGEN6 LDO is needed in place of the lower power VGEN5 for the GW54xx-G. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index 4627a156fe..9f5f20f781 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -1550,6 +1550,17 @@ void setup_pmic(void) int board = read_eeprom(CONFIG_I2C_GSC, &ventana_info); const int i2c_pmic = 1; u32 reg; + char rev; + int i; + + /* determine board revision */ + rev = 'A'; + for (i = sizeof(ventana_info.model) - 1; i > 0; i--) { + if (ventana_info.model[i] >= 'A') { + rev = ventana_info.model[i]; + break; + } + } i2c_set_bus_num(i2c_pmic); @@ -1573,6 +1584,17 @@ void setup_pmic(void) reg &= ~(SWBST_MODE_MASK | SWBST_VOL_MASK); reg |= (SWBST_5_00V | (SWBST_MODE_AUTO << SWBST_MODE_SHIFT)); pmic_reg_write(p, PFUZE100_SWBSTCON1, reg); + + if (board == GW54xx && (rev == 'G')) { + /* Disable VGEN5 */ + pmic_reg_write(p, PFUZE100_VGEN5VOL, 0); + + /* Set VGEN6 to 2.5V and enable */ + pmic_reg_read(p, PFUZE100_VGEN6VOL, ®); + reg &= ~(LDO_VOL_MASK); + reg |= (LDOB_2_50V | LDO_EN); + pmic_reg_write(p, PFUZE100_VGEN6VOL, reg); + } } } From 722d22813e1b79231451059a823d777e2c0867e7 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:23 -0700 Subject: [PATCH 10/53] imx: ventana: put PFUZ100 regulators in continuous mode In the default 'auto' mode regulators that are very lightly loaded can be put in PFM mode and fail to regulator properly. Switching them to always use continuous PWM mode has a neglibable affect on system power and garuntees proper regulation under lightly loaded circumstances. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index 9f5f20f781..b5a0162c5e 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -1596,6 +1596,32 @@ void setup_pmic(void) pmic_reg_write(p, PFUZE100_VGEN6VOL, reg); } } + + /* put all switchers in continuous mode */ + pmic_reg_read(p, PFUZE100_SW1ABMODE, ®); + reg &= ~(SW_MODE_MASK); + reg |= PWM_PWM; + pmic_reg_write(p, PFUZE100_SW1ABMODE, reg); + + pmic_reg_read(p, PFUZE100_SW2MODE, ®); + reg &= ~(SW_MODE_MASK); + reg |= PWM_PWM; + pmic_reg_write(p, PFUZE100_SW2MODE, reg); + + pmic_reg_read(p, PFUZE100_SW3AMODE, ®); + reg &= ~(SW_MODE_MASK); + reg |= PWM_PWM; + pmic_reg_write(p, PFUZE100_SW3AMODE, reg); + + pmic_reg_read(p, PFUZE100_SW3BMODE, ®); + reg &= ~(SW_MODE_MASK); + reg |= PWM_PWM; + pmic_reg_write(p, PFUZE100_SW3BMODE, reg); + + pmic_reg_read(p, PFUZE100_SW4MODE, ®); + reg &= ~(SW_MODE_MASK); + reg |= PWM_PWM; + pmic_reg_write(p, PFUZE100_SW4MODE, reg); } /* configure LTC3676 PMIC */ From 0545b17b695e03ad5ea7bd9736b9cdfc49530af5 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:24 -0700 Subject: [PATCH 11/53] imx: ventana: put LTC3676 regulators in continuous mode In the default pulse-skipping mode regulators that are very lightly loaded can fail to regulate properly. Switching them to always use continuous mode causes only around 10mW of overall system power difference in a lightly loaded system that isn't already operating them in continuous mode. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index b5a0162c5e..adbc6791b3 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -1688,6 +1688,12 @@ void setup_pmic(void) /* set SW3 (VDD_ARM) */ pmic_reg_write(p, LTC3676_DVB3A, 0x1f); } + + /* put all switchers in continuous mode */ + pmic_reg_write(p, LTC3676_BUCK1, 0xc0); + pmic_reg_write(p, LTC3676_BUCK2, 0xc0); + pmic_reg_write(p, LTC3676_BUCK3, 0xc0); + pmic_reg_write(p, LTC3676_BUCK4, 0xc0); } } From 9634c748b14444f6b274521fb2da30f28d310997 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:25 -0700 Subject: [PATCH 12/53] imx: ventana: add DP83867 PHY LED configuration Add DP83867 PHY LED configuration. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 4a6b1dc461..860342dd4a 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -96,6 +96,12 @@ int board_phy_config(struct phy_device *phydev) /* TI DP83867 */ else if (phydev->phy_id == 0x2000a231) { + /* LED configuration */ + val = 0; + val |= 0x5 << 4; /* LED1(Amber;Speed) : 1000BT link */ + val |= 0xb << 8; /* LED2(Green;Link/Act): blink for TX/RX act */ + phy_write(phydev, MDIO_DEVAD_NONE, 24, val); + /* configure register 0x170 for ref CLKOUT */ phy_write(phydev, MDIO_DEVAD_NONE, 13, 0x001f); phy_write(phydev, MDIO_DEVAD_NONE, 14, 0x0170); From e9284c03bc9f415fc5443abc76f9700f975ea5b6 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:26 -0700 Subject: [PATCH 13/53] imx: ventana: display neteowrk PHY Add displaying the detected network PHY on boot. Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 860342dd4a..4536d553ce 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -81,6 +81,7 @@ int board_phy_config(struct phy_device *phydev) /* Marvel 88E1510 */ if (phydev->phy_id == 0x1410dd1) { + puts("MV88E1510"); /* * Page 3, Register 16: LED[2:0] Function Control Register * LED[0] (SPD:Amber) R16_3.3:0 to 0111: on-GbE link @@ -96,6 +97,7 @@ int board_phy_config(struct phy_device *phydev) /* TI DP83867 */ else if (phydev->phy_id == 0x2000a231) { + puts("TIDP83867 "); /* LED configuration */ val = 0; val |= 0x5 << 4; /* LED1(Amber;Speed) : 1000BT link */ From b57b14dc7071e988a9d96dea7546b2d96684873d Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:27 -0700 Subject: [PATCH 14/53] imx: ventana: add support for DLC0700XDP21LF LCD display Add LVDS support for DLC0700XDP21LF 7in 1024x600 display (equivalent to the DLC-700JMGT4 with new touch controller) Signed-off-by: Robert Jones Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/gw_ventana.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 4536d553ce..583f1a26ee 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -245,6 +245,27 @@ struct display_info_t const displays[] = {{ .vsync_len = 10, .sync = FB_SYNC_EXT, .vmode = FB_VMODE_NONINTERLACED +} }, { + /* DLC0700XDP21LF-C-1 */ + .bus = 0, + .addr = 0, + .detect = NULL, + .enable = enable_lvds, + .pixfmt = IPU_PIX_FMT_LVDS666, + .mode = { + .name = "DLC0700XDP21LF", + .refresh = 60, + .xres = 1024, /* 1024x600active pixels */ + .yres = 600, + .pixclock = 15385, /* 64MHz */ + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED } }, { /* DLC800FIG-T-3 */ .bus = 2, From 31273c5af52932c5a2b3e1d5e6a2e668e442d259 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Fri, 11 Jun 2021 12:46:28 -0700 Subject: [PATCH 15/53] imx: ventana: display 'none' for MMC if board does not have it print 'None' instead of just a blank line if nothing is detected: MMC: None Signed-off-by: Tim Harvey --- board/gateworks/gw_ventana/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c index adbc6791b3..c07eb627a2 100644 --- a/board/gateworks/gw_ventana/common.c +++ b/board/gateworks/gw_ventana/common.c @@ -1758,6 +1758,7 @@ int board_mmc_init(struct bd_info *bis) return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); default: /* doesn't have MMC */ + printf("None"); return -1; } } From 364212ca291ca884f692be93d6779ba78311ce12 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 15 Jun 2021 20:38:38 -0300 Subject: [PATCH 16/53] smegw01: Allow booting the Yocto image by default On the Yocto image there is a single partition and the kernel and dtb are present in the 'boot' directory. Change it accordingly so that the board can boot the Yocto image by default. Use the generic 'load' command instead, which is able to read from an ext4 partition. Signed-off-by: Fabio Estevam --- include/configs/smegw01.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/configs/smegw01.h b/include/configs/smegw01.h index 50f00136ac..6f7b46e49b 100644 --- a/include/configs/smegw01.h +++ b/include/configs/smegw01.h @@ -29,11 +29,11 @@ "bootm_size=0x10000000\0" \ "mmcdev=0\0" \ "mmcpart=1\0" \ - "mmcroot=/dev/mmcblk0p2 rootwait rw\0" \ + "mmcroot=/dev/mmcblk0p1 rootwait rw\0" \ "mmcargs=setenv bootargs console=${console},${baudrate} " \ "root=${mmcroot}\0" \ - "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ - "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdtfile}\0" \ + "loadimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} boot/${image}\0" \ + "loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} boot/${fdtfile}\0" \ "mmcboot=echo Booting from mmc ...; " \ "run mmcargs; " \ "if run loadfdt; then " \ From 96f747b1f0e6762bc1b1ce41f4e315431f0c3279 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 15 Jun 2021 20:38:40 -0300 Subject: [PATCH 17/53] smegw01: Select the CMD_UNZIP option Select the CMD_UNZIP option so that the 'gzwrite' command can be used to flash .gz image into the eMMC. Signed-off-by: Fabio Estevam --- configs/smegw01_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/smegw01_defconfig b/configs/smegw01_defconfig index 9bfaa010ae..75fd5bc24a 100644 --- a/configs/smegw01_defconfig +++ b/configs/smegw01_defconfig @@ -21,6 +21,7 @@ CONFIG_CMD_BOOTZ=y # CONFIG_CMD_IMI is not set # CONFIG_CMD_XIMG is not set CONFIG_CMD_MEMTEST=y +CONFIG_CMD_UNZIP=y CONFIG_CMD_DFU=y CONFIG_CMD_GPIO=y CONFIG_CMD_MMC=y From c1f6fd2bb7fa19ec166584c1cce50b5fde93e8ac Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Tue, 6 Jul 2021 10:19:09 -0700 Subject: [PATCH 18/53] pci: imx: use reset-gpios if defined by device-tree If reset-gpio is defined by device-tree use that if CONFIG_PCIE_IMX_PERST_GPIO is not defined. Note that after this the following boards which define CONFIG_PCIE_IMX_PERST_GPIO in their board header file as well as their device-tree should be able to remove CONFIG_PCIE_IMX_PERST_GPIO without consequence: - mx6sabresd - mx6sxsabresd - novena - tbs2910 - vining_2000 Note that the ge_bx50v3 board uses CONFIG_PCIE_IMX_PERST_GPIO and does not have reset-gpios defined it it's pcie node in the dt thus removing CONFIG_PCIE_IMX_PERST_GPIO globally can't be done until that board adds reset-gpios. Cc: Ian Ray (maintainer:GE BX50V3 BOARD) Cc: Sebastian Reichel (maintainer:GE BX50V3 BOARD) Cc: Fabio Estevam (maintainer:MX6SABRESD BOARD) Cc: Marek Vasut (maintainer:NOVENA BOARD) Cc: Soeren Moch (maintainer:TBS2910 BOARD) Cc: Silvio Fricke (maintainer:VINING_2000 BOARD) Signed-off-by: Tim Harvey --- arch/arm/include/asm/arch-mx6/sys_proto.h | 3 ++- board/gateworks/gw_ventana/gw_ventana.c | 2 +- drivers/pci/pcie_imx.c | 29 +++++++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 1e5fa1a75e..c49759af92 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -7,6 +7,7 @@ #ifndef __SYS_PROTO_IMX6_ #define __SYS_PROTO_IMX6_ +#include #include #include @@ -18,7 +19,7 @@ USBPHY_PWD_RXPWDRX)) int imx6_pcie_toggle_power(void); -int imx6_pcie_toggle_reset(void); +int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high); enum ldo_reg { LDO_ARM, diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index 583f1a26ee..468fb093b7 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -372,7 +372,7 @@ int power_init_board(void) return 0; } -int imx6_pcie_toggle_reset(void) +int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high) { if (board_type < GW_UNKNOWN) { uint pin = gpio_cfg[board_type].pcie_rst; diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 73875e00db..7b46fdb89a 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -100,6 +100,8 @@ struct imx_pcie_priv { void __iomem *dbi_base; void __iomem *cfg_base; + struct gpio_desc reset_gpio; + bool reset_active_high; }; /* @@ -541,7 +543,7 @@ __weak int imx6_pcie_toggle_power(void) return 0; } -__weak int imx6_pcie_toggle_reset(void) +__weak int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high) { /* * See 'PCI EXPRESS BASE SPECIFICATION, REV 3.0, SECTION 6.6.1' @@ -579,12 +581,20 @@ __weak int imx6_pcie_toggle_reset(void) mdelay(20); gpio_free(CONFIG_PCIE_IMX_PERST_GPIO); #else - puts("WARNING: Make sure the PCIe #PERST line is connected!\n"); + if (dm_gpio_is_valid(gpio)) { + /* Assert PERST# for 20ms then de-assert */ + dm_gpio_set_value(gpio, active_high ? 0 : 1); + mdelay(20); + dm_gpio_set_value(gpio, active_high ? 1 : 0); + mdelay(20); + } else { + puts("WARNING: Make sure the PCIe #PERST line is connected!\n"); + } #endif return 0; } -static int imx6_pcie_deassert_core_reset(void) +static int imx6_pcie_deassert_core_reset(struct imx_pcie_priv *priv) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; @@ -612,7 +622,7 @@ static int imx6_pcie_deassert_core_reset(void) setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN); #endif - imx6_pcie_toggle_reset(); + imx6_pcie_toggle_reset(&priv->reset_gpio, priv->reset_active_high); return 0; } @@ -625,7 +635,7 @@ static int imx_pcie_link_up(struct imx_pcie_priv *priv) imx6_pcie_assert_core_reset(priv, false); imx6_pcie_init_phy(); - imx6_pcie_deassert_core_reset(); + imx6_pcie_deassert_core_reset(priv); imx_pcie_regions_setup(priv); @@ -787,6 +797,15 @@ static int imx_pcie_dm_probe(struct udevice *dev) { struct imx_pcie_priv *priv = dev_get_priv(dev); + /* if PERST# valid from dt then assert it */ + gpio_request_by_name(dev, "reset-gpio", 0, &priv->reset_gpio, + GPIOD_IS_OUT); + priv->reset_active_high = dev_read_bool(dev, "reset-gpio-active-high"); + if (dm_gpio_is_valid(&priv->reset_gpio)) { + dm_gpio_set_value(&priv->reset_gpio, + priv->reset_active_high ? 0 : 1); + } + return imx_pcie_link_up(priv); } From 6bd1db0a0c0ad04e1fa5a930a075178ddc45824b Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:57:56 +0000 Subject: [PATCH 19/53] arm: dts: imx8mp: Resync imx8mp device tree include Sync imx8mp include with kernel commit: d1689cd3c0f4 ("arm64: dts: imx8mp: Use the correct name for child node "snps, dwc3"") Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam Reviewed-by: Heiko Schocher --- arch/arm/dts/imx8mp.dtsi | 148 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 6 deletions(-) diff --git a/arch/arm/dts/imx8mp.dtsi b/arch/arm/dts/imx8mp.dtsi index ecccfbb4f5..c2d51a46cb 100644 --- a/arch/arm/dts/imx8mp.dtsi +++ b/arch/arm/dts/imx8mp.dtsi @@ -18,6 +18,7 @@ aliases { ethernet0 = &fec; + ethernet1 = &eqos; gpio0 = &gpio1; gpio1 = &gpio2; gpio2 = &gpio3; @@ -218,10 +219,12 @@ }; soc@0 { - compatible = "simple-bus"; + compatible = "fsl,imx8mp-soc", "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x0 0x3e000000>; + nvmem-cells = <&imx8mp_uid>; + nvmem-cell-names = "soc_unique_id"; aips1: bus@30000000 { compatible = "fsl,aips-bus", "simple-bus"; @@ -266,7 +269,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; - gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 0 144 4>; + gpio-ranges = <&iomuxc 0 56 26>, <&iomuxc 26 144 4>; }; gpio4: gpio@30230000 { @@ -310,6 +313,22 @@ status = "disabled"; }; + wdog2: watchdog@30290000 { + compatible = "fsl,imx8mp-wdt", "fsl,imx21-wdt"; + reg = <0x30290000 0x10000>; + interrupts = ; + clocks = <&clk IMX8MP_CLK_WDOG2_ROOT>; + status = "disabled"; + }; + + wdog3: watchdog@302a0000 { + compatible = "fsl,imx8mp-wdt", "fsl,imx21-wdt"; + reg = <0x302a0000 0x10000>; + interrupts = ; + clocks = <&clk IMX8MP_CLK_WDOG3_ROOT>; + status = "disabled"; + }; + iomuxc: pinctrl@30330000 { compatible = "fsl,imx8mp-iomuxc"; reg = <0x30330000 0x10000>; @@ -328,9 +347,17 @@ #address-cells = <1>; #size-cells = <1>; + imx8mp_uid: unique-id@420 { + reg = <0x8 0x8>; + }; + cpu_speed_grade: speed-grade@10 { reg = <0x10 4>; }; + + eth_mac1: mac-address@90 { + reg = <0x90 6>; + }; }; anatop: anatop@30360000 { @@ -762,13 +789,40 @@ assigned-clocks = <&clk IMX8MP_CLK_ENET_AXI>, <&clk IMX8MP_CLK_ENET_TIMER>, <&clk IMX8MP_CLK_ENET_REF>, - <&clk IMX8MP_CLK_ENET_TIMER>; + <&clk IMX8MP_CLK_ENET_PHY_REF>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>, + <&clk IMX8MP_SYS_PLL2_100M>, + <&clk IMX8MP_SYS_PLL2_125M>, + <&clk IMX8MP_SYS_PLL2_50M>; + assigned-clock-rates = <0>, <100000000>, <125000000>, <0>; + fsl,num-tx-queues = <3>; + fsl,num-rx-queues = <3>; + nvmem-cells = <ð_mac1>; + nvmem-cell-names = "mac-address"; + fsl,stop-mode = <&gpr 0x10 3>; + nvmem_macaddr_swap; + status = "disabled"; + }; + + eqos: ethernet@30bf0000 { + compatible = "nxp,imx8mp-dwmac-eqos", "snps,dwmac-5.10a"; + reg = <0x30bf0000 0x10000>; + interrupts = , + ; + interrupt-names = "eth_wake_irq", "macirq"; + clocks = <&clk IMX8MP_CLK_ENET_QOS_ROOT>, + <&clk IMX8MP_CLK_QOS_ENET_ROOT>, + <&clk IMX8MP_CLK_ENET_QOS_TIMER>, + <&clk IMX8MP_CLK_ENET_QOS>; + clock-names = "stmmaceth", "pclk", "ptp_ref", "tx"; + assigned-clocks = <&clk IMX8MP_CLK_ENET_AXI>, + <&clk IMX8MP_CLK_ENET_QOS_TIMER>, + <&clk IMX8MP_CLK_ENET_QOS>; assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>, <&clk IMX8MP_SYS_PLL2_100M>, <&clk IMX8MP_SYS_PLL2_125M>; - assigned-clock-rates = <0>, <0>, <125000000>, <100000000>; - fsl,num-tx-queues = <3>; - fsl,num-rx-queues = <3>; + assigned-clock-rates = <0>, <100000000>, <125000000>; + intf_mode = <&gpr 0x4>; status = "disabled"; }; }; @@ -788,5 +842,87 @@ reg = <0x3d800000 0x400000>; interrupts = ; }; + + usb3_phy0: usb-phy@381f0040 { + compatible = "fsl,imx8mp-usb-phy"; + reg = <0x381f0040 0x40>; + clocks = <&clk IMX8MP_CLK_USB_PHY_ROOT>; + clock-names = "phy"; + assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>; + assigned-clock-parents = <&clk IMX8MP_CLK_24M>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb3_0: usb@32f10100 { + compatible = "fsl,imx8mp-dwc3"; + reg = <0x32f10100 0x8>; + clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, + <&clk IMX8MP_CLK_USB_ROOT>; + clock-names = "hsio", "suspend"; + interrupts = ; + #address-cells = <1>; + #size-cells = <1>; + dma-ranges = <0x40000000 0x40000000 0xc0000000>; + ranges; + status = "disabled"; + + usb_dwc3_0: usb@38100000 { + compatible = "snps,dwc3"; + reg = <0x38100000 0x10000>; + clocks = <&clk IMX8MP_CLK_HSIO_AXI>, + <&clk IMX8MP_CLK_USB_CORE_REF>, + <&clk IMX8MP_CLK_USB_ROOT>; + clock-names = "bus_early", "ref", "suspend"; + assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>; + assigned-clock-rates = <500000000>; + interrupts = ; + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + snps,dis-u2-freeclk-exists-quirk; + }; + + }; + + usb3_phy1: usb-phy@382f0040 { + compatible = "fsl,imx8mp-usb-phy"; + reg = <0x382f0040 0x40>; + clocks = <&clk IMX8MP_CLK_USB_PHY_ROOT>; + clock-names = "phy"; + assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>; + assigned-clock-parents = <&clk IMX8MP_CLK_24M>; + #phy-cells = <0>; + }; + + usb3_1: usb@32f10108 { + compatible = "fsl,imx8mp-dwc3"; + reg = <0x32f10108 0x8>; + clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, + <&clk IMX8MP_CLK_USB_ROOT>; + clock-names = "hsio", "suspend"; + interrupts = ; + #address-cells = <1>; + #size-cells = <1>; + dma-ranges = <0x40000000 0x40000000 0xc0000000>; + ranges; + status = "disabled"; + + usb_dwc3_1: usb@38200000 { + compatible = "snps,dwc3"; + reg = <0x38200000 0x10000>; + clocks = <&clk IMX8MP_CLK_HSIO_AXI>, + <&clk IMX8MP_CLK_USB_CORE_REF>, + <&clk IMX8MP_CLK_USB_ROOT>; + clock-names = "bus_early", "ref", "suspend"; + assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>; + assigned-clock-rates = <500000000>; + interrupts = ; + phys = <&usb3_phy1>, <&usb3_phy1>; + phy-names = "usb2-phy", "usb3-phy"; + snps,dis-u2-freeclk-exists-quirk; + }; + }; }; }; From dafb164f61e642f429e37b5af42b7e59bbe47982 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:57:57 +0000 Subject: [PATCH 20/53] arm: dts: imx8mp: Add common u-boot dtsi Factor out the common node settings for dm-spl and dm-pre-reloc and move them to imx8mp-u-boot.dtsi Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam Reviewed-by: Heiko Schocher --- arch/arm/dts/imx8mp-evk-u-boot.dtsi | 143 +---------------- .../imx8mp-phyboard-pollux-rdk-u-boot.dtsi | 39 +---- arch/arm/dts/imx8mp-u-boot.dtsi | 149 ++++++++++++++++++ 3 files changed, 153 insertions(+), 178 deletions(-) create mode 100644 arch/arm/dts/imx8mp-u-boot.dtsi diff --git a/arch/arm/dts/imx8mp-evk-u-boot.dtsi b/arch/arm/dts/imx8mp-evk-u-boot.dtsi index 4162f41cff..2abcf1f03d 100644 --- a/arch/arm/dts/imx8mp-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-evk-u-boot.dtsi @@ -3,11 +3,9 @@ * Copyright 2019 NXP */ -/ { - binman: binman { - multiple-images; - }; +#include "imx8mp-u-boot.dtsi" +/ { wdt-reboot { compatible = "wdt-reboot"; wdt = <&wdog1>; @@ -21,43 +19,6 @@ }; }; -&{/soc@0} { - u-boot,dm-pre-reloc; - u-boot,dm-spl; -}; - -&clk { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&osc_32k { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&osc_24m { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&aips1 { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&aips2 { - u-boot,dm-spl; -}; - -&aips3 { - u-boot,dm-spl; -}; - -&iomuxc { - u-boot,dm-spl; -}; - ®_usdhc2_vmmc { u-boot,off-on-delay-us = <20000>; }; @@ -156,104 +117,4 @@ phy-reset-post-delay = <100>; }; -&binman { - u-boot-spl-ddr { - filename = "u-boot-spl-ddr.bin"; - pad-byte = <0xff>; - align-size = <4>; - align = <4>; - u-boot-spl { - align-end = <4>; - }; - - blob_1: blob-ext@1 { - filename = "lpddr4_pmu_train_1d_imem_202006.bin"; - size = <0x8000>; - }; - - blob_2: blob-ext@2 { - filename = "lpddr4_pmu_train_1d_dmem_202006.bin"; - size = <0x4000>; - }; - - blob_3: blob-ext@3 { - filename = "lpddr4_pmu_train_2d_imem_202006.bin"; - size = <0x8000>; - }; - - blob_4: blob-ext@4 { - filename = "lpddr4_pmu_train_2d_dmem_202006.bin"; - size = <0x4000>; - }; - }; - - - flash { - mkimage { - args = "-n spl/u-boot-spl.cfgout -T imx8mimage -e 0x920000"; - - blob { - filename = "u-boot-spl-ddr.bin"; - }; - }; - }; - - itb { - filename = "u-boot.itb"; - - fit { - description = "Configuration to load ATF before U-Boot"; - #address-cells = <1>; - fit,external-offset = ; - - images { - uboot { - description = "U-Boot (64-bit)"; - type = "standalone"; - arch = "arm64"; - compression = "none"; - load = ; - - uboot_blob: blob-ext { - filename = "u-boot-nodtb.bin"; - }; - }; - - atf { - description = "ARM Trusted Firmware"; - type = "firmware"; - arch = "arm64"; - compression = "none"; - load = <0x970000>; - entry = <0x970000>; - - atf_blob: blob-ext { - filename = "bl31.bin"; - }; - }; - - fdt { - description = "NAME"; - type = "flat_dt"; - compression = "none"; - - uboot_fdt_blob: blob-ext { - filename = "u-boot.dtb"; - }; - }; - }; - - configurations { - default = "conf"; - - conf { - description = "NAME"; - firmware = "uboot"; - loadables = "atf"; - fdt = "fdt"; - }; - }; - }; - }; -}; diff --git a/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi b/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi index 20e7f63ff9..6c1528934a 100644 --- a/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi @@ -4,6 +4,8 @@ * Author: Teresa Remmet */ +#include "imx8mp-u-boot.dtsi" + / { wdt-reboot { compatible = "wdt-reboot"; @@ -12,43 +14,6 @@ }; }; -&{/soc@0} { - u-boot,dm-pre-reloc; - u-boot,dm-spl; -}; - -&clk { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&osc_32k { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&osc_24m { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&aips1 { - u-boot,dm-spl; - u-boot,dm-pre-reloc; -}; - -&aips2 { - u-boot,dm-spl; -}; - -&aips3 { - u-boot,dm-spl; -}; - -&iomuxc { - u-boot,dm-spl; -}; - ®_usdhc2_vmmc { u-boot,dm-spl; }; diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi new file mode 100644 index 0000000000..d61346da30 --- /dev/null +++ b/arch/arm/dts/imx8mp-u-boot.dtsi @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 PHYTEC Messtechnik GmbH + * Author: Teresa Remmet + */ + +/ { + binman: binman { + multiple-images; + }; +}; + +&{/soc@0} { + u-boot,dm-pre-reloc; + u-boot,dm-spl; +}; + +&clk { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&osc_32k { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&osc_24m { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&aips1 { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&aips2 { + u-boot,dm-spl; +}; + +&aips3 { + u-boot,dm-spl; +}; + +&iomuxc { + u-boot,dm-spl; +}; + +&binman { + u-boot-spl-ddr { + filename = "u-boot-spl-ddr.bin"; + pad-byte = <0xff>; + align-size = <4>; + align = <4>; + + u-boot-spl { + align-end = <4>; + }; + + blob_1: blob-ext@1 { + filename = "lpddr4_pmu_train_1d_imem_202006.bin"; + size = <0x8000>; + }; + + blob_2: blob-ext@2 { + filename = "lpddr4_pmu_train_1d_dmem_202006.bin"; + size = <0x4000>; + }; + + blob_3: blob-ext@3 { + filename = "lpddr4_pmu_train_2d_imem_202006.bin"; + size = <0x8000>; + }; + + blob_4: blob-ext@4 { + filename = "lpddr4_pmu_train_2d_dmem_202006.bin"; + size = <0x4000>; + }; + }; + + flash { + mkimage { + args = "-n spl/u-boot-spl.cfgout -T imx8mimage -e 0x920000"; + + blob { + filename = "u-boot-spl-ddr.bin"; + }; + }; + }; + + itb { + filename = "u-boot.itb"; + + fit { + description = "Configuration to load ATF before U-Boot"; + #address-cells = <1>; + fit,external-offset = ; + + images { + uboot { + description = "U-Boot (64-bit)"; + type = "standalone"; + arch = "arm64"; + compression = "none"; + load = ; + + uboot_blob: blob-ext { + filename = "u-boot-nodtb.bin"; + }; + }; + + atf { + description = "ARM Trusted Firmware"; + type = "firmware"; + arch = "arm64"; + compression = "none"; + load = <0x970000>; + entry = <0x970000>; + + atf_blob: blob-ext { + filename = "bl31.bin"; + }; + }; + + fdt { + description = "NAME"; + type = "flat_dt"; + compression = "none"; + + uboot_fdt_blob: blob-ext { + filename = "u-boot.dtb"; + }; + }; + }; + + configurations { + default = "conf"; + + conf { + description = "NAME"; + firmware = "uboot"; + loadables = "atf"; + fdt = "fdt"; + }; + }; + }; + }; +}; From 3240d9c63a67880e55e33268d0796f71f65a1acd Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:57:58 +0000 Subject: [PATCH 21/53] arm: dts: imx8mp-phyboard-pollux: Sync dts files with kernel This update includes eqos support and some minor changes. Synced with kernel commit 412627f6ffe3 ("arm64: dts: imx8mp-phyboard-pollux-rdk: Add missing pinctrl entry") Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam Reviewed-by: Heiko Schocher --- arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts | 46 ++++++++++++++++++++- arch/arm/dts/imx8mp-phycore-som.dtsi | 2 +- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts b/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts index 0e1a6d9533..2031a9d40b 100644 --- a/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts +++ b/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts @@ -33,9 +33,33 @@ }; }; +&eqos { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eqos>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,clk-output-sel = ; + enet-phy-lane-no-swap; + }; + }; +}; + &i2c2 { clock-frequency = <400000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; pinctrl-1 = <&pinctrl_i2c2_gpio>; sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; @@ -90,6 +114,26 @@ }; &iomuxc { + pinctrl_eqos: eqosgrp { + fsl,pins = < + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 + MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 + MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 + MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f + MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f + MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f + MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x10 + >; + }; + pinctrl_i2c2: i2c2grp { fsl,pins = < MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3 diff --git a/arch/arm/dts/imx8mp-phycore-som.dtsi b/arch/arm/dts/imx8mp-phycore-som.dtsi index 44a8c2337c..f3965ec5b3 100644 --- a/arch/arm/dts/imx8mp-phycore-som.dtsi +++ b/arch/arm/dts/imx8mp-phycore-som.dtsi @@ -67,7 +67,7 @@ &i2c1 { clock-frequency = <400000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; pinctrl-1 = <&pinctrl_i2c1_gpio>; sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; From 1feac813fe54ff6466ea2d575960bc1de45b0e5c Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:57:59 +0000 Subject: [PATCH 22/53] board: phytec: phycore_imx8mp: Change debug UART With the first redesign the debug UART had changed from UART2 to UART1. As the first hardware revision is considered as alpha and will not be supported in future. The old setup will not be preserved. Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam Reviewed-by: Heiko Schocher --- arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi | 4 ++-- arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts | 12 ++++++------ board/phytec/phycore_imx8mp/spl.c | 6 +++--- include/configs/phycore_imx8mp.h | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi b/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi index 6c1528934a..32ed037e37 100644 --- a/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi @@ -18,7 +18,7 @@ u-boot,dm-spl; }; -&pinctrl_uart2 { +&pinctrl_uart1 { u-boot,dm-spl; }; @@ -54,7 +54,7 @@ u-boot,dm-spl; }; -&uart2 { +&uart1 { u-boot,dm-spl; }; diff --git a/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts b/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts index 2031a9d40b..984a6b9ded 100644 --- a/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts +++ b/arch/arm/dts/imx8mp-phyboard-pollux-rdk.dts @@ -16,7 +16,7 @@ "phytec,imx8mp-phycore-som", "fsl,imx8mp"; chosen { - stdout-path = &uart2; + stdout-path = &uart1; }; reg_usdhc2_vmmc: regulator-usdhc2 { @@ -95,9 +95,9 @@ }; /* debug console */ -&uart2 { +&uart1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; + pinctrl-0 = <&pinctrl_uart1>; status = "okay"; }; @@ -154,10 +154,10 @@ >; }; - pinctrl_uart2: uart2grp { + pinctrl_uart1: uart1grp { fsl,pins = < - MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x49 - MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x49 + MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x49 + MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x49 >; }; diff --git a/board/phytec/phycore_imx8mp/spl.c b/board/phytec/phycore_imx8mp/spl.c index f9fa8d1e12..0bc4c7693b 100644 --- a/board/phytec/phycore_imx8mp/spl.c +++ b/board/phytec/phycore_imx8mp/spl.c @@ -80,8 +80,8 @@ int board_fit_config_name_match(const char *name) #define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) static iomux_v3_cfg_t const uart_pads[] = { - MX8MP_PAD_UART2_RXD__UART2_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), - MX8MP_PAD_UART2_TXD__UART2_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX8MP_PAD_UART1_RXD__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX8MP_PAD_UART1_TXD__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; static iomux_v3_cfg_t const wdog_pads[] = { @@ -107,7 +107,7 @@ void board_init_f(ulong dummy) arch_cpu_init(); - init_uart_clk(1); + init_uart_clk(0); board_early_init_f(); diff --git a/include/configs/phycore_imx8mp.h b/include/configs/phycore_imx8mp.h index 0490049850..e24f223c21 100644 --- a/include/configs/phycore_imx8mp.h +++ b/include/configs/phycore_imx8mp.h @@ -39,7 +39,7 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "image=Image\0" \ - "console=ttymxc1,115200\0" \ + "console=ttymxc0,115200\0" \ "fdt_addr=0x48000000\0" \ "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ @@ -87,7 +87,7 @@ #define PHYS_SDRAM_SIZE 0x80000000 /* UART */ -#define CONFIG_MXC_UART_BASE UART2_BASE_ADDR +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR /* Monitor Command Prompt */ #define CONFIG_SYS_CBSIZE SZ_2K From 60f64bec414e139baa8764b56071eb22a1460c36 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:58:00 +0000 Subject: [PATCH 23/53] board: phytec: phycore_imx8mp: Add fec support Enable support for the fec ethernet on phyCORE-i.MX8MP. Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam Reviewed-by: Heiko Schocher --- board/phytec/phycore_imx8mp/phycore-imx8mp.c | 14 ++++++++++++++ configs/phycore-imx8mp_defconfig | 7 +++++++ include/configs/phycore_imx8mp.h | 17 +++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/board/phytec/phycore_imx8mp/phycore-imx8mp.c b/board/phytec/phycore_imx8mp/phycore-imx8mp.c index 67649078c2..a8f0821437 100644 --- a/board/phytec/phycore_imx8mp/phycore-imx8mp.c +++ b/board/phytec/phycore_imx8mp/phycore-imx8mp.c @@ -10,11 +10,25 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(&gpr->gpr[1], 0x2000, 0); + + return 0; +} + int board_init(void) { + setup_fec(); + return 0; } diff --git a/configs/phycore-imx8mp_defconfig b/configs/phycore-imx8mp_defconfig index 7f21e8888e..a22f5e089d 100644 --- a/configs/phycore-imx8mp_defconfig +++ b/configs/phycore-imx8mp_defconfig @@ -58,6 +58,7 @@ CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SYS_MMC_ENV_DEV=2 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_CLK_IMX8MP=y @@ -79,7 +80,13 @@ CONFIG_MMC_UHS_SUPPORT=y CONFIG_MMC_HS400_ES_SUPPORT=y CONFIG_MMC_HS400_SUPPORT=y CONFIG_FSL_ESDHC_IMX=y +CONFIG_PHYLIB=y +CONFIG_PHY_TI_DP83867=y CONFIG_DM_ETH=y +CONFIG_DM_ETH_PHY=y +CONFIG_FEC_MXC=y +CONFIG_RGMII=y +CONFIG_MII=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y diff --git a/include/configs/phycore_imx8mp.h b/include/configs/phycore_imx8mp.h index e24f223c21..75f84e60f5 100644 --- a/include/configs/phycore_imx8mp.h +++ b/include/configs/phycore_imx8mp.h @@ -42,6 +42,7 @@ "console=ttymxc0,115200\0" \ "fdt_addr=0x48000000\0" \ "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ + "ip_dyn=yes\0" \ "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \ "mmcroot=2\0" \ @@ -57,6 +58,22 @@ "else " \ "echo WARN: Cannot load the DT; " \ "fi;\0 " \ + "nfsroot=/nfs\0" \ + "netargs=setenv bootargs console=${console} root=/dev/nfs ip=dhcp " \ + "nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ + "netboot=echo Booting from net ...; " \ + "run netargs; " \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "${get_cmd} ${loadaddr} ${image}; " \ + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ + "booti ${loadaddr} - ${fdt_addr}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi;\0" \ #define CONFIG_BOOTCOMMAND \ "mmc dev ${mmcdev}; if mmc rescan; then " \ From 0f166b85ac473f72aaff6489f880d26cc41a1148 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:58:01 +0000 Subject: [PATCH 24/53] board: phytec: phycore_imx8mp: Set VDD_ARM to 0,95V Increase VDD_ARM to prevent timing issues as VDD_SOC is used in OD mode. Also increase GIC clock. Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam --- board/phytec/phycore_imx8mp/spl.c | 11 ++++++++++- configs/phycore-imx8mp_defconfig | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/board/phytec/phycore_imx8mp/spl.c b/board/phytec/phycore_imx8mp/spl.c index 0bc4c7693b..815ca9badc 100644 --- a/board/phytec/phycore_imx8mp/spl.c +++ b/board/phytec/phycore_imx8mp/spl.c @@ -62,7 +62,8 @@ int power_init_board(void) /* BUCKxOUT_DVS0/1 control BUCK123 output */ pmic_reg_write(p, PCA9450_BUCK123_DVS, 0x29); - /* increase VDD_SOC to typical value 0.95V */ + /* Increase VDD_SOC and VDD_ARM to OD voltage 0.95V */ + pmic_reg_write(p, PCA9450_BUCK1OUT_DVS0, 0x1C); pmic_reg_write(p, PCA9450_BUCK2OUT_DVS0, 0x1C); /* set WDOG_B_CFG to cold reset */ @@ -71,6 +72,14 @@ int power_init_board(void) return 0; } +void spl_board_init(void) +{ + /* Set GIC clock to 500Mhz for OD VDD_SOC. */ + clock_enable(CCGR_GIC, 0); + clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5)); + clock_enable(CCGR_GIC, 1); +} + int board_fit_config_name_match(const char *name) { return 0; diff --git a/configs/phycore-imx8mp_defconfig b/configs/phycore-imx8mp_defconfig index a22f5e089d..89c2ac977f 100644 --- a/configs/phycore-imx8mp_defconfig +++ b/configs/phycore-imx8mp_defconfig @@ -25,6 +25,7 @@ CONFIG_OF_SYSTEM_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mp-lpddr4.cfg" CONFIG_DEFAULT_FDT_FILE="oftree" CONFIG_BOARD_LATE_INIT=y +CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_BOOTROM_SUPPORT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y From fd82763cd256a0470d85a00458735721db719a00 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:58:02 +0000 Subject: [PATCH 25/53] board: phytec: phycore-imx8mp: Enable DVS1 control Enable DVS1 control through PMIC_STBY_REQ. Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam --- board/phytec/phycore_imx8mp/spl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/board/phytec/phycore_imx8mp/spl.c b/board/phytec/phycore_imx8mp/spl.c index 815ca9badc..19c486e551 100644 --- a/board/phytec/phycore_imx8mp/spl.c +++ b/board/phytec/phycore_imx8mp/spl.c @@ -66,7 +66,11 @@ int power_init_board(void) pmic_reg_write(p, PCA9450_BUCK1OUT_DVS0, 0x1C); pmic_reg_write(p, PCA9450_BUCK2OUT_DVS0, 0x1C); - /* set WDOG_B_CFG to cold reset */ + /* Set BUCK1 DVS1 to suspend controlled through PMIC_STBY_REQ */ + pmic_reg_write(p, PCA9450_BUCK1OUT_DVS1, 0x14); + pmic_reg_write(p, PCA9450_BUCK1CTRL, 0x59); + + /* Set WDOG_B_CFG to cold reset */ pmic_reg_write(p, PCA9450_RESET_CTRL, 0xA1); return 0; From f11e3dafb33f95719885f2825d36e4d38e270d62 Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:58:03 +0000 Subject: [PATCH 26/53] arm: dts: imx8mp-phyboard-pollux-rdk-u-boot: Add wdog pinctrl entry Add missing pinctrl entry in spl. Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam --- arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi b/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi index 32ed037e37..dbc48dfb48 100644 --- a/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi +++ b/arch/arm/dts/imx8mp-phyboard-pollux-rdk-u-boot.dtsi @@ -34,6 +34,10 @@ u-boot,dm-spl; }; +&pinctrl_wdog { + u-boot,dm-spl; +}; + &gpio1 { u-boot,dm-spl; }; From bbf04b28d2f45114cceadacb0bc53ab20406683a Mon Sep 17 00:00:00 2001 From: Teresa Remmet Date: Wed, 7 Jul 2021 12:58:04 +0000 Subject: [PATCH 27/53] board: phytec: imx8mp-phycore: Switch to binman Use now binman for image creation. Signed-off-by: Teresa Remmet Reviewed-by: Fabio Estevam Reviewed-by: Heiko Schocher --- arch/arm/mach-imx/imx8m/Kconfig | 1 + board/phytec/phycore_imx8mp/imximage-8mp-sd.cfg | 10 ++++++++++ configs/phycore-imx8mp_defconfig | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 board/phytec/phycore_imx8mp/imximage-8mp-sd.cfg diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 0669363c0f..ccaf106be5 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -127,6 +127,7 @@ config TARGET_PHYCORE_IMX8MM config TARGET_PHYCORE_IMX8MP bool "PHYTEC PHYCORE i.MX8MP" + select BINMAN select IMX8MP select SUPPORT_SPL select IMX8M_LPDDR4 diff --git a/board/phytec/phycore_imx8mp/imximage-8mp-sd.cfg b/board/phytec/phycore_imx8mp/imximage-8mp-sd.cfg new file mode 100644 index 0000000000..b2920b4908 --- /dev/null +++ b/board/phytec/phycore_imx8mp/imximage-8mp-sd.cfg @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 NXP + */ + +#define __ASSEMBLY__ + +ROM_VERSION v2 +BOOT_FROM sd +LOADER mkimage.flash.mkimage 0x920000 diff --git a/configs/phycore-imx8mp_defconfig b/configs/phycore-imx8mp_defconfig index 89c2ac977f..32d538c8bb 100644 --- a/configs/phycore-imx8mp_defconfig +++ b/configs/phycore-imx8mp_defconfig @@ -20,9 +20,9 @@ CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 CONFIG_FIT=y CONFIG_FIT_EXTERNAL_OFFSET=0x3000 CONFIG_SPL_LOAD_FIT=y -CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh" +# CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_OF_SYSTEM_SETUP=y -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mp-lpddr4.cfg" +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/phytec/phycore_imx8mp/imximage-8mp-sd.cfg" CONFIG_DEFAULT_FDT_FILE="oftree" CONFIG_BOARD_LATE_INIT=y CONFIG_SPL_BOARD_INIT=y From a5dc91febd9d471f1bfe2716500e844151561f07 Mon Sep 17 00:00:00 2001 From: Kacper Kubkowski Date: Wed, 12 May 2021 15:25:48 +0200 Subject: [PATCH 28/53] arm/mach-imx: Fix macros in mmdc_size.c Make macros actually use passed parameter instead of local variables that happen to be named the same as symbols in macro expansion. Signed-off-by: Kacper Kubkowski --- arch/arm/mach-imx/mmdc_size.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/mmdc_size.c b/arch/arm/mach-imx/mmdc_size.c index 1a094726aa..41a5af6bd3 100644 --- a/arch/arm/mach-imx/mmdc_size.c +++ b/arch/arm/mach-imx/mmdc_size.c @@ -24,11 +24,11 @@ struct esd_mmdc_regs { u32 misc; }; -#define ESD_MMDC_CTL_GET_ROW(mdctl) ((ctl >> 24) & 7) -#define ESD_MMDC_CTL_GET_COLUMN(mdctl) ((ctl >> 20) & 7) -#define ESD_MMDC_CTL_GET_WIDTH(mdctl) ((ctl >> 16) & 3) -#define ESD_MMDC_CTL_GET_CS1(mdctl) ((ctl >> 30) & 1) -#define ESD_MMDC_MISC_GET_BANK(mdmisc) ((misc >> 5) & 1) +#define ESD_MMDC_CTL_GET_ROW(mdctl) ((mdctl >> 24) & 7) +#define ESD_MMDC_CTL_GET_COLUMN(mdctl) ((mdctl >> 20) & 7) +#define ESD_MMDC_CTL_GET_WIDTH(mdctl) ((mdctl >> 16) & 3) +#define ESD_MMDC_CTL_GET_CS1(mdctl) ((mdctl >> 30) & 1) +#define ESD_MMDC_MISC_GET_BANK(mdmisc) ((mdmisc >> 5) & 1) /* * imx_ddr_size - return size in bytes of DRAM according MMDC config From 6b86554865ad271a71e93c125594335721b615c9 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Mon, 7 Jun 2021 14:36:42 +0200 Subject: [PATCH 29/53] spi: fsl_qspi: Build driver only if DM_SPI is available The driver depends on DM_SPI and if it's not available (e. g. in SPL), then we should not try to build it as this will fail. Signed-off-by: Frieder Schrempf --- drivers/spi/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index f70851e4bc..216e72c60f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o obj-$(CONFIG_SPI_MEM) += spi-mem.o obj-$(CONFIG_TI_QSPI) += ti_qspi.o +obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o else obj-y += spi.o obj-$(CONFIG_SPI_MEM) += spi-mem-nodm.o @@ -30,7 +31,6 @@ obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o obj-$(CONFIG_FSL_ESPI) += fsl_espi.o -obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o obj-$(CONFIG_SYNQUACER_SPI) += spi-synquacer.o obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o From c9f7ef37f97a38494ac757dc735b42ab00aba0c0 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:02 -0700 Subject: [PATCH 30/53] board: gateworks: venice: add imx8mm-gw7901 support The Gateworks GW7901 is an ARM based single board computer (SBC) featuring: - i.MX8M Mini SoC - LPDDR4 DRAM - eMMC FLASH - SPI FRAM - Gateworks System Controller (GSC) - Atmel ATECC Crypto Authentication - USB 2.0 - Microchip GbE Switch - Multiple multi-protocol RS232/RS485/RS422 Serial ports - onboard 802.11ac WiFi / BT - microSD socket - miniPCIe socket with PCIe, USB 2.0 and dual SIM sockets - Wide range DC power input - 802.3at PoE To add support for this board: - add dts from Linux (accepted for v5.14) - add SPL PMIC config Signed-off-by: Tim Harvey --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi | 117 ++ arch/arm/dts/imx8mm-venice-gw7901.dts | 1020 +++++++++++++++++ board/gateworks/venice/spl.c | 55 +- configs/imx8mm_venice_defconfig | 2 +- 5 files changed, 1193 insertions(+), 2 deletions(-) create mode 100644 arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mm-venice-gw7901.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 59d8078558..db3891e334 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -865,6 +865,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mm-venice-gw71xx-0x.dtb \ imx8mm-venice-gw72xx-0x.dtb \ imx8mm-venice-gw73xx-0x.dtb \ + imx8mm-venice-gw7901.dtb \ imx8mm-verdin.dtb \ phycore-imx8mm.dtb \ imx8mn-ddr4-evk.dtb \ diff --git a/arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi b/arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi new file mode 100644 index 0000000000..6992d91798 --- /dev/null +++ b/arch/arm/dts/imx8mm-venice-gw7901-u-boot.dtsi @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Gateworks Corporation + */ + +&{/soc@0} { + u-boot,dm-pre-reloc; + u-boot,dm-spl; +}; + +&clk { + u-boot,dm-spl; + u-boot,dm-pre-reloc; + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + /delete-property/ assigned-clock-rates; +}; + +&osc_24m { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&aips1 { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&aips2 { + u-boot,dm-spl; +}; + +&aips3 { + u-boot,dm-spl; +}; + +&iomuxc { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&pinctrl_uart2 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc2 { + u-boot,dm-spl; +}; + +&usdhc3 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc3 { + u-boot,dm-spl; +}; + +&i2c1 { + u-boot,dm-spl; +}; + +&pinctrl_i2c1 { + u-boot,dm-spl; +}; + +&i2c2 { + u-boot,dm-spl; +}; + +&pinctrl_i2c2 { + u-boot,dm-spl; +}; + +&fec1 { + phy-reset-gpios = <&gpio4 19 GPIO_ACTIVE_LOW>; + phy-reset-duration = <1>; + phy-reset-post-delay = <1>; +}; + +&{/soc@0/bus@30800000/i2c@30a30000/pmic@4b} { + u-boot,dm-spl; +}; + +&{/soc@0/bus@30800000/i2c@30a30000/pmic@4b/regulators} { + u-boot,dm-spl; +}; + +&pinctrl_pmic { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx8mm-venice-gw7901.dts b/arch/arm/dts/imx8mm-venice-gw7901.dts new file mode 100644 index 0000000000..0216facb2a --- /dev/null +++ b/arch/arm/dts/imx8mm-venice-gw7901.dts @@ -0,0 +1,1020 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2020 Gateworks Corporation + */ + +/dts-v1/; + +#include +#include +#include + +#include "imx8mm.dtsi" + +/ { + model = "Gateworks Venice GW7901 i.MX8MM board"; + compatible = "gw,imx8mm-gw7901", "fsl,imx8mm"; + + aliases { + ethernet0 = &fec1; + ethernet1 = &lan1; + ethernet2 = &lan2; + ethernet3 = &lan3; + ethernet4 = &lan4; + usb0 = &usbotg1; + usb1 = &usbotg2; + }; + + chosen { + stdout-path = &uart2; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0 0x80000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + user-pb { + label = "user_pb"; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + user-pb1x { + label = "user_pb1x"; + linux,code = ; + interrupt-parent = <&gsc>; + interrupts = <0>; + }; + + key-erased { + label = "key_erased"; + linux,code = ; + interrupt-parent = <&gsc>; + interrupts = <1>; + }; + + eeprom-wp { + label = "eeprom_wp"; + linux,code = ; + interrupt-parent = <&gsc>; + interrupts = <2>; + }; + + tamper { + label = "tamper"; + linux,code = ; + interrupt-parent = <&gsc>; + interrupts = <5>; + }; + + switch-hold { + label = "switch_hold"; + linux,code = ; + interrupt-parent = <&gsc>; + interrupts = <7>; + }; + }; + + led-controller { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led01_red"; + gpios = <&leds_gpio 0 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-1 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led01_grn"; + gpios = <&leds_gpio 1 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-2 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led02_red"; + gpios = <&leds_gpio 2 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-3 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led02_grn"; + gpios = <&leds_gpio 3 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-4 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led03_red"; + gpios = <&leds_gpio 4 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-5 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led03_grn"; + gpios = <&leds_gpio 5 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-6 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led04_red"; + gpios = <&leds_gpio 8 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-7 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led04_grn"; + gpios = <&leds_gpio 9 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-8 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led05_red"; + gpios = <&leds_gpio 10 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-9 { + function = LED_FUNCTION_STATUS; + color = ; + label = "led05_grn"; + gpios = <&leds_gpio 11 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-a { + function = LED_FUNCTION_STATUS; + color = ; + label = "led06_red"; + gpios = <&leds_gpio 12 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + led-b { + function = LED_FUNCTION_STATUS; + color = ; + label = "led06_grn"; + gpios = <&leds_gpio 13 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + regulator-ioexp { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_ioexp>; + compatible = "regulator-fixed"; + regulator-name = "ioexp"; + gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; + enable-active-high; + startup-delay-us = <100>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + regulator-isouart { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_isouart>; + compatible = "regulator-fixed"; + regulator-name = "iso_uart"; + gpio = <&gpio1 13 GPIO_ACTIVE_LOW>; + startup-delay-us = <100>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_usb2_vbus: regulator-usb2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usb2>; + compatible = "regulator-fixed"; + regulator-name = "usb_usb2_vbus"; + gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_wifi: regulator-wifi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_wl>; + compatible = "regulator-fixed"; + regulator-name = "wifi"; + gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>; + enable-active-high; + startup-delay-us = <100>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&ddrc { + operating-points-v2 = <&ddrc_opp_table>; + + ddrc_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-25M { + opp-hz = /bits/ 64 <25000000>; + }; + + opp-100M { + opp-hz = /bits/ 64 <100000000>; + }; + + opp-750M { + opp-hz = /bits/ 64 <750000000>; + }; + }; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + status = "okay"; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii-id"; + local-mac-address = [00 00 00 00 00 00]; + status = "okay"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + gsc: gsc@20 { + compatible = "gw,gsc"; + reg = <0x20>; + pinctrl-0 = <&pinctrl_gsc>; + interrupt-parent = <&gpio4>; + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + adc { + compatible = "gw,gsc-adc"; + #address-cells = <1>; + #size-cells = <0>; + + channel@6 { + gw,mode = <0>; + reg = <0x06>; + label = "temp"; + }; + + channel@8 { + gw,mode = <1>; + reg = <0x08>; + label = "vdd_bat"; + }; + + channel@82 { + gw,mode = <2>; + reg = <0x82>; + label = "vin_aux1"; + gw,voltage-divider-ohms = <22100 1000>; + }; + + channel@84 { + gw,mode = <2>; + reg = <0x84>; + label = "vin_aux2"; + gw,voltage-divider-ohms = <22100 1000>; + }; + + channel@86 { + gw,mode = <2>; + reg = <0x86>; + label = "vdd_vin"; + gw,voltage-divider-ohms = <22100 1000>; + }; + + channel@88 { + gw,mode = <2>; + reg = <0x88>; + label = "vdd_3p3"; + gw,voltage-divider-ohms = <10000 10000>; + }; + + channel@8c { + gw,mode = <2>; + reg = <0x8c>; + label = "vdd_2p5"; + gw,voltage-divider-ohms = <10000 10000>; + }; + + channel@8e { + gw,mode = <2>; + reg = <0x8e>; + label = "vdd_0p95"; + }; + + channel@90 { + gw,mode = <2>; + reg = <0x90>; + label = "vdd_soc"; + }; + + channel@92 { + gw,mode = <2>; + reg = <0x92>; + label = "vdd_arm"; + }; + + channel@98 { + gw,mode = <2>; + reg = <0x98>; + label = "vdd_1p8"; + }; + + channel@9a { + gw,mode = <2>; + reg = <0x9a>; + label = "vdd_1p2"; + }; + + channel@9c { + gw,mode = <2>; + reg = <0x9c>; + label = "vdd_dram"; + }; + + channel@a2 { + gw,mode = <2>; + reg = <0xa2>; + label = "vdd_gsc"; + gw,voltage-divider-ohms = <10000 10000>; + }; + }; + }; + + gpio: gpio@23 { + compatible = "nxp,pca9555"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gsc>; + interrupts = <4>; + }; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + + eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + }; + + eeprom@52 { + compatible = "atmel,24c02"; + reg = <0x52>; + pagesize = <16>; + }; + + eeprom@53 { + compatible = "atmel,24c02"; + reg = <0x53>; + pagesize = <16>; + }; + + rtc@68 { + compatible = "dallas,ds1672"; + reg = <0x68>; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + pmic@4b { + compatible = "rohm,bd71847"; + reg = <0x4b>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio3>; + interrupts = <20 IRQ_TYPE_LEVEL_LOW>; + rohm,reset-snvs-powered; + #clock-cells = <0>; + clocks = <&osc_32k 0>; + clock-output-names = "clk-32k-out"; + + regulators { + /* vdd_soc: 0.805-0.900V (typ=0.8V) */ + BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + }; + + /* vdd_arm: 0.805-1.0V (typ=0.9V) */ + BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + /* vdd_0p9: 0.805-1.0V (typ=0.9V) */ + BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + /* vdd_3p3 */ + BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + /* vdd_1p8 */ + BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + /* vdd_dram */ + BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + /* nvcc_snvs_1p8 */ + LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <1900000>; + regulator-boot-on; + regulator-always-on; + }; + + /* vdd_snvs_0p8 */ + LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + /* vdda_1p8 */ + LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + leds_gpio: gpio@20 { + compatible = "nxp,pca9555"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; + + switch: switch@5f { + compatible = "microchip,ksz9897"; + reg = <0x5f>; + pinctrl-0 = <&pinctrl_ksz>; + interrupt-parent = <&gpio4>; + interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + phy-mode = "rgmii-id"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + lan1: port@0 { + reg = <0>; + label = "lan1"; + local-mac-address = [00 00 00 00 00 00]; + }; + + lan2: port@1 { + reg = <1>; + label = "lan2"; + local-mac-address = [00 00 00 00 00 00]; + }; + + lan3: port@2 { + reg = <2>; + label = "lan3"; + local-mac-address = [00 00 00 00 00 00]; + }; + + lan4: port@3 { + reg = <3>; + label = "lan4"; + local-mac-address = [00 00 00 00 00 00]; + }; + + port@5 { + reg = <5>; + label = "cpu"; + ethernet = <&fec1>; + phy-mode = "rgmii-id"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + + crypto@60 { + compatible = "atmel,atecc508a"; + reg = <0x60>; + }; +}; + +&i2c4 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>, <&pinctrl_uart1_gpio>; + rts-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + cts-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + dtr-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +/* console */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_uart3_gpio>; + cts-gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; + rts-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>, <&pinctrl_uart4_gpio>; + cts-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; + rts-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "host"; + disable-over-current; + status = "okay"; +}; + +&usbotg2 { + dr_mode = "host"; + vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; + +/* SDIO WiFi */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + bus-width = <4>; + non-removable; + vmmc-supply = <®_wifi>; + status = "okay"; +}; + +/* microSD */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + bus-width = <4>; + vmmc-supply = <®_3p3v>; + status = "okay"; +}; + +/* eMMC */ +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hoggrp { + fsl,pins = < + MX8MM_IOMUXC_SPDIF_TX_GPIO5_IO3 0x40000041 /* DIG2_OUT */ + MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x40000041 /* DIG2_IN */ + MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x40000041 /* DIG1_IN */ + MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x40000041 /* DIG1_OUT */ + MX8MM_IOMUXC_SAI3_RXD_GPIO4_IO30 0x40000041 /* SIM2DET# */ + MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x40000041 /* SIM1DET# */ + MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x40000041 /* SIM2SEL */ + >; + }; + + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 + MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x19 /* IRQ# */ + MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x19 /* RST# */ + >; + }; + + pinctrl_gsc: gscgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x159 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 + MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 + MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 + MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 + >; + }; + + pinctrl_ksz: kszgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x41 + MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x41 /* RST# */ + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x41 + >; + }; + + pinctrl_reg_isouart: regisouartgrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x40000041 + >; + }; + + pinctrl_reg_ioexp: regioexpgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x40000041 + >; + }; + + pinctrl_reg_wl: regwlgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x40000041 + >; + }; + + pinctrl_reg_usb2: regusb1grp { + fsl,pins = < + MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2 0x41 + MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x140 + MX8MM_IOMUXC_GPIO1_IO15_USB2_OTG_OC 0x140 + >; + }; + + pinctrl_spi1: spi1grp { + fsl,pins = < + MX8MM_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK 0x82 + MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82 + MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82 + MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x140 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140 + MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140 + MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x140 + MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x140 + MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x140 + MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x140 + MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x140 + >; + }; + + pinctrl_uart1_gpio: uart1gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x40000041 /* RS422# */ + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x40000041 /* RS485# */ + MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x40000041 /* RS232# */ + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140 + MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140 + MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 + MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x140 + MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10 0x140 + >; + }; + + pinctrl_uart3_gpio: uart3gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x40000110 /* RS232# */ + MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x40000110 /* RS422# */ + MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x40000110 /* RS485# */ + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x140 + MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + MX8MM_IOMUXC_ECSPI2_MOSI_GPIO5_IO11 0x140 + MX8MM_IOMUXC_ECSPI2_MISO_GPIO5_IO12 0x140 + >; + }; + + pinctrl_uart4_gpio: uart4gpiogrp { + fsl,pins = < + + MX8MM_IOMUXC_ECSPI2_SCLK_GPIO5_IO10 0x40000041 /* RS232# */ + MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x40000041 /* RS422# */ + MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x40000041 /* RS485# */ + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2-gpiogrp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; +}; + +&cpu_alert0 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; +}; + +&cpu_crit0 { + temperature = <105000>; + hysteresis = <2000>; + type = "critical"; +}; diff --git a/board/gateworks/venice/spl.c b/board/gateworks/venice/spl.c index ea500d4f81..8c357757c1 100644 --- a/board/gateworks/venice/spl.c +++ b/board/gateworks/venice/spl.c @@ -26,6 +26,7 @@ #include #include +#include #include #include "gsc.h" @@ -88,8 +89,23 @@ int board_early_init_f(void) * Note that we can not use pmic dm drivers here as we have a generic * venice dt that does not have board-specific pmic's defined. * - * Instead we must use dm_i2c. + * Instead we must use dm_i2c so we a helpers to give us + * clrsetbit functions we would otherwise have if we could use PMIC dm + * drivers. */ +static int dm_i2c_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set) +{ + int ret; + u8 val; + + ret = dm_i2c_read(dev, reg, &val, 1); + if (ret) + return ret; + val = (val & ~clr) | set; + + return dm_i2c_write(dev, reg, &val, 1); +} + static int power_init_board(void) { const char *model = gsc_get_model(); @@ -117,6 +133,43 @@ static int power_init_board(void) BIT(7) | MP5416_VSET_SW3_SVAL(920000)); } + else if (!strncmp(model, "GW7901", 6)) { + ret = uclass_get_device_by_name(UCLASS_I2C, "i2c@30a30000", &bus); + if (ret) { + printf("PMIC : failed I2C2 probe: %d\n", ret); + return ret; + } + ret = dm_i2c_probe(bus, 0x4b, 0, &dev); + if (ret) { + printf("PMIC : failed probe: %d\n", ret); + return ret; + } + puts("PMIC : BD71847\n"); + + /* unlock the PMIC regs */ + dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x1); + + /* set switchers to forced PWM mode */ + dm_i2c_clrsetbits(dev, BD718XX_BUCK1_CTRL, 0, 0x8); + dm_i2c_clrsetbits(dev, BD718XX_BUCK2_CTRL, 0, 0x8); + dm_i2c_clrsetbits(dev, BD718XX_1ST_NODVS_BUCK_CTRL, 0, 0x8); + dm_i2c_clrsetbits(dev, BD718XX_2ND_NODVS_BUCK_CTRL, 0, 0x8); + dm_i2c_clrsetbits(dev, BD718XX_3RD_NODVS_BUCK_CTRL, 0, 0x8); + dm_i2c_clrsetbits(dev, BD718XX_4TH_NODVS_BUCK_CTRL, 0, 0x8); + + /* increase VDD_0P95 (VDD_GPU/VPU/DRAM) to 0.975v for 1.5Ghz DDR */ + dm_i2c_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83); + + /* increase VDD_SOC to 0.85v before first DRAM access */ + dm_i2c_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f); + + /* increase VDD_ARM to 0.92v for 800 and 1600Mhz */ + dm_i2c_reg_write(dev, BD718XX_BUCK2_VOLT_RUN, 0x16); + + /* Lock the PMIC regs */ + dm_i2c_reg_write(dev, BD718XX_REGLOCK, 0x11); + } + return 0; } diff --git a/configs/imx8mm_venice_defconfig b/configs/imx8mm_venice_defconfig index daffcc46d5..3961db00cb 100644 --- a/configs/imx8mm_venice_defconfig +++ b/configs/imx8mm_venice_defconfig @@ -58,7 +58,7 @@ CONFIG_CMD_EXT4_WRITE=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y -CONFIG_OF_LIST="imx8mm-venice-gw71xx-0x imx8mm-venice-gw72xx-0x imx8mm-venice-gw73xx-0x" +CONFIG_OF_LIST="imx8mm-venice-gw71xx-0x imx8mm-venice-gw72xx-0x imx8mm-venice-gw73xx-0x imx8mm-venice-gw7901" CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y From b247fa7b178084cb6f71849a5ebbcb5ac107e688 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:03 -0700 Subject: [PATCH 31/53] net: fec: use device sequence vs index when fetching fec When using uclass_get_device* to get the FEC device we need to use device sequence instead of index into UCLASS_ETH. In systems where for example a I2C based DSA switch exists it will probe before the FEC master and its ports will be registered first and have the first indexes yet the FEC's sequence comes from the device-tree alias. Take for example the imx8mm-venice-gw7901 board which has an i2c based DSA switch: u-boot=> net list eth1 : lan1 00:0d:8d:aa:00:2f eth2 : lan2 00:0d:8d:aa:00:30 eth3 : lan3 00:0d:8d:aa:00:31 eth4 : lan4 00:0d:8d:aa:00:32 eth0 : ethernet@30be0000 00:0d:8d:aa:00:2e active Thus in this case uclass_get_device(UCLASS_ETH, 0, &dev) returns lan1 which is wrong but uclass_get_device_seq(UCLASS_ETH, 0, &dev) returns ethernet@30be000 which is correct. Signed-off-by: Tim Harvey Reviewed-by: Ramon Fried --- drivers/net/fec_mxc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 4fd5c01b4a..3abf914833 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -146,7 +146,7 @@ static int fec_get_clk_rate(void *udev, int idx) CONFIG_IS_ENABLED(CLK_CCF)) { dev = udev; if (!dev) { - ret = uclass_get_device(UCLASS_ETH, idx, &dev); + ret = uclass_get_device_by_seq(UCLASS_ETH, idx, &dev); if (ret < 0) { debug("Can't get FEC udev: %d\n", ret); return ret; From 69c81d6546e2fb12acf8ebf0d64790eba193686c Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:04 -0700 Subject: [PATCH 32/53] net: fec: set phy_of_node properly for fixed-link phy If the FEC is connected to a fixed-link (upstream switch port for example) the phy_of_node should be set to the fixed-link node so that speed and other properties can be found properly. In addition fix a typo in the debug string. Signed-off-by: Tim Harvey Reviewed-by: Ramon Fried --- drivers/net/fec_mxc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 3abf914833..77680491d0 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1304,7 +1304,11 @@ static int device_get_phy_addr(struct fec_priv *priv, struct udevice *dev) ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &phandle_args); if (ret) { - debug("Failed to find phy-handle (err = %d\n)", ret); + priv->phy_of_node = ofnode_find_subnode(dev_ofnode(dev), + "fixed-link"); + if (ofnode_valid(priv->phy_of_node)) + return 0; + debug("Failed to find phy-handle (err = %d)\n", ret); return ret; } From 631f3afbef58a95f39bc46a0f37ce4d96d07d834 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:05 -0700 Subject: [PATCH 33/53] net: add set_promisc function to enable/disable Promiscuous mode Enabling promiscuous mode can be useful for DSA switches where each port has its own MAC address. Signed-off-by: Tim Harvey Reviewed-by: Ramon Fried --- include/net.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net.h b/include/net.h index b95d6a6f60..cec8c98618 100644 --- a/include/net.h +++ b/include/net.h @@ -158,6 +158,7 @@ enum eth_recv_flags { * ROM on the board. This is how the driver should expose it * to the network stack. This function should fill in the * eth_pdata::enetaddr field - optional + * set_promisc: Enable or Disable promiscuous mode */ struct eth_ops { int (*start)(struct udevice *dev); @@ -168,6 +169,7 @@ struct eth_ops { int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join); int (*write_hwaddr)(struct udevice *dev); int (*read_rom_hwaddr)(struct udevice *dev); + int (*set_promisc)(struct udevice *dev, bool enable); }; #define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops) From 87550a814e0f136c24c025371d96cf1303185569 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:06 -0700 Subject: [PATCH 34/53] net: fec: add set_promisc function Enabling promiscuous mode is necessary if FEC is the master of a DSA switch driver where each port has their own MAC address. Signed-off-by: Tim Harvey Reviewed-by: Ramon Fried --- drivers/net/fec_mxc.c | 13 +++++++++++++ drivers/net/fec_mxc.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 77680491d0..db2cdaf684 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -458,6 +458,9 @@ static void fec_reg_setup(struct fec_priv *fec) else if (fec->xcv_type == RMII) rcntrl |= FEC_RCNTRL_RMII; + if (fec->promisc) + rcntrl |= 0x8; + writel(rcntrl, &fec->eth->r_cntrl); } @@ -1278,6 +1281,15 @@ static int fecmxc_read_rom_hwaddr(struct udevice *dev) return fec_get_hwaddr(priv->dev_id, pdata->enetaddr); } +static int fecmxc_set_promisc(struct udevice *dev, bool enable) +{ + struct fec_priv *priv = dev_get_priv(dev); + + priv->promisc = enable; + + return 0; +} + static int fecmxc_free_pkt(struct udevice *dev, uchar *packet, int length) { if (packet) @@ -1294,6 +1306,7 @@ static const struct eth_ops fecmxc_ops = { .stop = fecmxc_halt, .write_hwaddr = fecmxc_set_hwaddr, .read_rom_hwaddr = fecmxc_read_rom_hwaddr, + .set_promisc = fecmxc_set_promisc, }; static int device_get_phy_addr(struct fec_priv *priv, struct udevice *dev) diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 5ccde9193b..62b55ef395 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -272,6 +272,7 @@ struct fec_priv { struct clk clk_ref; struct clk clk_ptp; u32 clk_rate; + char promisc; }; /** From 431f9d72ffa76031808cb2ed9c90d1da3621c8de Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:07 -0700 Subject: [PATCH 35/53] net: dsa: enable master promisc mode if available and needed If ports have their own unique MAC addrs and master has a set_promisc function, call it so that packets will be received for ports. Signed-off-by: Tim Harvey Reviewed-by: Ramon Fried --- net/dsa-uclass.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 7ea1cb6949..694664d81b 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -277,8 +277,15 @@ static int dsa_port_probe(struct udevice *pdev) * has a unique MAC address specified in the environment. */ eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr); - if (!is_zero_ethaddr(env_enetaddr)) + if (!is_zero_ethaddr(env_enetaddr)) { + /* individual port mac addrs require master to be promisc */ + struct eth_ops *eth_ops = eth_get_ops(master); + + if (eth_ops->set_promisc) + eth_ops->set_promisc(master, 1); + return 0; + } master_pdata = dev_get_plat(master); eth_pdata = dev_get_plat(pdev); From 668e205098215acf13f72b892aea9267dc23dd19 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:08 -0700 Subject: [PATCH 36/53] net: add support for KSZ9477/KSZ9897/KSZ9567 GbE switch The Microchip KSZ9477/KSZ9897/KSZ9567 7-Port Gigabit Ethernet Switches support SGMII/RGMII/MII/RMII with register access via SPI, I2C, or MDIO. This driver currently supports I2C register access but SPI or MDIO register access can be easily added at a later time. Tagging is not implemented and instead the active port is tracked to avoid needing a tag to store port information. This was tested with the imx8mm-venice-gw7901 board which has a KSZ9897S switch with an IMX8MM FEC MAC master connected via RGMII_ID. Signed-off-by: Tim Harvey Reviewed-by: Ramon Fried --- drivers/net/Kconfig | 7 + drivers/net/Makefile | 1 + drivers/net/ksz9477.c | 546 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 554 insertions(+) create mode 100644 drivers/net/ksz9477.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 483401681d..726ad36b7c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -402,6 +402,13 @@ config KS8851_MLL_BASEADDR endif #DM_ETH endif #KS8851_MLL +config KSZ9477 + bool "Microchip KSZ9477 I2C controller driver" + depends on DM_DSA && DM_I2C + help + This driver implements a DSA switch driver for the KSZ9477 family + of GbE switches using the I2C interface. + config MVGBE bool "Marvell Orion5x/Kirkwood network interface support" depends on ARCH_KIRKWOOD || ARCH_ORION5X diff --git a/drivers/net/Makefile b/drivers/net/Makefile index d56baa65b2..03900ffa3a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_FTMAC110) += ftmac110.o obj-$(CONFIG_FTMAC100) += ftmac100.o obj-$(CONFIG_GMAC_ROCKCHIP) += gmac_rockchip.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o +obj-$(CONFIG_KSZ9477) += ksz9477.o obj-$(CONFIG_LAN91C96) += lan91c96.o obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o obj-$(CONFIG_MACB) += macb.o diff --git a/drivers/net/ksz9477.c b/drivers/net/ksz9477.c new file mode 100644 index 0000000000..ed8f1895cb --- /dev/null +++ b/drivers/net/ksz9477.c @@ -0,0 +1,546 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 + * Tim Harvey, Gateworks Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Global registers */ + +/* Chip ID */ +#define REG_CHIP_ID0__1 0x0000 + +/* Operation control */ +#define REG_SW_OPERATION 0x0300 +#define SW_RESET BIT(1) +#define SW_START BIT(0) + +/* Port Specific Registers */ +#define PORT_CTRL_ADDR(port, addr) ((addr) | (((port) + 1) << 12)) + +/* Port Control */ +#define REG_PORT_XMII_CTRL_1 0x0301 +#define PORT_MII_NOT_1GBIT BIT(6) +#define PORT_MII_SEL_EDGE BIT(5) +#define PORT_RGMII_ID_IG_ENABLE BIT(4) +#define PORT_RGMII_ID_EG_ENABLE BIT(3) +#define PORT_MII_MAC_MODE BIT(2) +#define PORT_MII_SEL_M 0x3 +#define PORT_RGMII_SEL 0x0 +#define PORT_RMII_SEL 0x1 +#define PORT_GMII_SEL 0x2 +#define PORT_MII_SEL 0x3 + +/* Port MSTP State Register */ +#define REG_PORT_MSTP_STATE 0x0b04 +#define PORT_TX_ENABLE BIT(2) +#define PORT_RX_ENABLE BIT(1) +#define PORT_LEARN_DISABLE BIT(0) + +/* MMD */ +#define REG_PORT_PHY_MMD_SETUP 0x011A +#define PORT_MMD_OP_MODE_M 0x3 +#define PORT_MMD_OP_MODE_S 14 +#define PORT_MMD_OP_INDEX 0 +#define PORT_MMD_OP_DATA_NO_INCR 1 +#define PORT_MMD_OP_DATA_INCR_RW 2 +#define PORT_MMD_OP_DATA_INCR_W 3 +#define PORT_MMD_DEVICE_ID_M 0x1F +#define MMD_SETUP(mode, dev) (((u16)(mode) << PORT_MMD_OP_MODE_S) | (dev)) +#define REG_PORT_PHY_MMD_INDEX_DATA 0x011C + +struct ksz_dsa_priv { + struct udevice *dev; + int active_port; +}; + +static inline int ksz_read8(struct udevice *dev, u32 reg, u8 *val) +{ + int ret = dm_i2c_read(dev, reg, val, 1); + + dev_dbg(dev, "%s 0x%04x<<0x%02x\n", __func__, reg, *val); + + return ret; +} + +static inline int ksz_pread8(struct udevice *dev, int port, int reg, u8 *val) +{ + return ksz_read8(dev, PORT_CTRL_ADDR(port, reg), val); +} + +static inline int ksz_write8(struct udevice *dev, u32 reg, u8 val) +{ + dev_dbg(dev, "%s 0x%04x>>0x%02x\n", __func__, reg, val); + return dm_i2c_write(dev, reg, &val, 1); +} + +static inline int ksz_pwrite8(struct udevice *dev, int port, int reg, u8 val) +{ + return ksz_write8(dev, PORT_CTRL_ADDR(port, reg), val); +} + +static inline int ksz_write16(struct udevice *dev, u32 reg, u16 val) +{ + u8 buf[2]; + + buf[1] = val & 0xff; + buf[0] = val >> 8; + dev_dbg(dev, "%s 0x%04x>>0x%04x\n", __func__, reg, val); + + return dm_i2c_write(dev, reg, buf, 2); +} + +static inline int ksz_pwrite16(struct udevice *dev, int port, int reg, u16 val) +{ + return ksz_write16(dev, PORT_CTRL_ADDR(port, reg), val); +} + +static inline int ksz_read16(struct udevice *dev, u32 reg, u16 *val) +{ + u8 buf[2]; + int ret; + + ret = dm_i2c_read(dev, reg, buf, 2); + *val = (buf[0] << 8) | buf[1]; + dev_dbg(dev, "%s 0x%04x<<0x%04x\n", __func__, reg, *val); + + return ret; +} + +static inline int ksz_pread16(struct udevice *dev, int port, int reg, u16 *val) +{ + return ksz_read16(dev, PORT_CTRL_ADDR(port, reg), val); +} + +static inline int ksz_read32(struct udevice *dev, u32 reg, u32 *val) +{ + return dm_i2c_read(dev, reg, (u8 *)val, 4); +} + +static inline int ksz_pread32(struct udevice *dev, int port, int reg, u32 *val) +{ + return ksz_read32(dev, PORT_CTRL_ADDR(port, reg), val); +} + +static inline int ksz_write32(struct udevice *dev, u32 reg, u32 val) +{ + u8 buf[4]; + + buf[3] = val & 0xff; + buf[2] = (val >> 24) & 0xff; + buf[1] = (val >> 16) & 0xff; + buf[0] = (val >> 8) & 0xff; + dev_dbg(dev, "%s 0x%04x>>0x%04x\n", __func__, reg, val); + + return dm_i2c_write(dev, reg, buf, 4); +} + +static inline int ksz_pwrite32(struct udevice *dev, int port, int reg, u32 val) +{ + return ksz_write32(dev, PORT_CTRL_ADDR(port, reg), val); +} + +static __maybe_unused void ksz_port_mmd_read(struct udevice *dev, int port, + u8 addr, u16 reg, u16 *val) +{ + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_INDEX, addr)); + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, reg); + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_DATA_NO_INCR, addr)); + ksz_pread16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, val); + dev_dbg(dev, "%s P%d 0x%02x:0x%04x<<0x%04x\n", __func__, port + 1, addr, reg, *val); +} + +static void ksz_port_mmd_write(struct udevice *dev, int port, u8 addr, u16 reg, u16 val) +{ + dev_dbg(dev, "%s P%d 0x%02x:0x%04x>>0x%04x\n", __func__, port + 1, addr, addr, val); + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_INDEX, addr)); + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, addr); + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_SETUP, MMD_SETUP(PORT_MMD_OP_DATA_NO_INCR, addr)); + ksz_pwrite16(dev, port, REG_PORT_PHY_MMD_INDEX_DATA, val); +} + +/* Apply PHY settings to address errata listed in KSZ9477, KSZ9897, KSZ9896, KSZ9567 + * Silicon Errata and Data Sheet Clarification documents + */ +static void ksz_phy_errata_setup(struct udevice *dev, int port) +{ + dev_dbg(dev, "%s P%d\n", __func__, port + 1); + + /* Register settings are needed to improve PHY receive performance */ + ksz_port_mmd_write(dev, port, 0x01, 0x6f, 0xdd0b); + ksz_port_mmd_write(dev, port, 0x01, 0x8f, 0x6032); + ksz_port_mmd_write(dev, port, 0x01, 0x9d, 0x248c); + ksz_port_mmd_write(dev, port, 0x01, 0x75, 0x0060); + ksz_port_mmd_write(dev, port, 0x01, 0xd3, 0x7777); + ksz_port_mmd_write(dev, port, 0x1c, 0x06, 0x3008); + ksz_port_mmd_write(dev, port, 0x1c, 0x08, 0x2001); + + /* Transmit waveform amplitude can be improved (1000BASE-T, 100BASE-TX, 10BASE-Te) */ + ksz_port_mmd_write(dev, port, 0x1c, 0x04, 0x00d0); + + /* Energy Efficient Ethernet (EEE) feature select must be manually disabled */ + ksz_port_mmd_write(dev, port, 0x07, 0x3c, 0x0000); + + /* Register settings are required to meet data sheet supply current specifications */ + ksz_port_mmd_write(dev, port, 0x1c, 0x13, 0x6eff); + ksz_port_mmd_write(dev, port, 0x1c, 0x14, 0xe6ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x15, 0x6eff); + ksz_port_mmd_write(dev, port, 0x1c, 0x16, 0xe6ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x17, 0x00ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x18, 0x43ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x19, 0xc3ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x1a, 0x6fff); + ksz_port_mmd_write(dev, port, 0x1c, 0x1b, 0x07ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x1c, 0x0fff); + ksz_port_mmd_write(dev, port, 0x1c, 0x1d, 0xe7ff); + ksz_port_mmd_write(dev, port, 0x1c, 0x1e, 0xefff); + ksz_port_mmd_write(dev, port, 0x1c, 0x20, 0xeeee); +} + +/* + * mii bus driver + */ +#define KSZ_MDIO_CHILD_DRV_NAME "ksz_mdio" + +struct ksz_mdio_priv { + struct ksz_dsa_priv *ksz; +}; + +static int dm_ksz_mdio_read(struct udevice *dev, int addr, int devad, int reg) +{ + struct ksz_mdio_priv *priv = dev_get_priv(dev); + struct ksz_dsa_priv *ksz = priv->ksz; + u16 val = 0xffff; + + ksz_pread16(ksz->dev, addr, 0x100 + (reg << 1), &val); + dev_dbg(ksz->dev, "%s P%d reg=0x%04x:0x%04x<<0x%04x\n", __func__, + addr + 1, reg, 0x100 + (reg << 1), val); + + return val; +}; + +static int dm_ksz_mdio_write(struct udevice *dev, int addr, int devad, int reg, u16 val) +{ + struct ksz_mdio_priv *priv = dev_get_priv(dev); + struct ksz_dsa_priv *ksz = priv->ksz; + + dev_dbg(ksz->dev, "%s P%d reg=0x%04x:%04x>>0x%04x\n", + __func__, addr + 1, reg, 0x100 + (reg << 1), val); + ksz_pwrite16(ksz->dev, addr, 0x100 + (reg << 1), val); + + return 0; +} + +static const struct mdio_ops ksz_mdio_ops = { + .read = dm_ksz_mdio_read, + .write = dm_ksz_mdio_write, +}; + +static int ksz_mdio_bind(struct udevice *dev) +{ + char name[16]; + static int num_devices; + + dev_dbg(dev, "%s\n", __func__); + sprintf(name, "ksz-mdio-%d", num_devices++); + device_set_name(dev, name); + + return 0; +} + +static int ksz_mdio_probe(struct udevice *dev) +{ + struct ksz_mdio_priv *priv = dev_get_priv(dev); + + dev_dbg(dev, "%s\n", __func__); + priv->ksz = dev_get_parent_priv(dev->parent); + + return 0; +} + +static const struct udevice_id ksz_mdio_ids[] = { + { .compatible = "microchip,ksz-mdio" }, + { } +}; + +U_BOOT_DRIVER(ksz_mdio) = { + .name = KSZ_MDIO_CHILD_DRV_NAME, + .id = UCLASS_MDIO, + .of_match = ksz_mdio_ids, + .bind = ksz_mdio_bind, + .probe = ksz_mdio_probe, + .ops = &ksz_mdio_ops, + .priv_auto = sizeof(struct ksz_mdio_priv), + .plat_auto = sizeof(struct mdio_perdev_priv), +}; + +static int ksz_port_setup(struct udevice *dev, int port, + phy_interface_t interface) +{ + struct dsa_pdata *pdata = dev_get_uclass_plat(dev); + u8 data8; + + dev_dbg(dev, "%s P%d %s\n", __func__, port + 1, + (port == pdata->cpu_port) ? "cpu" : ""); + + if (port != pdata->cpu_port) { + /* phy port: config errata and leds */ + ksz_phy_errata_setup(dev, port); + } else { + /* cpu port: configure MAC interface mode */ + ksz_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8); + dev_dbg(dev, "%s P%d cpu interface %s\n", __func__, port + 1, + phy_string_for_interface(interface)); + switch (interface) { + case PHY_INTERFACE_MODE_MII: + data8 &= ~PORT_MII_SEL_M; + data8 |= PORT_MII_SEL; + data8 |= PORT_MII_NOT_1GBIT; + break; + case PHY_INTERFACE_MODE_RMII: + data8 &= ~PORT_MII_SEL_M; + data8 |= PORT_RMII_SEL; + data8 |= PORT_MII_NOT_1GBIT; + break; + case PHY_INTERFACE_MODE_GMII: + data8 &= ~PORT_MII_SEL_M; + data8 |= PORT_GMII_SEL; + data8 &= ~PORT_MII_NOT_1GBIT; + break; + default: + data8 &= ~PORT_MII_SEL_M; + data8 |= PORT_RGMII_SEL; + data8 &= ~PORT_MII_NOT_1GBIT; + data8 &= ~PORT_RGMII_ID_IG_ENABLE; + data8 &= ~PORT_RGMII_ID_EG_ENABLE; + if (interface == PHY_INTERFACE_MODE_RGMII_ID || + interface == PHY_INTERFACE_MODE_RGMII_RXID) + data8 |= PORT_RGMII_ID_IG_ENABLE; + if (interface == PHY_INTERFACE_MODE_RGMII_ID || + interface == PHY_INTERFACE_MODE_RGMII_TXID) + data8 |= PORT_RGMII_ID_EG_ENABLE; + break; + } + ksz_write8(dev, PORT_CTRL_ADDR(port, REG_PORT_XMII_CTRL_1), data8); + } + + return 0; +} + +static int ksz_port_enable(struct udevice *dev, int port, struct phy_device *phy) +{ + struct dsa_pdata *pdata = dev_get_uclass_plat(dev); + struct ksz_dsa_priv *priv = dev_get_priv(dev); + int supported = PHY_GBIT_FEATURES; + u8 data8; + int ret; + + dev_dbg(dev, "%s P%d 0x%x %s\n", __func__, port + 1, phy->phy_id, + phy_string_for_interface(phy->interface)); + + /* setup this port */ + ret = ksz_port_setup(dev, port, phy->interface); + if (ret) { + dev_err(dev, "port setup failed: %d\n", ret); + return ret; + } + + /* enable port forwarding for this port */ + ksz_pread8(priv->dev, port, REG_PORT_MSTP_STATE, &data8); + data8 &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE); + data8 |= (PORT_TX_ENABLE | PORT_RX_ENABLE); + ksz_pwrite8(priv->dev, port, REG_PORT_MSTP_STATE, data8); + + /* if cpu master we are done */ + if (port == pdata->cpu_port) + return 0; + + /* configure phy */ + phy->supported &= supported; + phy->advertising &= supported; + ret = phy_config(phy); + if (ret) + return ret; + + ret = phy_startup(phy); + if (ret) + return ret; + + /* start switch */ + ksz_read8(priv->dev, REG_SW_OPERATION, &data8); + data8 |= SW_START; + ksz_write8(priv->dev, REG_SW_OPERATION, data8); + + /* keep track of current enabled non-cpu port */ + priv->active_port = port; + + return 0; +} + +static void ksz_port_disable(struct udevice *dev, int port, struct phy_device *phy) +{ + struct dsa_pdata *pdata = dev_get_uclass_plat(dev); + struct ksz_dsa_priv *priv = dev_get_priv(dev); + u8 data8; + + dev_dbg(dev, "%s P%d 0x%x\n", __func__, port + 1, phy->phy_id); + + /* can't disable CPU port without re-configuring/re-starting switch */ + if (port == pdata->cpu_port) + return; + + /* disable port */ + ksz_pread8(priv->dev, port, REG_PORT_MSTP_STATE, &data8); + data8 &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE); + data8 |= PORT_LEARN_DISABLE; + ksz_pwrite8(priv->dev, port, REG_PORT_MSTP_STATE, data8); + + /* + * we don't call phy_shutdown here to avoid waiting next time we use + * the port, but the downside is that remote side will think we're + * actively processing traffic although we are not. + */ +} + +static int ksz_xmit(struct udevice *dev, int port, void *packet, int length) +{ + dev_dbg(dev, "%s P%d %d\n", __func__, port + 1, length); + + return 0; +} + +static int ksz_recv(struct udevice *dev, int *port, void *packet, int length) +{ + struct ksz_dsa_priv *priv = dev_get_priv(dev); + + dev_dbg(dev, "%s P%d %d\n", __func__, priv->active_port + 1, length); + *port = priv->active_port; + + return 0; +}; + +static const struct dsa_ops ksz_dsa_ops = { + .port_enable = ksz_port_enable, + .port_disable = ksz_port_disable, + .xmit = ksz_xmit, + .rcv = ksz_recv, +}; + +static int ksz_probe_mdio(struct udevice *dev) +{ + ofnode node, mdios; + int ret; + + mdios = dev_read_subnode(dev, "mdios"); + if (ofnode_valid(mdios)) { + ofnode_for_each_subnode(node, mdios) { + const char *name = ofnode_get_name(node); + struct udevice *pdev; + + ret = device_bind_driver_to_node(dev, + KSZ_MDIO_CHILD_DRV_NAME, + name, node, &pdev); + if (ret) + dev_err(dev, "failed to probe %s: %d\n", name, ret); + } + } + + return 0; +} + +/* + * I2C driver + */ +static int ksz_i2c_probe(struct udevice *dev) +{ + struct dsa_pdata *pdata = dev_get_uclass_plat(dev); + struct ksz_dsa_priv *priv = dev_get_priv(dev); + struct udevice *master = dsa_get_master(dev); + int i, ret; + u8 data8; + u32 id; + + if (!master) + return -ENODEV; + + dev_dbg(dev, "%s %s master:%s\n", __func__, dev->name, master->name); + dev_set_parent_priv(dev, priv); + + ret = i2c_set_chip_offset_len(dev, 2); + if (ret) { + printf("i2c_set_chip_offset_len failed: %d\n", ret); + return ret; + } + + /* default config */ + priv->dev = dev; + + /* chip level reset */ + ksz_read8(priv->dev, REG_SW_OPERATION, &data8); + data8 |= SW_RESET; + ksz_write8(priv->dev, REG_SW_OPERATION, data8); + + /* read chip id */ + ret = ksz_read32(dev, REG_CHIP_ID0__1, &id); + if (ret) + return ret; + id = __swab32(id); + dev_dbg(dev, "%s id=0x%08x\n", __func__, id); + switch (id & 0xffffff00) { + case 0x00947700: + puts("KSZ9477S: "); + break; + case 0x00956700: + puts("KSZ9567R: "); + break; + case 0x00989700: + puts("KSZ9897S: "); + break; + default: + dev_err(dev, "invalid chip id: 0x%08x\n", id); + return -EINVAL; + } + + /* probe mdio bus */ + ret = ksz_probe_mdio(dev); + if (ret) + return ret; + + /* disable ports by default */ + for (i = 0; i < pdata->num_ports; i++) { + ksz_pread8(priv->dev, i, REG_PORT_MSTP_STATE, &data8); + data8 &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE); + ksz_pwrite8(priv->dev, i, REG_PORT_MSTP_STATE, data8); + } + + dsa_set_tagging(dev, 0, 0); + + return 0; +}; + +static const struct udevice_id ksz_i2c_ids[] = { + { .compatible = "microchip,ksz9897" }, + { .compatible = "microchip,ksz9477" }, + { .compatible = "microchip,ksz9567" }, + { } +}; + +U_BOOT_DRIVER(ksz) = { + .name = "ksz-switch", + .id = UCLASS_DSA, + .of_match = ksz_i2c_ids, + .probe = ksz_i2c_probe, + .ops = &ksz_dsa_ops, + .priv_auto = sizeof(struct ksz_dsa_priv), +}; From 1cb87b929e1ec92dd1f984f265b29f500019b300 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:09 -0700 Subject: [PATCH 37/53] arm: dts: imx8mm-venice-gw7901.dts: fix dsa switch configuration Fix the dsa switch config: - remove the unnecessary phy-mode from the switch itself - added the necessary fixed-link node to the non-cpu ports required for U-Boot DSA Signed-off-by: Tim Harvey --- arch/arm/dts/imx8mm-venice-gw7901.dts | 37 ++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/imx8mm-venice-gw7901.dts b/arch/arm/dts/imx8mm-venice-gw7901.dts index 0216facb2a..124e1e4e70 100644 --- a/arch/arm/dts/imx8mm-venice-gw7901.dts +++ b/arch/arm/dts/imx8mm-venice-gw7901.dts @@ -577,7 +577,6 @@ pinctrl-0 = <&pinctrl_ksz>; interrupt-parent = <&gpio4>; interrupts = <18 IRQ_TYPE_EDGE_FALLING>; - phy-mode = "rgmii-id"; ports { #address-cells = <1>; @@ -587,24 +586,32 @@ reg = <0>; label = "lan1"; local-mac-address = [00 00 00 00 00 00]; + phy-handle = <&sw_phy0>; + phy-mode = "internal"; }; lan2: port@1 { reg = <1>; label = "lan2"; local-mac-address = [00 00 00 00 00 00]; + phy-handle = <&sw_phy1>; + phy-mode = "internal"; }; lan3: port@2 { reg = <2>; label = "lan3"; local-mac-address = [00 00 00 00 00 00]; + phy-handle = <&sw_phy2>; + phy-mode = "internal"; }; lan4: port@3 { reg = <3>; label = "lan4"; local-mac-address = [00 00 00 00 00 00]; + phy-handle = <&sw_phy3>; + phy-mode = "internal"; }; port@5 { @@ -619,6 +626,34 @@ }; }; }; + + mdios { + #address-cells = <1>; + #size-cells = <0>; + + mdio@0 { + reg = <0>; + compatible = "microchip,ksz-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + sw_phy0: ethernet-phy@0 { + reg = <0x0>; + }; + + sw_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + + sw_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + + sw_phy3: ethernet-phy@3 { + reg = <0x3>; + }; + }; + }; }; crypto@60 { From 9fe2106fe0adcbc860e741382790e85e9081d397 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 16:50:10 -0700 Subject: [PATCH 38/53] configs: imx8mm_venice_defconfig: add support for gbe switch The imx8mm-venice-gw7901 board has an I2C connected KSZ9897S GbE switch with an IMX8MM FEC MAC master connected via RGMII_ID. Signed-off-by: Tim Harvey --- configs/imx8mm_venice_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configs/imx8mm_venice_defconfig b/configs/imx8mm_venice_defconfig index 3961db00cb..49affccec4 100644 --- a/configs/imx8mm_venice_defconfig +++ b/configs/imx8mm_venice_defconfig @@ -87,9 +87,13 @@ CONFIG_SPL_MMC_HS400_SUPPORT=y CONFIG_FSL_USDHC=y CONFIG_PHYLIB=y CONFIG_PHY_TI_DP83867=y +CONFIG_PHY_FIXED=y CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y +CONFIG_DM_DSA=y CONFIG_PHY_GIGE=y CONFIG_FEC_MXC=y +CONFIG_KSZ9477=y CONFIG_MII=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y From c4e565662086170b4d1080800b0c09f0a14a9bde Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 17:07:38 -0700 Subject: [PATCH 39/53] board: gateworks: venice: gsc: fix typo Fix typo in error message. Signed-off-by: Tim Harvey --- board/gateworks/venice/gsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/gateworks/venice/gsc.c b/board/gateworks/venice/gsc.c index d2490e6063..23ad58094c 100644 --- a/board/gateworks/venice/gsc.c +++ b/board/gateworks/venice/gsc.c @@ -176,7 +176,7 @@ static int gsc_read_eeprom(int bus, int slave, int alen, struct venice_board_inf chksum += buf[i]; if ((info->chksum[0] != chksum >> 8) || (info->chksum[1] != (chksum & 0xff))) { - printf("EEPROM: I2C%d@0x%02x: Invalid Model in EEPROM\n", bus, slave); + printf("EEPROM: I2C%d@0x%02x: Invalid Checksum\n", bus, slave); print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, sizeof(*info)); memset(info, 0, sizeof(*info)); return -EINVAL; From 658eb1abd84378d52b9157ca5190475091d0f608 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 17:07:39 -0700 Subject: [PATCH 40/53] board: gateworks: venice: gsc: fix voltage offset The voltage offset property is in microvolts so must be scaled accordingly. Signed-off-by: Tim Harvey --- board/gateworks/venice/gsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/gateworks/venice/gsc.c b/board/gateworks/venice/gsc.c index 23ad58094c..9a6712ec88 100644 --- a/board/gateworks/venice/gsc.c +++ b/board/gateworks/venice/gsc.c @@ -298,7 +298,7 @@ int gsc_hwmon(void) } /* adjust by offset */ - val += offset; + val += (offset / 1000); printf("%-8s: %d.%03dV\n", label, val / 1000, val % 1000); break; From 9d2e639f8ed606cfca1b1f862023c73122b5ec66 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 17:07:40 -0700 Subject: [PATCH 41/53] board: gateworks: venice: display DTB used Display the DTB file used for U-Boot. Signed-off-by: Tim Harvey --- board/gateworks/venice/imx8mm_venice.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/board/gateworks/venice/imx8mm_venice.c b/board/gateworks/venice/imx8mm_venice.c index 1d51b6ea9b..cb00f532bf 100644 --- a/board/gateworks/venice/imx8mm_venice.c +++ b/board/gateworks/venice/imx8mm_venice.c @@ -42,12 +42,16 @@ int board_fit_config_name_match(const char *name) { int i = 0; const char *dtb; + static char init; char buf[32]; do { dtb = gsc_get_dtb_name(i++, buf, sizeof(buf)); - if (!strcmp(dtb, name)) + if (!strcmp(dtb, name)) { + if (!init++) + printf("DTB : %s\n", name); return 0; + } } while (dtb); return -1; From 0f3f6e62eaf6e6d309173c1dbe31b5d811cf08b4 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 17:07:41 -0700 Subject: [PATCH 42/53] board: gateworks: venice: add ftd_file env vars on boot The ftd_file* vars can be used by bootscripts to look for appropriate dtb's Signed-off-by: Tim Harvey --- board/gateworks/venice/imx8mm_venice.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/board/gateworks/venice/imx8mm_venice.c b/board/gateworks/venice/imx8mm_venice.c index cb00f532bf..2657bd675f 100644 --- a/board/gateworks/venice/imx8mm_venice.c +++ b/board/gateworks/venice/imx8mm_venice.c @@ -105,13 +105,26 @@ int board_init(void) int board_late_init(void) { - const char *ethmac; + const char *str; char env[32]; int ret, i; u8 enetaddr[6]; + char fdt[64]; led_default_state(); + /* Set fdt_file vars */ + i = 0; + do { + str = gsc_get_dtb_name(i, fdt, sizeof(fdt)); + if (str) { + sprintf(env, "fdt_file%d", i + 1); + strcat(fdt, ".dtb"); + env_set(env, fdt); + } + i++; + } while (str); + /* Set mac addrs */ i = 0; do { @@ -119,8 +132,8 @@ int board_late_init(void) sprintf(env, "eth%daddr", i); else sprintf(env, "ethaddr"); - ethmac = env_get(env); - if (!ethmac) { + str = env_get(env); + if (!str) { ret = gsc_getmac(i, enetaddr); if (!ret) eth_env_set_enetaddr(env, enetaddr); From d107235a38920dcff8f35fefafeebd3479411513 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 30 Jun 2021 17:07:42 -0700 Subject: [PATCH 43/53] board: gateworks: venice: remove forced enable of GSC thermal protection The Gateworks System Controller thermal protection feature will disable the board primary power supply if the on-board temperature sensor reaches 86C. In many cases this could occur before the temperature critical components such as CPU, DRAM, eMMC, and power supplies have reached their max temperature. Remove the forced re-enable of thermal protection so that users can knowingly disable it. Signed-off-by: Tim Harvey --- board/gateworks/venice/gsc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/board/gateworks/venice/gsc.c b/board/gateworks/venice/gsc.c index 9a6712ec88..c75bc6f855 100644 --- a/board/gateworks/venice/gsc.c +++ b/board/gateworks/venice/gsc.c @@ -221,9 +221,11 @@ static const char *gsc_get_rst_cause(struct udevice *dev) /* thermal protection */ if (!dm_i2c_read(dev, GSC_SC_THERM_PROTECT, ®, 1)) { - reg |= 1; - dm_i2c_write(dev, GSC_SC_THERM_PROTECT, ®, 1); - strcat(str, " Thermal Protection Enabled"); + strcat(str, " Thermal Protection "); + if (reg & BIT(0)) + strcat(str, "Enabled"); + else + strcat(str, "Disabled"); } return str; From 9b19159174f72655e59ddc94ed79c21c01a80539 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 3 Jul 2021 04:55:32 +0200 Subject: [PATCH 44/53] spl: mmc: Factor out eMMC boot partition selection code Factor out eMMC boot partition selection code into default_spl_mmc_emmc_boot_partition() function and implement weak spl_mmc_emmc_boot_partition(), so that architecture or board code can override the eMMC boot partition selection. Signed-off-by: Marek Vasut Cc: Faiz Abbas Cc: Harald Seiler Cc: Lokesh Vutla Cc: Simon Glass Cc: Fabio Estevam Cc: Peng Fan Cc: Stefano Babic Cc: Ye Li Reviewed-by: Jaehoon Chung --- common/spl/spl_mmc.c | 37 ++++++++++++++++++++++++------------- include/spl.h | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index add2785b4e..2377d0937d 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -324,6 +324,29 @@ unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc, return raw_sect; } +int default_spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + int part; +#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION + part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION; +#else + /* + * We need to check what the partition is configured to. + * 1 and 2 match up to boot0 / boot1 and 7 is user data + * which is the first physical partition (0). + */ + part = (mmc->part_config >> 3) & PART_ACCESS_MASK; + if (part == 7) + part = 0; +#endif + return part; +} + +int __weak spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + return default_spl_mmc_emmc_boot_partition(mmc); +} + int spl_mmc_load(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, const char *filename, @@ -355,19 +378,7 @@ int spl_mmc_load(struct spl_image_info *spl_image, err = -EINVAL; switch (boot_mode) { case MMCSD_MODE_EMMCBOOT: -#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION - part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION; -#else - /* - * We need to check what the partition is configured to. - * 1 and 2 match up to boot0 / boot1 and 7 is user data - * which is the first physical partition (0). - */ - part = (mmc->part_config >> 3) & PART_ACCESS_MASK; - - if (part == 7) - part = 0; -#endif + part = spl_mmc_emmc_boot_partition(mmc); if (CONFIG_IS_ENABLED(MMC_TINY)) err = mmc_switch_part(mmc, part); diff --git a/include/spl.h b/include/spl.h index cee9a42ddb..c643943482 100644 --- a/include/spl.h +++ b/include/spl.h @@ -357,6 +357,29 @@ u32 spl_mmc_boot_mode(const u32 boot_device); * If not overridden, it is weakly defined in common/spl/spl_mmc.c. */ int spl_mmc_boot_partition(const u32 boot_device); + +struct mmc; +/** + * default_spl_mmc_emmc_boot_partition() - eMMC boot partition to load U-Boot from. + * mmc: Pointer for the mmc device structure + * + * This function should return the eMMC boot partition number which + * the SPL should load U-Boot from (on the given boot_device). + */ +int default_spl_mmc_emmc_boot_partition(struct mmc *mmc); + +/** + * spl_mmc_emmc_boot_partition() - eMMC boot partition to load U-Boot from. + * mmc: Pointer for the mmc device structure + * + * This function should return the eMMC boot partition number which + * the SPL should load U-Boot from (on the given boot_device). + * + * If not overridden, it is weakly defined in common/spl/spl_mmc.c + * and calls default_spl_mmc_emmc_boot_partition(); + */ +int spl_mmc_emmc_boot_partition(struct mmc *mmc); + void spl_set_bd(void); /** From a5ee05cf7180b411ffdf148ca8cb220c029f2e19 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 3 Jul 2021 04:55:33 +0200 Subject: [PATCH 45/53] ARM: imx: Pick correct eMMC boot partition from ROM log In case the iMX8M boot from eMMC boot partition and the primary image is corrupted, the BootROM is capable of starting a secondary image in the other eMMC boot partition as a fallback. However, the BootROM leaves the eMMC BOOT_PARTITION_ENABLE setting as it was, i.e. pointing to the boot partition containing the corrupted image, and the BootROM does not provide any indication that this sort of fallback occured. According to AN12853 i.MX ROMs Log Events, Rev. 0, May 2020, it is possible to determine whether fallback event occurred by parsing the ROM event log. In case ROM event ID 0x51 is present, fallback event did occur. This patch implements ROM event log parsing and search for event ID 0x51 for all iMX8M SoCs, and based on that corrects the eMMC boot partition selection. This way, the SPL loads the remaining boot components from the same eMMC boot partition from which it was started, even in case of the fallback. Signed-off-by: Marek Vasut Cc: Faiz Abbas Cc: Harald Seiler Cc: Lokesh Vutla Cc: Simon Glass Cc: Fabio Estevam Cc: Peng Fan Cc: Stefano Babic Cc: Ye Li --- arch/arm/mach-imx/imx8m/soc.c | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index f5983320c7..f2ddc834d4 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -585,6 +585,67 @@ enum boot_device get_boot_device(void) } #endif +#if defined(CONFIG_IMX8M) +#include +int spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + u32 *rom_log_addr = (u32 *)0x9e0; + u32 *rom_log; + u8 event_id; + int i, part; + + part = default_spl_mmc_emmc_boot_partition(mmc); + + /* If the ROM event log pointer is not valid. */ + if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 || + *rom_log_addr & 0x3) + return part; + + /* Parse the ROM event ID version 2 log */ + rom_log = (u32 *)(uintptr_t)(*rom_log_addr); + for (i = 0; i < 128; i++) { + event_id = rom_log[i] >> 24; + switch (event_id) { + case 0x00: /* End of list */ + return part; + /* Log entries with 1 parameter, skip 1 */ + case 0x80: /* Start to perform the device initialization */ + case 0x81: /* The boot device initialization completes */ + case 0x8f: /* The boot device initialization fails */ + case 0x90: /* Start to read data from boot device */ + case 0x91: /* Reading data from boot device completes */ + case 0x9f: /* Reading data from boot device fails */ + i += 1; + continue; + /* Log entries with 2 parameters, skip 2 */ + case 0xa0: /* Image authentication result */ + case 0xc0: /* Jump to the boot image soon */ + i += 2; + continue; + /* Boot from the secondary boot image */ + case 0x51: + /* + * Swap the eMMC boot partitions in case there was a + * fallback event (i.e. primary image was corrupted + * and that corruption was recognized by the BootROM), + * so the SPL loads the rest of the U-Boot from the + * correct eMMC boot partition, since the BootROM + * leaves the boot partition set to the corrupted one. + */ + if (part == 1) + part = 2; + else if (part == 2) + part = 1; + continue; + default: + continue; + } + } + + return part; +} +#endif + bool is_usb_boot(void) { return get_boot_device() == USB_BOOT; From 55d46761a30f779dc82544bdc0de89f4c8c6e4ea Mon Sep 17 00:00:00 2001 From: Cody Gray Date: Sat, 26 Jun 2021 22:15:22 -0700 Subject: [PATCH 46/53] mx6sabresd: Make checkboard respect CONFIG_NXP_BOARD_REVISION The default implementation of checkboard() calls the nxp_board_rev_string() function to retrieve a character representing the revision number of the board. However, this attempt to retrieve the revision number may fail in certain situations or be otherwise undesirable. There is already a configuration option to avoid retrieving the revision number of the board: CONFIG_NXP_BOARD_REVISION. In fact, if this option is enabled, the nxp_board_rev_string() function's definition will be omitted entirely, meaning that the previous implementation of checkboard() would result in a linker error. This changeset makes the default implementation of checkboard() respect the CONFIG_NXP_BOARD_REVISION configuration option, only attempting to retrieve the board revision number if that option is defined. Signed-off-by: Cody Gray --- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index 57fab23864..e7958df402 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -320,7 +320,10 @@ int board_late_init(void) int checkboard(void) { +#ifdef CONFIG_NXP_BOARD_REVISION printf("Board: MX6SX SABRE SDB rev%c\n", nxp_board_rev_string()); - +#else + puts("Board: MX6SX SABRE SDB"); +#endif return 0; } From 375d7e92980671c868788daf106e66d212faad6a Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Sat, 10 Jul 2021 16:31:29 +0200 Subject: [PATCH 47/53] spi: mxc_spi: fix warnings if CLK_ENABLED not set Following warnings (unused variables) are raised: drivers/spi/mxc_spi.c: In function 'mxc_spi_probe': drivers/spi/mxc_spi.c:595:14: error: unused variable 'blob' [-Werror=unused-variable] 595 | const void *blob = gd->fdt_blob; | ^~~~ drivers/spi/mxc_spi.c:594:6: error: unused variable 'node' [-Werror=unused-variable] 594 | int node = dev_of_offset(bus); Move the variable declaration inside the code where they are used. Signed-off-by: Stefano Babic --- drivers/spi/mxc_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index f3dddbdbd7..a80c3e737d 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -591,8 +591,6 @@ void spi_release_bus(struct spi_slave *slave) static int mxc_spi_probe(struct udevice *bus) { struct mxc_spi_slave *mxcs = dev_get_plat(bus); - int node = dev_of_offset(bus); - const void *blob = gd->fdt_blob; int ret; int i; @@ -629,6 +627,8 @@ static int mxc_spi_probe(struct udevice *bus) mxcs->max_hz = clk_get_rate(&clk); #else + int node = dev_of_offset(bus); + const void *blob = gd->fdt_blob; mxcs->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 20000000); #endif From 4266dc1dffc173099966d7e2e0cdf959c93800b8 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 21 Feb 2021 08:26:21 -0800 Subject: [PATCH 48/53] phy: phy-imx8mq-usb: Add USB PHY driver for i.MX8MQ Add the USB PHY driver for i.MX8MQ to work with DWC3 USB controller. Signed-off-by: Ye Li Reviewed-by: Patrick Wildt Tested-by: Patrick Wildt --- drivers/phy/Kconfig | 7 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-imx8mq-usb.c | 197 +++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 drivers/phy/phy-imx8mq-usb.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 008186a10d..09cb744276 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -268,5 +268,12 @@ config PHY_MTK_TPHY multi-ports is first version, otherwise is second veriosn, so you can easily distinguish them by banks layout. +config PHY_IMX8MQ_USB + bool "NXP i.MX8MQ USB PHY Driver" + depends on PHY + depends on IMX8MQ + help + Support the USB3.0 PHY in NXP i.MX8MQ SoC + source "drivers/phy/rockchip/Kconfig" endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 3c4a673a83..c6ad3b1b26 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -31,3 +31,4 @@ obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o +obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o diff --git a/drivers/phy/phy-imx8mq-usb.c b/drivers/phy/phy-imx8mq-usb.c new file mode 100644 index 0000000000..afbc7ad8dd --- /dev/null +++ b/drivers/phy/phy-imx8mq-usb.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 NXP + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PHY_CTRL0 0x0 +#define PHY_CTRL0_REF_SSP_EN BIT(2) +#define PHY_CTRL0_FSEL_MASK GENMASK(10, 5) +#define PHY_CTRL0_FSEL_24M 0x2a +#define PHY_CTRL0_FSEL_100M 0x27 +#define PHY_CTRL0_SSC_RANGE_MASK GENMASK(23, 21) +#define PHY_CTRL0_SSC_RANGE_4003PPM (0x2 << 21) + +#define PHY_CTRL1 0x4 +#define PHY_CTRL1_RESET BIT(0) +#define PHY_CTRL1_COMMONONN BIT(1) +#define PHY_CTRL1_ATERESET BIT(3) +#define PHY_CTRL1_DCDENB BIT(17) +#define PHY_CTRL1_CHRGSEL BIT(18) +#define PHY_CTRL1_VDATSRCENB0 BIT(19) +#define PHY_CTRL1_VDATDETENB0 BIT(20) + +#define PHY_CTRL2 0x8 +#define PHY_CTRL2_TXENABLEN0 BIT(8) +#define PHY_CTRL2_OTG_DISABLE BIT(9) + +#define PHY_CTRL3 0xc +#define PHY_CTRL3_COMPDISTUNE_MASK GENMASK(2, 0) +#define PHY_CTRL3_TXPREEMP_TUNE_MASK GENMASK(16, 15) +#define PHY_CTRL3_TXPREEMP_TUNE_SHIFT 15 +#define PHY_CTRL3_TXRISE_TUNE_MASK GENMASK(21, 20) +#define PHY_CTRL3_TXRISE_TUNE_SHIFT 20 +/* 1111: +24% ... 0000: -6% step: 2% */ +#define PHY_CTRL3_TXVREF_TUNE_MASK GENMASK(25, 22) +#define PHY_CTRL3_TXVREF_TUNE_SHIFT 22 +#define PHY_CTRL3_TX_VBOOST_LEVEL_MASK GENMASK(31, 29) +#define PHY_CTRL3_TX_VBOOST_LEVEL_SHIFT 29 + +#define PHY_CTRL4 0x10 +#define PHY_CTRL4_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(20, 15) +#define PHY_CTRL4_PCS_TX_DEEMPH_3P5DB_SHIFT 15 + +#define PHY_CTRL5 0x14 +#define PHY_CTRL5_DMPWD_OVERRIDE_SEL BIT(23) +#define PHY_CTRL5_DMPWD_OVERRIDE BIT(22) +#define PHY_CTRL5_DPPWD_OVERRIDE_SEL BIT(21) +#define PHY_CTRL5_DPPWD_OVERRIDE BIT(20) +#define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0) + +#define PHY_CTRL6 0x18 +#define PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29) +#define PHY_CTRL6_ALT_CLK_EN BIT(1) +#define PHY_CTRL6_ALT_CLK_SEL BIT(0) + +#define PHY_STS0 0x40 +#define PHY_STS0_OTGSESSVLD BIT(7) +#define PHY_STS0_CHGDET BIT(4) +#define PHY_STS0_FSVPLUS BIT(3) +#define PHY_STS0_FSVMINUS BIT(2) + +struct imx8mq_usb_phy { +#if CONFIG_IS_ENABLED(CLK) + struct clk phy_clk; +#endif + void __iomem *base; +}; + +static const struct udevice_id imx8mq_usb_phy_of_match[] = { + { + .compatible = "fsl,imx8mq-usb-phy", + }, + {}, +}; + +static int imx8mq_usb_phy_init(struct phy *usb_phy) +{ + struct udevice *dev = usb_phy->dev; + struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev); + u32 value; + + value = readl(imx_phy->base + PHY_CTRL1); + value &= ~(PHY_CTRL1_VDATSRCENB0 | PHY_CTRL1_VDATDETENB0 | + PHY_CTRL1_COMMONONN); + value |= PHY_CTRL1_RESET | PHY_CTRL1_ATERESET; + writel(value, imx_phy->base + PHY_CTRL1); + + value = readl(imx_phy->base + PHY_CTRL0); + value |= PHY_CTRL0_REF_SSP_EN; + value &= ~PHY_CTRL0_SSC_RANGE_MASK; + value |= PHY_CTRL0_SSC_RANGE_4003PPM; + writel(value, imx_phy->base + PHY_CTRL0); + + value = readl(imx_phy->base + PHY_CTRL2); + value |= PHY_CTRL2_TXENABLEN0; + writel(value, imx_phy->base + PHY_CTRL2); + + value = readl(imx_phy->base + PHY_CTRL1); + value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET); + writel(value, imx_phy->base + PHY_CTRL1); + + return 0; +} + +static int imx8mq_usb_phy_power_on(struct phy *usb_phy) +{ + struct udevice *dev = usb_phy->dev; + struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev); + u32 value; + +#if CONFIG_IS_ENABLED(CLK) + int ret; + ret = clk_enable(&imx_phy->phy_clk); + if (ret) { + printf("Failed to enable usb phy clock\n"); + return ret; + } +#endif + + /* Disable rx term override */ + value = readl(imx_phy->base + PHY_CTRL6); + value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL; + writel(value, imx_phy->base + PHY_CTRL6); + + return 0; +} + +static int imx8mq_usb_phy_power_off(struct phy *usb_phy) +{ + struct udevice *dev = usb_phy->dev; + struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev); + u32 value; + + /* Override rx term to be 0 */ + value = readl(imx_phy->base + PHY_CTRL6); + value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL; + writel(value, imx_phy->base + PHY_CTRL6); + +#if CONFIG_IS_ENABLED(CLK) + clk_disable(&imx_phy->phy_clk); +#endif + + return 0; +} + +static int imx8mq_usb_phy_exit(struct phy *usb_phy) +{ + return imx8mq_usb_phy_power_off(usb_phy); +} + +struct phy_ops imx8mq_usb_phy_ops = { + .init = imx8mq_usb_phy_init, + .power_on = imx8mq_usb_phy_power_on, + .power_off = imx8mq_usb_phy_power_off, + .exit = imx8mq_usb_phy_exit, +}; + +int imx8mq_usb_phy_probe(struct udevice *dev) +{ + struct imx8mq_usb_phy *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + + if (!priv->base) + return -EINVAL; + +#if CONFIG_IS_ENABLED(CLK) + int ret; + + /* Assigned clock already set clock */ + ret = clk_get_by_name(dev, "phy", &priv->phy_clk); + if (ret) { + printf("Failed to get usb phy clock\n"); + return ret; + } +#endif + + return 0; +} + +U_BOOT_DRIVER(nxp_imx8mq_usb_phy) = { + .name = "nxp_imx8mq_usb_phy", + .id = UCLASS_PHY, + .of_match = imx8mq_usb_phy_of_match, + .probe = imx8mq_usb_phy_probe, + .ops = &imx8mq_usb_phy_ops, + .priv_auto = sizeof(struct imx8mq_usb_phy), +}; From 4390e9f99746aa1ef824b55f810c2fcad80e4229 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 21 Feb 2021 08:26:22 -0800 Subject: [PATCH 49/53] arm: dts: imx8mq: Add alias for two usb controllers Add alias for two DWC3 usb controllers to fix the seq index. Signed-off-by: Ye Li Tested-by: Patrick Wildt --- arch/arm/dts/imx8mq.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/dts/imx8mq.dtsi b/arch/arm/dts/imx8mq.dtsi index a841a023e8..a44f729d0e 100644 --- a/arch/arm/dts/imx8mq.dtsi +++ b/arch/arm/dts/imx8mq.dtsi @@ -39,6 +39,8 @@ spi0 = &ecspi1; spi1 = &ecspi2; spi2 = &ecspi3; + usb0 = &usb_dwc3_0; + usb1 = &usb_dwc3_1; }; ckil: clock-ckil { From 4a837d433c673b6568f7b81428530fd336a22f9b Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 21 Feb 2021 08:26:23 -0800 Subject: [PATCH 50/53] arm: imx8mq: Add USB clock init function Add clock function to setup relevant clocks for USB3.0 controllers and PHYs on i.MX8MQ Signed-off-by: Ye Li Reviewed-by: Patrick Wildt Tested-by: Patrick Wildt --- arch/arm/include/asm/arch-imx8m/clock.h | 1 + arch/arm/mach-imx/imx8m/clock_imx8mq.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8m/clock.h b/arch/arm/include/asm/arch-imx8m/clock.h index 77d9428a18..c705dfdf46 100644 --- a/arch/arm/include/asm/arch-imx8m/clock.h +++ b/arch/arm/include/asm/arch-imx8m/clock.h @@ -257,6 +257,7 @@ u32 imx_get_uartclk(void); int clock_init(void); void init_clk_usdhc(u32 index); void init_uart_clk(u32 index); +void init_usb_clk(void); void init_wdog_clk(void); unsigned int mxc_get_clock(enum mxc_clock clk); int clock_enable(enum clk_ccgr_index index, bool enable); diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c index 8fecc60ecb..60e2218a3c 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c @@ -400,6 +400,28 @@ void init_wdog_clk(void) clock_enable(CCGR_WDOG3, 1); } +void init_usb_clk(void) +{ + if (!is_usb_boot()) { + clock_enable(CCGR_USB_CTRL1, 0); + clock_enable(CCGR_USB_CTRL2, 0); + clock_enable(CCGR_USB_PHY1, 0); + clock_enable(CCGR_USB_PHY2, 0); + /* 500MHz */ + clock_set_target_val(USB_BUS_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + /* 100MHz */ + clock_set_target_val(USB_CORE_REF_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + /* 100MHz */ + clock_set_target_val(USB_PHY_REF_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_USB_CTRL1, 1); + clock_enable(CCGR_USB_CTRL2, 1); + clock_enable(CCGR_USB_PHY1, 1); + clock_enable(CCGR_USB_PHY2, 1); + } +} void init_nand_clk(void) { From cb391e339932d9e87477082b2b4b491a78b9ca41 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 21 Feb 2021 08:26:24 -0800 Subject: [PATCH 51/53] imx8mq_evk: Enable the USB3.0 host port Setup USB clock in board codes, and enable the DWC3 XHCI and PHY drivers to make USB3.0 host port working on i.MX8MQ EVK. Signed-off-by: Ye Li Reviewed-by: Patrick Wildt --- board/freescale/imx8mq_evk/imx8mq_evk.c | 4 ++++ configs/imx8mq_evk_defconfig | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/board/freescale/imx8mq_evk/imx8mq_evk.c b/board/freescale/imx8mq_evk/imx8mq_evk.c index 93da67d779..e394805856 100644 --- a/board/freescale/imx8mq_evk/imx8mq_evk.c +++ b/board/freescale/imx8mq_evk/imx8mq_evk.c @@ -86,6 +86,10 @@ int board_init(void) setup_fec(); #endif +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_DWC3) + init_usb_clk(); +#endif + return 0; } diff --git a/configs/imx8mq_evk_defconfig b/configs/imx8mq_evk_defconfig index 1df4192401..f4d5397674 100644 --- a/configs/imx8mq_evk_defconfig +++ b/configs/imx8mq_evk_defconfig @@ -53,3 +53,12 @@ CONFIG_DM_REGULATOR_GPIO=y CONFIG_DM_RESET=y CONFIG_MXC_UART=y CONFIG_DM_THERMAL=y +CONFIG_CMD_USB=y +CONFIG_USB=y +CONFIG_USB_STORAGE=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_PHY=y +CONFIG_PHY_IMX8MQ_USB=y From c6ae713c7ccf2a6a30b6bffb47d7806c43d9d05f Mon Sep 17 00:00:00 2001 From: Breno Lima Date: Tue, 29 Jun 2021 10:32:34 +0800 Subject: [PATCH 52/53] mx7ulp: Update unlock and refresh sequences in sWDOG driver According to i.MX7ULP Reference Manual the second word write for both UNLOCK and REFRESH operations must occur in maximum 16 bus clock. The current code is using writel() function which has a DMB barrier to order the memory access. The DMB between two words write may introduce some delay in certain circumstance, causing a WDOG timeout due to 16 bus clock window requirement. Replace writel() function by __raw_writel() to achieve a faster memory access and avoid such issue. Reviewed-by: Ye Li Signed-off-by: Breno Lima --- drivers/watchdog/ulp_wdog.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c index 6f63b11b9f..490a2c94ec 100644 --- a/drivers/watchdog/ulp_wdog.c +++ b/drivers/watchdog/ulp_wdog.c @@ -52,8 +52,10 @@ void hw_watchdog_reset(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - writel(REFRESH_WORD0, &wdog->cnt); - writel(REFRESH_WORD1, &wdog->cnt); + dmb(); + __raw_writel(REFRESH_WORD0, &wdog->cnt); + __raw_writel(REFRESH_WORD1, &wdog->cnt); + dmb(); } void hw_watchdog_init(void) @@ -61,8 +63,10 @@ void hw_watchdog_init(void) u8 val; struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - writel(UNLOCK_WORD0, &wdog->cnt); - writel(UNLOCK_WORD1, &wdog->cnt); + dmb(); + __raw_writel(UNLOCK_WORD0, &wdog->cnt); + __raw_writel(UNLOCK_WORD1, &wdog->cnt); + dmb(); val = readb(&wdog->cs2); val |= WDGCS2_FLG; @@ -81,8 +85,10 @@ void reset_cpu(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; - writel(UNLOCK_WORD0, &wdog->cnt); - writel(UNLOCK_WORD1, &wdog->cnt); + dmb(); + __raw_writel(UNLOCK_WORD0, &wdog->cnt); + __raw_writel(UNLOCK_WORD1, &wdog->cnt); + dmb(); hw_watchdog_set_timeout(5); /* 5ms timeout */ writel(0, &wdog->win); From edf95bdeddeab8f0fd7b88d4865fbc6e99071c73 Mon Sep 17 00:00:00 2001 From: Breno Lima Date: Tue, 29 Jun 2021 10:32:35 +0800 Subject: [PATCH 53/53] mx7ulp: wdog: Wait for WDOG unlock and reconfiguration to complete According to i.MX7ULP Reference Manual we should wait for WDOG unlock and reconfiguration to complete. Section "59.5.3 Configure Watchdog" provides the following example: DisableInterrupts; //disable global interrupt WDOG_CNT = 0xD928C520; //unlock watchdog while(WDOG_CS[ULK]==0); //wait until registers are unlocked WDOG_TOVAL = 256; //set timeout value WDOG_CS = WDOG_CS_EN(1) | WDOG_CS_CLK(1) | WDOG_CS_INT(1) | WDOG_CS_WIN(0) | WDOG_CS_UPDATE(1); while(WDOG_CS[RCS]==0); //wait until new configuration takes effect EnableInterrupts; //enable global interrupt Update U-Boot WDOG driver to align with i.MX7ULP reference manual. Use 32 bits accessing to CS register. According to RM, the bits in this register only can write once after unlock. So using 8 bits access will cause problem. Reviewed-by: Ye Li Signed-off-by: Breno Lima Signed-off-by: Peng Fan --- drivers/watchdog/ulp_wdog.c | 39 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c index 490a2c94ec..ecd35ef22a 100644 --- a/drivers/watchdog/ulp_wdog.c +++ b/drivers/watchdog/ulp_wdog.c @@ -12,9 +12,7 @@ * MX7ULP WDOG Register Map */ struct wdog_regs { - u8 cs1; - u8 cs2; - u16 reserve0; + u32 cs; u32 cnt; u32 toval; u32 win; @@ -30,10 +28,12 @@ struct wdog_regs { #define UNLOCK_WORD0 0xC520 /* 1st unlock word */ #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ -#define WDGCS1_WDGE (1<<7) -#define WDGCS1_WDGUPDATE (1<<5) +#define WDGCS_WDGE BIT(7) +#define WDGCS_WDGUPDATE BIT(5) -#define WDGCS2_FLG (1<<6) +#define WDGCS_RCS BIT(10) +#define WDGCS_ULK BIT(11) +#define WDGCS_FLG BIT(14) #define WDG_BUS_CLK (0x0) #define WDG_LPO_CLK (0x1) @@ -60,7 +60,6 @@ void hw_watchdog_reset(void) void hw_watchdog_init(void) { - u8 val; struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR; dmb(); @@ -68,15 +67,19 @@ void hw_watchdog_init(void) __raw_writel(UNLOCK_WORD1, &wdog->cnt); dmb(); - val = readb(&wdog->cs2); - val |= WDGCS2_FLG; - writeb(val, &wdog->cs2); + /* Wait WDOG Unlock */ + while (!(readl(&wdog->cs) & WDGCS_ULK)) + ; hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); writel(0, &wdog->win); - writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ - writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */ + /* setting 1-kHz clock source, enable counter running, and clear interrupt */ + writel((WDGCS_WDGE | WDGCS_WDGUPDATE |(WDG_LPO_CLK << 8) | WDGCS_FLG), &wdog->cs); + + /* Wait WDOG reconfiguration */ + while (!(readl(&wdog->cs) & WDGCS_RCS)) + ; hw_watchdog_reset(); } @@ -90,11 +93,19 @@ void reset_cpu(void) __raw_writel(UNLOCK_WORD1, &wdog->cnt); dmb(); + /* Wait WDOG Unlock */ + while (!(readl(&wdog->cs) & WDGCS_ULK)) + ; + hw_watchdog_set_timeout(5); /* 5ms timeout */ writel(0, &wdog->win); - writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */ - writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */ + /* enable counter running */ + writel((WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs); + + /* Wait WDOG reconfiguration */ + while (!(readl(&wdog->cs) & WDGCS_RCS)) + ; hw_watchdog_reset();