From 30d083d22611c5d54163f668cb3f412ac318ec6c Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 8 Apr 2021 10:25:28 +0200 Subject: arm64: dts: meson: odroidc2: readd PHY reset properties The sync of the device tree and dt-bindings from Linux v5.6-rc2 11a48a5a18c6 ("Linux 5.6-rc2") causes Ethernet to break on some ODROID-C2. The PHY seems to need proper reset timing to be functional in U-Boot and Linux afterwards. Readd the old PHY reset bindings for dwmac until we support the new bindings in the PHY node. Fixes: dd5f2351e99a ("arm64: dts: meson: sync dt and bindings from v5.6-rc2") Signed-off-by: Stefan Agner Signed-off-by: Neil Armstrong --- arch/arm/dts/meson-gxbb-odroidc2-u-boot.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/dts/meson-gxbb-odroidc2-u-boot.dtsi b/arch/arm/dts/meson-gxbb-odroidc2-u-boot.dtsi index 90087b0..5a2be81 100644 --- a/arch/arm/dts/meson-gxbb-odroidc2-u-boot.dtsi +++ b/arch/arm/dts/meson-gxbb-odroidc2-u-boot.dtsi @@ -29,6 +29,12 @@ }; }; +ðmac { + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; +}; + &usb0 { status = "disabled"; }; -- cgit v1.1 From 2696a41ef114d73237045c5ce23c3f64d44545cf Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 25 Feb 2021 18:46:12 +0100 Subject: clk: meson-g12a: add PCIe gates Add missing gates used for PCIe. Signed-off-by: Neil Armstrong --- drivers/clk/meson/g12a.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 5058db1..e4fed8d 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -120,7 +120,9 @@ static struct meson_gate gates[NUM_CLKS] = { MESON_GATE(CLKID_SD_EMMC_C, HHI_GCLK_MPEG0, 26), MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3), MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16), + MESON_GATE(CLKID_PCIE_COMB, HHI_GCLK_MPEG1, 24), MESON_GATE(CLKID_USB, HHI_GCLK_MPEG1, 25), + MESON_GATE(CLKID_PCIE_PHY, HHI_GCLK_MPEG1, 27), MESON_GATE(CLKID_HTX_PCLK, HHI_GCLK_MPEG2, 4), MESON_GATE(CLKID_USB1_DDR_BRIDGE, HHI_GCLK_MPEG2, 8), MESON_GATE(CLKID_VPU_INTR, HHI_GCLK_MPEG2, 25), -- cgit v1.1 From 628adbd70eaf316e2433a60afc3776ba55f2b1ec Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 25 Feb 2021 17:53:23 +0100 Subject: phy: meson-g12a-usb3-pcie: add support for PCIe ops Add the PCIe part of the G12A USB3 PCIe Combo PHY driver. Signed-off-by: Neil Armstrong --- drivers/phy/meson-g12a-usb3-pcie.c | 81 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/drivers/phy/meson-g12a-usb3-pcie.c b/drivers/phy/meson-g12a-usb3-pcie.c index 0433d93..8f72b5a 100644 --- a/drivers/phy/meson-g12a-usb3-pcie.c +++ b/drivers/phy/meson-g12a-usb3-pcie.c @@ -23,6 +23,9 @@ #include #include +#define PHY_TYPE_PCIE 2 +#define PHY_TYPE_USB3 4 + #define PHY_R0 0x00 #define PHY_R0_PCIE_POWER_STATE GENMASK(4, 0) #define PHY_R0_PCIE_USB3_SWITCH GENMASK(6, 5) @@ -55,6 +58,8 @@ #define PHY_R5_PHY_CR_ACK BIT(16) #define PHY_R5_PHY_BS_OUT BIT(17) +#define PCIE_RESET_DELAY 500 + struct phy_g12a_usb3_pcie_priv { struct regmap *regmap; #if CONFIG_IS_ENABLED(CLK) @@ -202,8 +207,6 @@ static int phy_meson_g12a_usb3_init(struct phy *phy) unsigned int data; int ret; - /* TOFIX Handle PCIE mode */ - ret = reset_assert_bulk(&priv->resets); udelay(1); ret |= reset_deassert_bulk(&priv->resets); @@ -296,9 +299,79 @@ static int phy_meson_g12a_usb3_exit(struct phy *phy) return reset_assert_bulk(&priv->resets); } +static int phy_meson_g12a_usb3_pcie_init(struct phy *phy) +{ + if (phy->id == PHY_TYPE_USB3) + return phy_meson_g12a_usb3_init(phy); + + return 0; +} + +static int phy_meson_g12a_usb3_pcie_exit(struct phy *phy) +{ + if (phy->id == PHY_TYPE_USB3) + return phy_meson_g12a_usb3_exit(phy); + + return 0; +} + +static int phy_meson_g12a_usb3_pcie_power_on(struct phy *phy) +{ + struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev); + + if (phy->id == PHY_TYPE_USB3) + return 0; + + regmap_update_bits(priv->regmap, PHY_R0, + PHY_R0_PCIE_POWER_STATE, + FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c)); + + return 0; +} + +static int phy_meson_g12a_usb3_pcie_power_off(struct phy *phy) +{ + struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev); + + if (phy->id == PHY_TYPE_USB3) + return 0; + + regmap_update_bits(priv->regmap, PHY_R0, + PHY_R0_PCIE_POWER_STATE, + FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1d)); + + return 0; +} + +static int phy_meson_g12a_usb3_pcie_reset(struct phy *phy) +{ + struct phy_g12a_usb3_pcie_priv *priv = dev_get_priv(phy->dev); + int ret; + + if (phy->id == PHY_TYPE_USB3) + return 0; + + ret = reset_assert_bulk(&priv->resets); + if (ret) + return ret; + + udelay(PCIE_RESET_DELAY); + + ret = reset_deassert_bulk(&priv->resets); + if (ret) + return ret; + + udelay(PCIE_RESET_DELAY); + + return 0; +} + struct phy_ops meson_g12a_usb3_pcie_phy_ops = { - .init = phy_meson_g12a_usb3_init, - .exit = phy_meson_g12a_usb3_exit, + .init = phy_meson_g12a_usb3_pcie_init, + .exit = phy_meson_g12a_usb3_pcie_exit, + .power_on = phy_meson_g12a_usb3_pcie_power_on, + .power_off = phy_meson_g12a_usb3_pcie_power_off, + .reset = phy_meson_g12a_usb3_pcie_reset, }; int meson_g12a_usb3_pcie_phy_probe(struct udevice *dev) -- cgit v1.1 From c8dd2ad696677107dee00ee4a87ed8fe273c6831 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 25 Feb 2021 18:47:05 +0100 Subject: arm: dts: meson-khadas-vim3: enable PCIe in U-boot Enable PCIe by default in u-boot, this should eventually be made dynamic in the runtime board config depending on the MCU configuration. Signed-off-by: Neil Armstrong --- arch/arm/dts/meson-khadas-vim3-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi b/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi index 81fd5be..24dbf8c 100644 --- a/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi +++ b/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi @@ -10,6 +10,10 @@ }; }; +&pcie { + status = "okay"; +}; + &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_4b_pins>, <&emmc_ds_pins>; -- cgit v1.1 From 8f4f65ed6a82b7020f953c17b33c973817e9eabe Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 26 Feb 2021 14:47:06 +0100 Subject: configs: khadas-vim3: enable PCIe and NVMe Now we have PCIe, let's also enable NVMe to access an eventual NVMe SSDs connected on the M.2 slot. Signed-off-by: Neil Armstrong --- configs/khadas-vim3_defconfig | 5 +++++ configs/khadas-vim3l_defconfig | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig index cd0327c..bb41670 100644 --- a/configs/khadas-vim3_defconfig +++ b/configs/khadas-vim3_defconfig @@ -88,3 +88,8 @@ CONFIG_BMP_16BPP=y CONFIG_BMP_24BPP=y CONFIG_BMP_32BPP=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_PCI=y +CONFIG_CMD_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_DW_MESON=y +CONFIG_NVME=y diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig index ef85f00..59541e7 100644 --- a/configs/khadas-vim3l_defconfig +++ b/configs/khadas-vim3l_defconfig @@ -88,3 +88,8 @@ CONFIG_BMP_16BPP=y CONFIG_BMP_24BPP=y CONFIG_BMP_32BPP=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_PCI=y +CONFIG_CMD_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_DW_MESON=y +CONFIG_NVME=y -- cgit v1.1 From 2dbe777753927176580dd4121b826241283009cb Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 26 Feb 2021 15:17:36 +0100 Subject: configs: meson64: add NVME boot target Let's add a boot target for NVMe so we can do a full boot over NVMe. Signed-off-by: Neil Armstrong --- include/configs/meson64.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/configs/meson64.h b/include/configs/meson64.h index 7e97f89..17ebccd 100644 --- a/include/configs/meson64.h +++ b/include/configs/meson64.h @@ -58,6 +58,12 @@ #define BOOT_TARGET_DEVICES_USB(func) #endif +#ifdef CONFIG_CMD_NVME + #define BOOT_TARGET_NVME(func) func(NVME, nvme, 0) +#else + #define BOOT_TARGET_NVME(func) +#endif + #ifndef BOOT_TARGET_DEVICES #define BOOT_TARGET_DEVICES(func) \ func(ROMUSB, romusb, na) \ @@ -65,6 +71,7 @@ func(MMC, mmc, 1) \ func(MMC, mmc, 2) \ BOOT_TARGET_DEVICES_USB(func) \ + BOOT_TARGET_NVME(func) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na) #endif -- cgit v1.1 From 612729b178d25b34199e169e8e24689d4fd4a820 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 16 Apr 2021 14:22:31 +0200 Subject: boards: amlogic: update documentation for PCIe support Signed-off-by: Neil Armstrong --- doc/board/amlogic/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/board/amlogic/index.rst b/doc/board/amlogic/index.rst index 275c366..8da7afd 100644 --- a/doc/board/amlogic/index.rst +++ b/doc/board/amlogic/index.rst @@ -70,6 +70,8 @@ This matrix concerns the actual source code version. +-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ | SoC (version) information | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | **Yes** | +-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ +| PCIe (+NVMe) | *N/A* | *N/A* | *N/A* | **Yes** | **Yes** | **Yes** | **Yes** | ++-------------------------------+-----------+-----------------+--------------+------------+------------+-------------+--------------+ Board Documentation ------------------- -- cgit v1.1 From 6f6876a0c0304acc117d075344275d716f8a935a Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Fri, 5 Mar 2021 15:02:35 +0800 Subject: arm64: gic-v3-its: Clear the Pending table before enabling LPIs The GICv3 RM requires "The first 1KB of memory for the LPI Pending tables must contain only zeros on initial allocation, and this must be visible to the Redistributors, or else the effect is UNPREDICTABLE". And as the following statement, we here clear the whole Pending tables instead of the first 1KB. "An LPI Pending table that contains only zeros, including in the first 1KB, indicates that there are no pending LPIs. The first 1KB of the LPI Pending table is IMPLEMENTATION DEFINED. However, if the first 1KB of the LPI Pending table and the rest of the table contain only zeros, this must indicate that there are no pending LPIs." And there isn't any pending LPI under U-Boot, so it's unnecessary to load the contents of the Pending table during the enablement, then set the GICR_PENDBASER.PTZ flag. Signed-off-by: Hou Zhiqiang Tested-by: Vladimir Oltean # NXP LS1028A Reviewed-by: Wasim Khan Reviewed-by: Priyanka Jain --- arch/arm/lib/gic-v3-its.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c index f5a921b..2d3fdb6 100644 --- a/arch/arm/lib/gic-v3-its.c +++ b/arch/arm/lib/gic-v3-its.c @@ -3,6 +3,7 @@ * Copyright 2019 Broadcom. */ #include +#include #include #include #include @@ -108,6 +109,8 @@ int gic_lpi_tables_init(void) int i; u64 redist_lpi_base; u64 pend_base; + ulong pend_tab_total_sz; + void *pend_tab_va; if (gic_v3_its_get_gic_addr(&priv)) return -EINVAL; @@ -161,6 +164,12 @@ int gic_lpi_tables_init(void) } redist_lpi_base = priv.lpi_base + LPI_PROPBASE_SZ; + pend_tab_total_sz = priv.num_redist * LPI_PENDBASE_SZ; + pend_tab_va = map_physmem(redist_lpi_base, pend_tab_total_sz, + MAP_NOCACHE); + memset(pend_tab_va, 0, pend_tab_total_sz); + flush_cache((ulong)pend_tab_va, pend_tab_total_sz); + unmap_physmem(pend_tab_va, MAP_NOCACHE); pend_base = priv.gicr_base + GICR_PENDBASER; for (i = 0; i < priv.num_redist; i++) { @@ -168,7 +177,8 @@ int gic_lpi_tables_init(void) val = ((redist_lpi_base + (i * LPI_PENDBASE_SZ)) | GICR_PENDBASER_INNERSHAREABLE | - GICR_PENDBASER_RAWAWB); + GICR_PENDBASER_RAWAWB | + GICR_PENDBASER_PTZ); writeq(val, (uintptr_t)(pend_base + offset)); tmp = readq((uintptr_t)(pend_base + offset)); -- cgit v1.1 From 182c5f1efbec12419ef458db5565101647ff5911 Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 8 Mar 2021 16:48:13 +0100 Subject: misc: make CONFIG_IRQ selectable for all platforms UCLASS_IRQ driver is not Intel specific. Make CONFIG_IRQ selectable for all platforms. Signed-off-by: Wasim Khan Tested-by: Vladimir Oltean Reviewed-by: Simon Glass --- drivers/misc/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c650471..997b713 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -211,10 +211,9 @@ config FSL_SEC_MON like software violations or hardware security violations. config IRQ - bool "Intel Interrupt controller" - depends on X86 || SANDBOX + bool "Interrupt controller" help - This enables support for Intel interrupt controllers, including ITSS. + This enables support for interrupt controllers, including ITSS. Some devices have extra features, such as Apollo Lake. The device has its own uclass since there are several operations involved. -- cgit v1.1 From 504f8648f036fe2ddf8a65a93d0d27871e32c71d Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 8 Mar 2021 16:48:14 +0100 Subject: arch: arm: update Kconfig to select IRQ when GIC_V3_ITS is enabled GIC_V3_ITS uses UCLASS_IRQ driver. Update Kconfig to select IRQ when GIC_V3_ITS is enabled. Signed-off-by: Wasim Khan Reviewed-by: Hou Zhiqiang Reviewed-by: Simon Glass Tested-by: Vladimir Oltean --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b39b043..15b8454 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -67,6 +67,7 @@ config GIC_V3_ITS bool "ARM GICV3 ITS" select REGMAP select SYSCON + select IRQ help ARM GICV3 Interrupt translation service (ITS). Basic support for programming locality specific peripheral -- cgit v1.1 From 543d091edba851ea15bc67ac34d9d14d70a58216 Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 8 Mar 2021 16:48:15 +0100 Subject: arch: Kconfig: enable IRQ using select for x86 architecture use 'select' to enable IRQ as it does not have architecture specific dependency. Signed-off-by: Wasim Khan Reviewed-by: Hou Zhiqiang Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- arch/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index dd1ff9d..1cbbed2 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -185,6 +185,7 @@ config X86 select TIMER select USE_PRIVATE_LIBGCC select X86_TSC_TIMER + select IRQ imply HAS_ROM if X86_RESET_VECTOR imply BLK imply CMD_DM @@ -215,7 +216,6 @@ config X86 imply USB_HOST_ETHER imply PCH imply RTC_MC146818 - imply IRQ imply ACPIGEN if !QEMU imply SYSINFO if GENERATE_SMBIOS_TABLE imply SYSINFO_SMBIOS if GENERATE_SMBIOS_TABLE -- cgit v1.1 From 57c675d699d524985f625bc0d4e72a55a97ebe8e Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Mon, 8 Mar 2021 16:48:16 +0100 Subject: sandbox: enable IRQ using select for sandbox architecture Enable IRQ using select for sandbox architecture. Signed-off-by: Wasim Khan Reviewed-by: Simon Glass Reviewed-by: Priyanka Jain --- arch/Kconfig | 1 + configs/sandbox64_defconfig | 1 - configs/sandbox_defconfig | 1 - configs/sandbox_flattree_defconfig | 1 - configs/sandbox_spl_defconfig | 1 - 5 files changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 1cbbed2..e61a752 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -120,6 +120,7 @@ config SANDBOX select SPI select SUPPORT_OF_CONTROL select SYSRESET_CMD_POWEROFF + select IRQ imply BITREVERSE select BLOBLIST imply CMD_DM diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 4648808..8a7e519 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -137,7 +137,6 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y -CONFIG_IRQ=y CONFIG_P2SB=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 6038dcb..12af9be 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -166,7 +166,6 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y -CONFIG_IRQ=y CONFIG_P2SB=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 689b3a9..97ac46d 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -115,7 +115,6 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y -CONFIG_IRQ=y CONFIG_P2SB=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 7f1a5ef..0fac3ad 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -139,7 +139,6 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y -CONFIG_IRQ=y CONFIG_P2SB=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y -- cgit v1.1 From 0a527fda7821c133ff34132b50e29e2b707db3f0 Mon Sep 17 00:00:00 2001 From: Reinoud Zandijk Date: Wed, 24 Feb 2021 17:44:42 +0100 Subject: Fix IDE commands issued, fix endian issues, fix non MMIO Fixes IDE issues found on the Malta board under Qemu: 1) DMA implied commands were sent to the controller in stead of the PIO variants. The rest of the code is DMA free and written for PIO operation. 2) direct pointer access was used to read and write the registers instead of the inb/inw/outb/outw functions/macros. Registers don't have to be memory mapped and ATA_CURR_BASE() does not have to return an offset from address zero. 3) Endian isues in ide_ident() and reading/writing data in general. Names were corrupted and sizes misreported. Tested malta_defconfig and maltael_defconfig to work again in Qemu. Signed-off-by: Reinoud Zandijk Tested-by: Heinrich Schuchardt --- drivers/block/ide.c | 152 +++++++++++++++------------------------------------- include/ata.h | 2 +- 2 files changed, 44 insertions(+), 110 deletions(-) diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 43a0776..862a85b 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -130,56 +130,38 @@ OUT: * ATAPI Support */ -#if defined(CONFIG_IDE_SWAP_IO) /* since ATAPI may use commands with not 4 bytes alligned length * we have our own transfer functions, 2 bytes alligned */ __weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) { + uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG); ushort *dbuf; - volatile ushort *pbuf; - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); dbuf = (ushort *)sect_buf; - debug("in output data shorts base for read is %lx\n", - (unsigned long) pbuf); + debug("in output data shorts base for read is %p\n", (void *)paddr); while (shorts--) { EIEIO; - *pbuf = *dbuf++; + outw(cpu_to_le16(*dbuf++), paddr); } } __weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) { + uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG); ushort *dbuf; - volatile ushort *pbuf; - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); dbuf = (ushort *)sect_buf; - debug("in input data shorts base for read is %lx\n", - (unsigned long) pbuf); + debug("in input data shorts base for read is %p\n", (void *)paddr); while (shorts--) { EIEIO; - *dbuf++ = *pbuf; + *dbuf++ = le16_to_cpu(inw(paddr)); } } -#else /* ! CONFIG_IDE_SWAP_IO */ -__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) -{ - outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); -} - -__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) -{ - insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); -} - -#endif /* CONFIG_IDE_SWAP_IO */ - /* * Wait until (Status & mask) == res, or timeout (in ms) * Return last status @@ -636,19 +618,6 @@ static void ide_ident(struct blk_desc *dev_desc) sizeof(dev_desc->vendor)); ident_cpy((unsigned char *)dev_desc->product, iop.serial_no, sizeof(dev_desc->product)); -#ifdef __LITTLE_ENDIAN - /* - * firmware revision, model, and serial number have Big Endian Byte - * order in Word. Convert all three to little endian. - * - * See CF+ and CompactFlash Specification Revision 2.0: - * 6.2.1.6: Identify Drive, Table 39 for more details - */ - - strswab(dev_desc->revision); - strswab(dev_desc->vendor); - strswab(dev_desc->product); -#endif /* __LITTLE_ENDIAN */ if ((iop.config & 0x0080) == 0x0080) dev_desc->removable = 1; @@ -662,26 +631,22 @@ static void ide_ident(struct blk_desc *dev_desc) } #endif /* CONFIG_ATAPI */ -#ifdef __BIG_ENDIAN - /* swap shorts */ - dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16); -#else /* ! __BIG_ENDIAN */ - /* - * do not swap shorts on little endian - * - * See CF+ and CompactFlash Specification Revision 2.0: - * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details. - */ - dev_desc->lba = iop.lba_capacity; -#endif /* __BIG_ENDIAN */ + iop.lba_capacity[0] = be16_to_cpu(iop.lba_capacity[0]); + iop.lba_capacity[1] = be16_to_cpu(iop.lba_capacity[1]); + dev_desc->lba = + ((unsigned long)iop.lba_capacity[0]) | + ((unsigned long)iop.lba_capacity[1] << 16); #ifdef CONFIG_LBA48 if (iop.command_set_2 & 0x0400) { /* LBA 48 support */ dev_desc->lba48 = 1; - dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] | - ((unsigned long long) iop.lba48_capacity[1] << 16) | - ((unsigned long long) iop.lba48_capacity[2] << 32) | - ((unsigned long long) iop.lba48_capacity[3] << 48); + for (int i = 0; i < 4; i++) + iop.lba48_capacity[i] = be16_to_cpu(iop.lba48_capacity[i]); + dev_desc->lba = + ((unsigned long long)iop.lba48_capacity[0] | + ((unsigned long long)iop.lba48_capacity[1] << 16) | + ((unsigned long long)iop.lba48_capacity[2] << 32) | + ((unsigned long long)iop.lba48_capacity[3] << 48)); } else { dev_desc->lba48 = 0; } @@ -846,90 +811,59 @@ void ide_init(void) #endif } -/* We only need to swap data if we are running on a big endian cpu. */ -#if defined(__LITTLE_ENDIAN) __weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) { - ide_input_data(dev, sect_buf, words); -} -#else -__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) -{ - volatile ushort *pbuf = - (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); + uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG); ushort *dbuf = (ushort *)sect_buf; - debug("in input swap data base for read is %lx\n", - (unsigned long) pbuf); + debug("in input swap data base for read is %p\n", (void *)paddr); while (words--) { -#ifdef __MIPS__ - *dbuf++ = swab16p((u16 *)pbuf); - *dbuf++ = swab16p((u16 *)pbuf); -#else - *dbuf++ = ld_le16(pbuf); - *dbuf++ = ld_le16(pbuf); -#endif /* !MIPS */ + EIEIO; + *dbuf++ = be16_to_cpu(inw(paddr)); + EIEIO; + *dbuf++ = be16_to_cpu(inw(paddr)); } } -#endif /* __LITTLE_ENDIAN */ - -#if defined(CONFIG_IDE_SWAP_IO) __weak void ide_output_data(int dev, const ulong *sect_buf, int words) { +#if defined(CONFIG_IDE_AHB) + ide_write_data(dev, sect_buf, words); +#else + uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG); ushort *dbuf; - volatile ushort *pbuf; - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { EIEIO; - *pbuf = *dbuf++; + outw(cpu_to_le16(*dbuf++), paddr); EIEIO; - *pbuf = *dbuf++; + outw(cpu_to_le16(*dbuf++), paddr); } +#endif /* CONFIG_IDE_AHB */ } -#else /* ! CONFIG_IDE_SWAP_IO */ -__weak void ide_output_data(int dev, const ulong *sect_buf, int words) -{ -#if defined(CONFIG_IDE_AHB) - ide_write_data(dev, sect_buf, words); -#else - outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); -#endif -} -#endif /* CONFIG_IDE_SWAP_IO */ -#if defined(CONFIG_IDE_SWAP_IO) __weak void ide_input_data(int dev, ulong *sect_buf, int words) { +#if defined(CONFIG_IDE_AHB) + ide_read_data(dev, sect_buf, words); +#else + uintptr_t paddr = (ATA_CURR_BASE(dev) + ATA_DATA_REG); ushort *dbuf; - volatile ushort *pbuf; - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); dbuf = (ushort *)sect_buf; - debug("in input data base for read is %lx\n", (unsigned long) pbuf); + debug("in input data base for read is %p\n", (void *)paddr); while (words--) { EIEIO; - *dbuf++ = *pbuf; + *dbuf++ = le16_to_cpu(inw(paddr)); EIEIO; - *dbuf++ = *pbuf; + *dbuf++ = le16_to_cpu(inw(paddr)); } +#endif /* CONFIG_IDE_AHB */ } -#else /* ! CONFIG_IDE_SWAP_IO */ -__weak void ide_input_data(int dev, ulong *sect_buf, int words) -{ -#if defined(CONFIG_IDE_AHB) - ide_read_data(dev, sect_buf, words); -#else - insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); -#endif -} - -#endif /* CONFIG_IDE_SWAP_IO */ #ifdef CONFIG_BLK ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, @@ -1019,14 +953,14 @@ ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, if (lba48) { ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT); + ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_READ_EXT); } else #endif { ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); - ide_outb(device, ATA_COMMAND, ATA_CMD_READ); + ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_READ); } udelay(50); @@ -1116,14 +1050,14 @@ ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, if (lba48) { ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT); + ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_WRITE_EXT); } else #endif { ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); - ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE); + ide_outb(device, ATA_COMMAND, ATA_CMD_PIO_WRITE); } udelay(50); diff --git a/include/ata.h b/include/ata.h index 3d870c9..32ad5f6 100644 --- a/include/ata.h +++ b/include/ata.h @@ -134,7 +134,7 @@ typedef struct hd_driveid { unsigned short cur_capacity1; /* (2 words, misaligned int) */ unsigned char multsect; /* current multiple sector count */ unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ - unsigned int lba_capacity; /* total number of sectors */ + unsigned short lba_capacity[2];/* two words containing total number of sectors */ unsigned short dma_1word; /* single-word dma info */ unsigned short dma_mword; /* multiple-word dma info */ unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ -- cgit v1.1 From 227c53de874b5725f6752e70d40a29f36ca0d2fc Mon Sep 17 00:00:00 2001 From: Karl Beldan Date: Wed, 17 Mar 2021 22:31:58 +0000 Subject: lz4: Fix unaligned accesses Signed-off-by: Karl Beldan --- lib/lz4_wrapper.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/lz4_wrapper.c b/lib/lz4_wrapper.c index e0f7d36..cdbcd05 100644 --- a/lib/lz4_wrapper.c +++ b/lib/lz4_wrapper.c @@ -11,9 +11,18 @@ #include #include -static u16 LZ4_readLE16(const void *src) { return le16_to_cpu(*(u16 *)src); } -static void LZ4_copy4(void *dst, const void *src) { *(u32 *)dst = *(u32 *)src; } -static void LZ4_copy8(void *dst, const void *src) { *(u64 *)dst = *(u64 *)src; } +static u16 LZ4_readLE16(const void *src) +{ + return get_unaligned_le16(src); +} +static void LZ4_copy4(void *dst, const void *src) +{ + put_unaligned(get_unaligned((const u32 *)src), (u32 *)dst); +} +static void LZ4_copy8(void *dst, const void *src) +{ + put_unaligned(get_unaligned((const u64 *)src), (u64 *)dst); +} typedef uint8_t BYTE; typedef uint16_t U16; -- cgit v1.1 From ab7f8d18502eda35cef5539b1cf2dbbce9d48c30 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 25 Mar 2021 17:07:32 -0700 Subject: arm: octeontx: move CONFIG_SUPPORT_RAW_INITRD to configs Move CONFIG_SUPPORT_RAW_INITRD out of the octeontx_common header and into the defconfig files. Signed-off-by: Tim Harvey Reviewed-by: Stefan Roese --- configs/octeontx_81xx_defconfig | 1 + configs/octeontx_83xx_defconfig | 1 + include/configs/octeontx_common.h | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/octeontx_81xx_defconfig b/configs/octeontx_81xx_defconfig index f0585a7..9881c10 100644 --- a/configs/octeontx_81xx_defconfig +++ b/configs/octeontx_81xx_defconfig @@ -17,6 +17,7 @@ CONFIG_DEBUG_UART=y CONFIG_AHCI=y CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y +CONFIG_SUPPORT_RAW_INITRD=y CONFIG_OF_BOARD_SETUP=y CONFIG_BOOTDELAY=5 CONFIG_USE_BOOTARGS=y diff --git a/configs/octeontx_83xx_defconfig b/configs/octeontx_83xx_defconfig index 86b4bc5..1fc7f0c 100644 --- a/configs/octeontx_83xx_defconfig +++ b/configs/octeontx_83xx_defconfig @@ -15,6 +15,7 @@ CONFIG_DEBUG_UART=y CONFIG_AHCI=y CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y +CONFIG_SUPPORT_RAW_INITRD=y CONFIG_OF_BOARD_SETUP=y CONFIG_BOOTDELAY=5 CONFIG_USE_BOOTARGS=y diff --git a/include/configs/octeontx_common.h b/include/configs/octeontx_common.h index 810b2bd..55d329f 100644 --- a/include/configs/octeontx_common.h +++ b/include/configs/octeontx_common.h @@ -8,8 +8,6 @@ #ifndef __OCTEONTX_COMMON_H__ #define __OCTEONTX_COMMON_H__ -#define CONFIG_SUPPORT_RAW_INITRD - /** Maximum size of image supported for bootm (and bootable FIT images) */ #define CONFIG_SYS_BOOTM_LEN (256 << 20) -- cgit v1.1 From 8bb5a66e5b100b7de1d787a471c117c14743537b Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 25 Mar 2021 17:07:33 -0700 Subject: arm: octeontx: support generic distro config Support Generic Distro Default config Signed-off-by: Tim Harvey Reviewed-by: Stefan Roese --- include/configs/octeontx_common.h | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/include/configs/octeontx_common.h b/include/configs/octeontx_common.h index 55d329f..434e544 100644 --- a/include/configs/octeontx_common.h +++ b/include/configs/octeontx_common.h @@ -8,6 +8,32 @@ #ifndef __OCTEONTX_COMMON_H__ #define __OCTEONTX_COMMON_H__ +#ifdef CONFIG_DISTRO_DEFAULTS +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(MMC, mmc, 1) \ + func(USB, usb, 0) \ + func(SCSI, scsi, 0) + +#include +/* Extra environment variables */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "autoload=0\0" \ + "loadaddr=0x20080000\0" \ + "kernel_addr_r=0x02000000\0" \ + "ramdisk_addr_r=0x03000000\0" \ + "scriptaddr=0x04000000\0" \ + BOOTENV + +#else + +/** Extra environment settings */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadaddr=20080000\0" \ + "autoload=0\0" + +#endif /* ifdef CONFIG_DISTRO_DEFAULTS*/ + /** Maximum size of image supported for bootm (and bootable FIT images) */ #define CONFIG_SYS_BOOTM_LEN (256 << 20) @@ -50,11 +76,6 @@ # define CONFIG_SF_DEFAULT_CS 0 #endif -/** Extra environment settings */ -#define CONFIG_EXTRA_ENV_SETTINGS \ - "loadaddr=20080000\0" \ - "autoload=0\0" - /** Environment defines */ #if defined(CONFIG_ENV_IS_IN_MMC) #define CONFIG_SYS_MMC_ENV_DEV 0 -- cgit v1.1 From 9889a8e562461837312879d82bcbfe80854de67a Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 25 Mar 2021 17:07:34 -0700 Subject: arm: octeontx: enable WDT_SBSA The OcteonTX uses ARM's SBSA Watchdog device Signed-off-by: Tim Harvey Reviewed-by: Stefan Roese --- configs/octeontx_81xx_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/octeontx_81xx_defconfig b/configs/octeontx_81xx_defconfig index 9881c10..bcf03db 100644 --- a/configs/octeontx_81xx_defconfig +++ b/configs/octeontx_81xx_defconfig @@ -132,4 +132,5 @@ CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_ASIX88179=y CONFIG_USB_ETHER_RTL8152=y CONFIG_WDT=y +CONFIG_WDT_SBSA=y CONFIG_ERRNO_STR=y -- cgit v1.1 From 8c64347b7e45f96d82f8c6782c2fcd309f4e45cf Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 25 Mar 2021 17:07:35 -0700 Subject: drivers: net: octeontx: fix QSGMII Revert a change that occured between the Marvell SDK-10.1.1.0 and SDK-10.3.1.1 which broke QSMII phy support. Signed-off-by: Tim Harvey --- drivers/net/octeontx/bgx.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/octeontx/bgx.c b/drivers/net/octeontx/bgx.c index 2ea54be..a5c0c9f 100644 --- a/drivers/net/octeontx/bgx.c +++ b/drivers/net/octeontx/bgx.c @@ -36,7 +36,6 @@ struct lmac { int dmac; u8 mac[6]; bool link_up; - bool init_pend; int lmacid; /* ID within BGX */ int phy_addr; /* ID on board */ struct udevice *dev; @@ -849,6 +848,7 @@ static int bgx_lmac_enable(struct bgx *bgx, int8_t lmacid) u64 cfg; lmac = &bgx->lmac[lmacid]; + lmac->bgx = bgx; debug("%s: lmac: %p, lmacid = %d\n", __func__, lmac, lmacid); @@ -895,16 +895,6 @@ int bgx_poll_for_link(int node, int bgx_idx, int lmacid) debug("%s: %d, lmac: %d/%d/%d %p\n", __FILE__, __LINE__, node, bgx_idx, lmacid, lmac); - if (lmac->init_pend) { - ret = bgx_lmac_enable(lmac->bgx, lmacid); - if (ret < 0) { - printf("BGX%d LMAC%d lmac_enable failed\n", bgx_idx, - lmacid); - return ret; - } - lmac->init_pend = 0; - mdelay(100); - } if (lmac->qlm_mode == QLM_MODE_SGMII || lmac->qlm_mode == QLM_MODE_RGMII || lmac->qlm_mode == QLM_MODE_QSGMII) { @@ -1461,6 +1451,7 @@ int octeontx_bgx_remove(struct udevice *dev) int octeontx_bgx_probe(struct udevice *dev) { + int err; struct bgx *bgx = dev_get_priv(dev); u8 lmac = 0; int qlm[4] = {-1, -1, -1, -1}; @@ -1540,8 +1531,11 @@ skip_qlm_config: struct lmac *tlmac = &bgx->lmac[lmac]; tlmac->dev = dev; - tlmac->init_pend = 1; - tlmac->bgx = bgx; + err = bgx_lmac_enable(bgx, lmac); + if (err) { + printf("BGX%d failed to enable lmac%d\n", + bgx->bgx_id, lmac); + } } return 0; -- cgit v1.1 From 98a8180dcaf55bd61758435d1fe3cfa27588dab8 Mon Sep 17 00:00:00 2001 From: Suneel Garapati Date: Thu, 25 Mar 2021 17:07:36 -0700 Subject: drivers: ata: ahci: update max id if it is more than available ports After check for maximum between max id and available ports, also check if available port count is less than max id and update. In the case of the CN8030 OcteonTX SoC max_id needs to be reduced to the number of ports found otherwise the following occurs on a scan: GW6404-B> scsi scan scanning bus for devices... Target spinup took 0 ms. AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode flags: 64bit ncq ilck stag pm led clo only pmp fbss pio slum part ccc apst Device 0: (0:0) Vendor: ATA Prod.: SanDisk SD8SFAT0 Rev: Z233 Type: Hard Disk Capacity: 61057.3 MB = 59.6 GB (125045424 x 512) "Synchronous Abort" handler, esr 0x96000006 elr: 000000000052f824 lr : 000000000052fa10 (reloc) elr: 000000007fee9824 lr : 000000007fee9a10 x0 : 0000000000000001 x1 : 0000000000000001 x2 : 000000007bea3528 x3 : 000000007bea3580 x4 : 0000000000000200 x5 : 0000000000000000 x6 : 0000000000000002 x7 : 000000007bea3540 x8 : 00000000fffffff8 x9 : 0000000000000008 x10: 00000000000186a0 x11: 000000000000000d x12: 0000000000000006 x13: 000000000001869f x14: 0000000000000007 x15: 00000000ffffffff x16: 000000007ff439a5 x17: 000000007ff5730c x18: 000000007bea9de0 x19: 000000007ff7a580 x20: 000000007bec79f8 x21: 0000000000000000 x22: 000000007bea3580 x23: 0000000000000000 x24: 0000000000000000 x25: 000000007bec7a00 x26: 00000000ffffffc0 x27: 000000007bec79d0 x28: 000000007beb51c0 x29: 000000007bea3480 Code: 91246800 940130c2 12800000 1400004f (b9402ae0) Resetting CPU ... Signed-off-by: Suneel Garapati Reviewed-by: Stefan Roese --- drivers/ata/ahci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2ef21ec..98b2882 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1190,6 +1190,9 @@ int ahci_probe_scsi(struct udevice *ahci_dev, ulong base) */ uc_plat->max_id = max_t(unsigned long, uc_priv->n_ports, uc_plat->max_id); + /* If port count is less than max_id, update max_id */ + if (uc_priv->n_ports < uc_plat->max_id) + uc_plat->max_id = uc_priv->n_ports; return 0; } -- cgit v1.1 From 935e0b0ecd2d2303fca12aa0c55d2af1783e61dc Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 25 Mar 2021 17:07:37 -0700 Subject: net: octeontx: smi: fix mii probe The fdt node offset is apparently not set properly when probed causing no MDIO busses to be found. Fix this by obtaining the offset. Signed-off-by: Tim Harvey Reviewed-by: Stefan Roese --- drivers/net/octeontx/smi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/octeontx/smi.c b/drivers/net/octeontx/smi.c index 91dcd05..27f4423 100644 --- a/drivers/net/octeontx/smi.c +++ b/drivers/net/octeontx/smi.c @@ -325,6 +325,8 @@ int octeontx_smi_probe(struct udevice *dev) return -1; } + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, + "cavium,thunder-8890-mdio-nexus"); fdt_for_each_subnode(subnode, gd->fdt_blob, node) { ret = fdt_node_check_compatible(gd->fdt_blob, subnode, "cavium,thunder-8890-mdio"); -- cgit v1.1 From ec611871f3eb366f7efd557167ec2284e5f5069b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 27 Mar 2021 11:43:54 +0100 Subject: cmd: CONFIG_CMD_MMC depends on CONFIG_MMC Trying to compile with CONFIG_CMD_MMC=y and CONFIG_MMC=n leads to errors: riscv64-linux-gnu-ld.bfd: cmd/built-in.o: in function `do_mmcops': cmd/mmc.c:984: undefined reference to `get_mmc_num' riscv64-linux-gnu-ld.bfd: cmd/built-in.o: in function `do_mmc_setdsr': cmd/mmc.c:873: undefined reference to `find_mmc_device' Add missing dependency. Signed-off-by: Heinrich Schuchardt Reviewed-by: Bin Meng Reviewed-by: Jaehoon Chung --- cmd/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/Kconfig b/cmd/Kconfig index f4cff0c..2b66285 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1067,6 +1067,7 @@ config CMD_MISC config CMD_MMC bool "mmc" + depends on MMC help MMC memory mapped support. -- cgit v1.1 From 6ab0286ae1bd37b95528b50513abe1b236e2f32c Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Sat, 27 Mar 2021 21:46:51 +0800 Subject: power: regulator: add driver for ANATOP regulator Anatop is an integrated regulator inside i.MX6 SoC. There are 3 digital regulators which controls PU, CORE (ARM), and SOC. And 3 analog regulators which controls 1P1, 2P5, 3P0 (USB). This patch adds the Anatop regulator driver. Signed-off-by: Ying-Chun Liu (PaulLiu) Reviewed-by: Sean Anderson Cc: Fabio Estevam Cc: Jaehoon Chung Cc: Peng Fan Reviewed-by: Jaehoon Chung --- drivers/power/regulator/Kconfig | 10 ++ drivers/power/regulator/Makefile | 1 + drivers/power/regulator/anatop_regulator.c | 278 +++++++++++++++++++++++++++++ 3 files changed, 289 insertions(+) create mode 100644 drivers/power/regulator/anatop_regulator.c diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 5d61802..17942e2 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -312,6 +312,16 @@ config DM_REGULATOR_STPMIC1 by the PMIC device. This driver is controlled by a device tree node which includes voltage limits. +config DM_REGULATOR_ANATOP + bool "Enable driver for ANATOP regulators" + depends on DM_REGULATOR + select REGMAP + select SYSCON + help + Enable support for the Freescale i.MX on-chip ANATOP LDO + regulators. It is recommended that this option be enabled on + i.MX6 platform. + config SPL_DM_REGULATOR_STPMIC1 bool "Enable driver for STPMIC1 regulators in SPL" depends on SPL_DM_REGULATOR && PMIC_STPMIC1 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index b2f5972..677134c 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -31,3 +31,4 @@ obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o obj-$(CONFIG_DM_REGULATOR_SCMI) += scmi_regulator.o +obj-$(CONFIG_$(SPL_)DM_REGULATOR_ANATOP) += anatop_regulator.o diff --git a/drivers/power/regulator/anatop_regulator.c b/drivers/power/regulator/anatop_regulator.c new file mode 100644 index 0000000..096a156 --- /dev/null +++ b/drivers/power/regulator/anatop_regulator.c @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2021 Linaro + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ +#define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ + +#define LDO_POWER_GATE 0x00 +#define LDO_FET_FULL_ON 0x1f + +#define BIT_WIDTH_MAX 32 + +#define ANATOP_REGULATOR_STEP 25000 +#define MIN_DROPOUT_UV 125000 + +struct anatop_regulator { + const char *name; + struct regmap *regmap; + struct udevice *supply; + u32 control_reg; + u32 vol_bit_shift; + u32 vol_bit_width; + u32 min_bit_val; + u32 min_voltage; + u32 max_voltage; + u32 delay_reg; + u32 delay_bit_shift; + u32 delay_bit_width; +}; + +static u32 anatop_get_bits(struct udevice *dev, u32 addr, int bit_shift, + int bit_width) +{ + const struct anatop_regulator *anatop_reg = dev_get_plat(dev); + int err; + u32 val, mask; + + if (bit_width == BIT_WIDTH_MAX) + mask = ~0; + else + mask = (1 << bit_width) - 1; + + err = regmap_read(anatop_reg->regmap, addr, &val); + if (err) { + dev_dbg(dev, "cannot read reg (%d)\n", err); + return err; + } + + val = (val >> bit_shift) & mask; + + return val; +} + +static int anatop_set_bits(struct udevice *dev, u32 addr, int bit_shift, + int bit_width, u32 data) +{ + const struct anatop_regulator *anatop_reg = dev_get_plat(dev); + int err; + u32 val, mask; + + if (bit_width == 32) + mask = ~0; + else + mask = (1 << bit_width) - 1; + + err = regmap_read(anatop_reg->regmap, addr, &val); + if (err) { + dev_dbg(dev, "cannot read reg (%d)\n", err); + return err; + } + val = val & ~(mask << bit_shift); + err = regmap_write(anatop_reg->regmap, + addr, (data << bit_shift) | val); + if (err) { + dev_dbg(dev, "cannot write reg (%d)\n", err); + return err; + } + + return 0; +} + +static int anatop_get_voltage(struct udevice *dev) +{ + const struct anatop_regulator *anatop_reg = dev_get_plat(dev); + u32 sel; + u32 val; + + if (!anatop_reg->control_reg) + return -ENOSYS; + + val = anatop_get_bits(dev, + anatop_reg->control_reg, + anatop_reg->vol_bit_shift, + anatop_reg->vol_bit_width); + + sel = val - anatop_reg->min_bit_val; + + return sel * ANATOP_REGULATOR_STEP + anatop_reg->min_voltage; +} + +static int anatop_set_voltage(struct udevice *dev, int uV) +{ + const struct anatop_regulator *anatop_reg = dev_get_plat(dev); + u32 val; + u32 sel; + int ret; + + dev_dbg(dev, "uv %d, min %d, max %d\n", uV, anatop_reg->min_voltage, + anatop_reg->max_voltage); + + if (uV < anatop_reg->min_voltage) + return -EINVAL; + + if (!anatop_reg->control_reg) + return -ENOSYS; + + sel = DIV_ROUND_UP(uV - anatop_reg->min_voltage, + ANATOP_REGULATOR_STEP); + if (sel * ANATOP_REGULATOR_STEP + anatop_reg->min_voltage > + anatop_reg->max_voltage) + return -EINVAL; + val = anatop_reg->min_bit_val + sel; + dev_dbg(dev, "calculated val %d\n", val); + + if (anatop_reg->supply) { + ret = regulator_set_value(anatop_reg->supply, + uV + MIN_DROPOUT_UV); + if (ret) + return ret; + } + + ret = anatop_set_bits(dev, + anatop_reg->control_reg, + anatop_reg->vol_bit_shift, + anatop_reg->vol_bit_width, + val); + + return ret; +} + +static const struct dm_regulator_ops anatop_regulator_ops = { + .set_value = anatop_set_voltage, + .get_value = anatop_get_voltage, +}; + +static int anatop_regulator_probe(struct udevice *dev) +{ + struct anatop_regulator *anatop_reg; + struct dm_regulator_uclass_plat *uc_pdata; + struct udevice *syscon; + int ret = 0; + u32 val; + + anatop_reg = dev_get_plat(dev); + uc_pdata = dev_get_uclass_plat(dev); + + anatop_reg->name = ofnode_read_string(dev_ofnode(dev), + "regulator-name"); + if (!anatop_reg->name) + return log_msg_ret("regulator-name", -EINVAL); + + ret = device_get_supply_regulator(dev, "vin-supply", + &anatop_reg->supply); + if (ret != -ENODEV) { + if (ret) + return log_msg_ret("get vin-supply", ret); + + ret = regulator_set_enable(anatop_reg->supply, true); + if (ret) + return ret; + } + + ret = dev_read_u32(dev, + "anatop-reg-offset", + &anatop_reg->control_reg); + if (ret) + return log_msg_ret("anatop-reg-offset", ret); + + ret = dev_read_u32(dev, + "anatop-vol-bit-width", + &anatop_reg->vol_bit_width); + if (ret) + return log_msg_ret("anatop-vol-bit-width", ret); + + ret = dev_read_u32(dev, + "anatop-vol-bit-shift", + &anatop_reg->vol_bit_shift); + if (ret) + return log_msg_ret("anatop-vol-bit-shift", ret); + + ret = dev_read_u32(dev, + "anatop-min-bit-val", + &anatop_reg->min_bit_val); + if (ret) + return log_msg_ret("anatop-min-bit-val", ret); + + ret = dev_read_u32(dev, + "anatop-min-voltage", + &anatop_reg->min_voltage); + if (ret) + return log_msg_ret("anatop-min-voltage", ret); + + ret = dev_read_u32(dev, + "anatop-max-voltage", + &anatop_reg->max_voltage); + if (ret) + return log_msg_ret("anatop-max-voltage", ret); + + /* read LDO ramp up setting, only for core reg */ + dev_read_u32(dev, "anatop-delay-reg-offset", + &anatop_reg->delay_reg); + dev_read_u32(dev, "anatop-delay-bit-width", + &anatop_reg->delay_bit_width); + dev_read_u32(dev, "anatop-delay-bit-shift", + &anatop_reg->delay_bit_shift); + + syscon = dev_get_parent(dev); + if (!syscon) { + dev_dbg(dev, "unable to find syscon device\n"); + return -ENOENT; + } + + anatop_reg->regmap = syscon_get_regmap(syscon); + if (IS_ERR(anatop_reg->regmap)) { + dev_dbg(dev, "unable to find regmap (%ld)\n", + PTR_ERR(anatop_reg->regmap)); + return -ENOENT; + } + + /* check whether need to care about LDO ramp up speed */ + if (anatop_reg->delay_bit_width) { + /* + * the delay for LDO ramp up time is + * based on the register setting, we need + * to calculate how many steps LDO need to + * ramp up, and how much delay needed. (us) + */ + val = anatop_get_bits(dev, + anatop_reg->delay_reg, + anatop_reg->delay_bit_shift, + anatop_reg->delay_bit_width); + uc_pdata->ramp_delay = (LDO_RAMP_UP_UNIT_IN_CYCLES << val) + / LDO_RAMP_UP_FREQ_IN_MHZ + 1; + } + + return 0; +} + +static const struct udevice_id of_anatop_regulator_match_tbl[] = { + { .compatible = "fsl,anatop-regulator", }, + { /* end */ } +}; + +U_BOOT_DRIVER(anatop_regulator) = { + .name = "anatop_regulator", + .id = UCLASS_REGULATOR, + .ops = &anatop_regulator_ops, + .of_match = of_anatop_regulator_match_tbl, + .plat_auto = sizeof(struct anatop_regulator), + .probe = anatop_regulator_probe, +}; -- cgit v1.1 From a606106402ff1781b123d4041a09d0af23a3078e Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Sat, 27 Mar 2021 21:46:52 +0800 Subject: doc: device-tree-bindings: regulator: anatop regulator Document the bindings for fsl,anatop-regulator Signed-off-by: Ying-Chun Liu (PaulLiu) Reviewed-by: Sean Anderson Cc: Fabio Estevam Cc: Jaehoon Chung Cc: Peng Fan Reviewed-by: Jaehoon Chung --- .../regulator/fsl,anatop-regulator.txt | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 doc/device-tree-bindings/regulator/fsl,anatop-regulator.txt diff --git a/doc/device-tree-bindings/regulator/fsl,anatop-regulator.txt b/doc/device-tree-bindings/regulator/fsl,anatop-regulator.txt new file mode 100644 index 0000000..2a60e49 --- /dev/null +++ b/doc/device-tree-bindings/regulator/fsl,anatop-regulator.txt @@ -0,0 +1,45 @@ +ANATOP REGULATOR + +Anatop is an integrated regulator inside i.MX6 SoC. + +Required properties: +- compatible: Must be "fsl,anatop-regulator". +- regulator-name: Name of the regulator +- anatop-reg-offset: u32 value representing the anatop MFD register offset. +- anatop-vol-bit-shift: u32 value representing the bit shift for the register. +- anatop-vol-bit-width: u32 value representing the number of bits used in the + register. +- anatop-min-bit-val: u32 value representing the minimum value of this + register. +- anatop-min-voltage: u32 value representing the minimum voltage of this + regulator. +- anatop-max-voltage: u32 value representing the maximum voltage of this + regulator. + +Optional properties: +- anatop-delay-reg-offset: u32 value representing the anatop MFD step time + register offset. +- anatop-delay-bit-shift: u32 value representing the bit shift for the step + time register. +- anatop-delay-bit-width: u32 value representing the number of bits used in + the step time register. +- anatop-enable-bit: u32 value representing regulator enable bit offset. +- vin-supply: input supply phandle. + +Example: + regulator-vddpu { + compatible = "fsl,anatop-regulator"; + regulator-name = "vddpu"; + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + anatop-reg-offset = <0x140>; + anatop-vol-bit-shift = <9>; + anatop-vol-bit-width = <5>; + anatop-delay-reg-offset = <0x170>; + anatop-delay-bit-shift = <24>; + anatop-delay-bit-width = <2>; + anatop-min-bit-val = <1>; + anatop-min-voltage = <725000>; + anatop-max-voltage = <1300000>; + }; -- cgit v1.1 From 84b2cd74f370dabb707e2611bf57714a66d08622 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 12 Apr 2021 01:04:50 +0100 Subject: arm: highbank: Limit FDT and initrd load addresses So far on Highbank/Midway machines U-Boot only ever uses 512MB of DRAM, even though the machines have typically 4GB and 8GB, respectively. That means that so far we didn't need an extra limit for placing the DTB and initrd, as the 512MB are lower than the kernel's limit ("lowmem", typically 768MB). With U-Boot now needing to learn about the actual memory size (to correctly populate the EFI memory map), it might relocate fdt and initrd to the end of DRAM, which is out of reach of the kernel. So add limiting values to the fdt_high and initrd_high environment variables, to prevent U-Boot from using too high addresses. Signed-off-by: Andre Przywara Reviewed-by: Tom Rini --- include/configs/highbank.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/highbank.h b/include/configs/highbank.h index bdbaa47..5e3cc3a 100644 --- a/include/configs/highbank.h +++ b/include/configs/highbank.h @@ -57,4 +57,8 @@ #define CONFIG_SYS_INIT_SP_ADDR 0x01000000 #define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0x20000000\0" \ + "initrd_high=0x20000000\0" + #endif -- cgit v1.1 From 109552d773e7aeb0f6417d8245fb0ecf01599ef3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 12 Apr 2021 01:04:51 +0100 Subject: arm: highbank: Enable OF_CONTROL All Calxeda machines are actually a poster book example of device tree usage: the DT is loaded from flash by the management processor into DRAM, the memory node is populated with the detected DRAM size and this DT is then handed over to the kernel. So it's a shame that U-Boot didn't participate in this chain, but fortunately this is easy to fix: Define CONFIG_OF_CONTROL and CONFIG_OF_BOARD, and provide a trivial function to tell U-Boot about the (fixed) location of the DTB in DRAM. Then enable DM_SERIAL, to let the PL011 driver pick up the UART platform data from the DT. Also define AHCI, to bring this driver into the driver model world as well. Signed-off-by: Andre Przywara --- arch/arm/Kconfig | 9 ++++++++- board/highbank/highbank.c | 10 ++++++++++ configs/highbank_defconfig | 1 + include/configs/highbank.h | 1 - 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15b8454..3586426 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -711,7 +711,14 @@ config ARCH_S5PC1XX config ARCH_HIGHBANK bool "Calxeda Highbank" select CPU_V7A - select PL011_SERIAL + select PL01X_SERIAL + select DM + select DM_SERIAL + select OF_CONTROL + select OF_BOARD + select CLK + select CLK_CCF + select AHCI config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c index 906bd9b..2e2300a 100644 --- a/board/highbank/highbank.c +++ b/board/highbank/highbank.c @@ -119,6 +119,16 @@ int ft_board_setup(void *fdt, struct bd_info *bd) } #endif +void *board_fdt_blob_setup(void) +{ + /* + * The ECME management processor loads the DTB from NOR flash + * into DRAM (at 4KB), where it gets patched to contain the + * detected memory size. + */ + return (void *)0x1000; +} + static int is_highbank(void) { uint32_t midr; diff --git a/configs/highbank_defconfig b/configs/highbank_defconfig index 369b65c..773ed7a 100644 --- a/configs/highbank_defconfig +++ b/configs/highbank_defconfig @@ -26,3 +26,4 @@ CONFIG_BOOTCOUNT_LIMIT=y CONFIG_SCSI=y CONFIG_CONS_INDEX=0 CONFIG_OF_LIBFDT=y +CONFIG_OF_BOARD=y diff --git a/include/configs/highbank.h b/include/configs/highbank.h index 5e3cc3a..7f37c81 100644 --- a/include/configs/highbank.h +++ b/include/configs/highbank.h @@ -18,7 +18,6 @@ #define CONFIG_SYS_MALLOC_LEN (512 * 1024) #define CONFIG_PL011_CLOCK 150000000 -#define CONFIG_PL01x_PORTS { (void *)(0xFFF36000) } #define CONFIG_SYS_BOOTCOUNT_LE /* Use little-endian accessors */ -- cgit v1.1 From debb07bf107a9feb3cbf03db6b10abae466e4d41 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 12 Apr 2021 01:04:52 +0100 Subject: net: calxedagmac: Convert to DM_ETH To squash that nasty warning message and make better use of the newly gained OF_CONTROL feature, let's convert the calxedagmac driver to the "new" driver model. The conversion is pretty straight forward, mostly just adjusting the use of the involved data structures. The only actual change is the required split of the receive routine into a receive and free_pkt part. Also this allows us to get rid of the hardcoded platform information and explicit init calls. This also uses the opportunity to wrap the code decoding the MMIO register base address, to make it safe for using PHYS_64BIT later. Signed-off-by: Andre Przywara Reviewed-by: Ramon Fried --- arch/arm/Kconfig | 1 + board/highbank/highbank.c | 13 --- configs/highbank_defconfig | 1 + drivers/net/Kconfig | 7 ++ drivers/net/calxedaxgmac.c | 192 ++++++++++++++++++++++++++++--------------- include/configs/highbank.h | 2 - include/netdev.h | 1 - scripts/config_whitelist.txt | 1 - 8 files changed, 137 insertions(+), 81 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3586426..e9f72b1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -719,6 +719,7 @@ config ARCH_HIGHBANK select CLK select CLK_CCF select AHCI + select DM_ETH config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c index 2e2300a..0667a48 100644 --- a/board/highbank/highbank.c +++ b/board/highbank/highbank.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -52,18 +51,6 @@ int board_init(void) return 0; } -/* We know all the init functions have been run now */ -int board_eth_init(struct bd_info *bis) -{ - int rc = 0; - -#ifdef CONFIG_CALXEDA_XGMAC - rc += calxedaxgmac_initialize(0, 0xfff50000); - rc += calxedaxgmac_initialize(1, 0xfff51000); -#endif - return rc; -} - #ifdef CONFIG_SCSI_AHCI_PLAT void scsi_init(void) { diff --git a/configs/highbank_defconfig b/configs/highbank_defconfig index 773ed7a..c3352b8 100644 --- a/configs/highbank_defconfig +++ b/configs/highbank_defconfig @@ -27,3 +27,4 @@ CONFIG_SCSI=y CONFIG_CONS_INDEX=0 CONFIG_OF_LIBFDT=y CONFIG_OF_BOARD=y +CONFIG_CALXEDA_XGMAC=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 72822ea..3826390 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -180,6 +180,13 @@ config CORTINA_NI_ENET This driver supports the Cortina-Access Ethernet MAC for all supported CAxxxx SoCs. +config CALXEDA_XGMAC + bool "Calxeda XGMAC support" + depends on DM_ETH + help + This driver supports the XGMAC in Calxeda Highbank and Midway + machines. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH diff --git a/drivers/net/calxedaxgmac.c b/drivers/net/calxedaxgmac.c index 8b2ee49..b98d709 100644 --- a/drivers/net/calxedaxgmac.c +++ b/drivers/net/calxedaxgmac.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include /* for dev_set_priv() */ #define TX_NUM_DESC 1 #define RX_NUM_DESC 32 @@ -212,6 +214,18 @@ struct xgmac_dma_desc { __le32 res[3]; }; +static struct xgmac_regs *xgmac_get_regs(struct eth_pdata *pdata) +{ + /* + * We use PHYS_64BIT on Highbank, so phys_addr_t is bigger than + * a pointer. U-Boot doesn't use LPAE (not even the MMU on highbank), + * so we can't access anything above 4GB. + * We have a check in the probe function below the ensure this, + * so casting to a 32-bit pointer type is fine here. + */ + return (struct xgmac_regs *)(uintptr_t)pdata->iobase; +} + /* XGMAC Descriptor Access Helpers */ static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz) { @@ -304,8 +318,6 @@ struct calxeda_eth_dev { u32 tx_currdesc; u32 rx_currdesc; - - struct eth_device *dev; } __aligned(32); /* @@ -313,10 +325,10 @@ struct calxeda_eth_dev { * advanced descriptors. */ -static void init_rx_desc(struct calxeda_eth_dev *priv) +static void init_rx_desc(struct eth_pdata *pdata, struct calxeda_eth_dev *priv) { struct xgmac_dma_desc *rxdesc = priv->rx_chain; - struct xgmac_regs *regs = (struct xgmac_regs *)priv->dev->iobase; + struct xgmac_regs *regs = xgmac_get_regs(pdata); void *rxbuffer = priv->rxbuffer; int i; @@ -330,17 +342,16 @@ static void init_rx_desc(struct calxeda_eth_dev *priv) } } -static void init_tx_desc(struct calxeda_eth_dev *priv) +static void init_tx_desc(struct eth_pdata *pdata, struct calxeda_eth_dev *priv) { - struct xgmac_regs *regs = (struct xgmac_regs *)priv->dev->iobase; + struct xgmac_regs *regs = xgmac_get_regs(pdata); desc_init_tx_desc(priv->tx_chain, TX_NUM_DESC); writel((ulong)priv->tx_chain, ®s->txdesclist); } -static int xgmac_reset(struct eth_device *dev) +static int xgmac_reset(struct xgmac_regs *regs) { - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; int timeout = MAC_TIMEOUT; u32 value; @@ -356,27 +367,28 @@ static int xgmac_reset(struct eth_device *dev) return timeout; } -static void xgmac_hwmacaddr(struct eth_device *dev) +static void xgmac_hwmacaddr(struct eth_pdata *pdata) { - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; + struct xgmac_regs *regs = xgmac_get_regs(pdata); u32 macaddr[2]; - memcpy(macaddr, dev->enetaddr, 6); + memcpy(macaddr, pdata->enetaddr, ARP_HLEN); writel(macaddr[1], ®s->macaddr[0].hi); writel(macaddr[0], ®s->macaddr[0].lo); } -static int xgmac_init(struct eth_device *dev, struct bd_info * bis) +static int xgmac_eth_start(struct udevice *dev) { - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; - int value; + struct eth_pdata *pdata = dev_get_plat(dev); + struct xgmac_regs *regs = xgmac_get_regs(pdata); + struct calxeda_eth_dev *priv = dev_get_priv(dev); + u32 value; - if (xgmac_reset(dev) < 0) - return -1; + if (xgmac_reset(regs) < 0) + return -ETIMEDOUT; /* set the hardware MAC address */ - xgmac_hwmacaddr(dev); + xgmac_hwmacaddr(pdata); /* set the AXI bus modes */ value = XGMAC_DMA_BUSMODE_ATDS | @@ -401,8 +413,8 @@ static int xgmac_init(struct eth_device *dev, struct bd_info * bis) writel(value, ®s->flow_control); /* Initialize the descriptor chains */ - init_rx_desc(priv); - init_tx_desc(priv); + init_rx_desc(pdata, priv); + init_tx_desc(pdata, priv); /* must set to 0, or when started up will cause issues */ priv->tx_currdesc = 0; @@ -425,10 +437,11 @@ static int xgmac_init(struct eth_device *dev, struct bd_info * bis) return 0; } -static int xgmac_tx(struct eth_device *dev, void *packet, int length) +static int xgmac_tx(struct udevice *dev, void *packet, int length) { - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; + struct calxeda_eth_dev *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + struct xgmac_regs *regs = xgmac_get_regs(pdata); u32 currdesc = priv->tx_currdesc; struct xgmac_dma_desc *txdesc = &priv->tx_chain[currdesc]; int timeout; @@ -453,35 +466,45 @@ static int xgmac_tx(struct eth_device *dev, void *packet, int length) return 0; } -static int xgmac_rx(struct eth_device *dev) +static int xgmac_rx(struct udevice *dev, int flags, uchar **packetp) { - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; + struct calxeda_eth_dev *priv = dev_get_priv(dev); u32 currdesc = priv->rx_currdesc; struct xgmac_dma_desc *rxdesc = &priv->rx_chain[currdesc]; int length = 0; /* check if the host has the desc */ if (desc_get_owner(rxdesc)) - return -1; /* something bad happened */ + return -EAGAIN; /* the MAC is still chewing on it */ length = desc_get_rx_frame_len(rxdesc); + *packetp = desc_get_buf_addr(rxdesc); - net_process_received_packet(desc_get_buf_addr(rxdesc), length); + priv->rx_currdesc = (currdesc + 1) & (RX_NUM_DESC - 1); + + return length; +} + +static int xgmac_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct xgmac_regs *regs = xgmac_get_regs(pdata); + struct calxeda_eth_dev *priv = dev_get_priv(dev); + u32 rxdesc = ((char *)packet - priv->rxbuffer) / ETH_BUF_SZ; + struct xgmac_dma_desc *p = &priv->rx_chain[rxdesc]; /* set descriptor back to owned by XGMAC */ - desc_set_rx_owner(rxdesc); + desc_set_rx_owner(p); writel(1, ®s->rxpoll); - priv->rx_currdesc = (currdesc + 1) & (RX_NUM_DESC - 1); - - return length; + return 0; } -static void xgmac_halt(struct eth_device *dev) +static void xgmac_eth_stop(struct udevice *dev) { - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; + struct calxeda_eth_dev *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + struct xgmac_regs *regs = xgmac_get_regs(pdata); int value; /* Disable TX/RX */ @@ -499,47 +522,88 @@ static void xgmac_halt(struct eth_device *dev) priv->rx_currdesc = 0; } -int calxedaxgmac_initialize(u32 id, ulong base_addr) +/* + * Changing the MAC address is not a good idea, as the fabric would + * need to know about this as well (it does not learn MAC addresses). + */ +static int xgmac_eth_write_hwaddr(struct udevice *dev) +{ + return -ENOSYS; +} + +static int xgmac_eth_read_rom_hwaddr(struct udevice *dev) { - struct eth_device *dev; - struct calxeda_eth_dev *priv; - struct xgmac_regs *regs; + struct eth_pdata *pdata = dev_get_plat(dev); + struct xgmac_regs *regs = xgmac_get_regs(pdata); u32 macaddr[2]; - regs = (struct xgmac_regs *)base_addr; + /* The MAC address is already configured, so read it from registers. */ + macaddr[1] = readl(®s->macaddr[0].hi); + macaddr[0] = readl(®s->macaddr[0].lo); + memcpy(pdata->enetaddr, macaddr, ARP_HLEN); - /* check hardware version */ - if (readl(®s->version) != 0x1012) - return -1; + return 0; +} - dev = malloc(sizeof(*dev)); - if (!dev) - return 0; - memset(dev, 0, sizeof(*dev)); +static int xgmac_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct calxeda_eth_dev *priv; /* Structure must be aligned, because it contains the descriptors */ priv = memalign(32, sizeof(*priv)); - if (!priv) { - free(dev); - return 0; + if (!priv) + return -ENOMEM; + dev_set_priv(dev, priv); + + pdata->iobase = devfdt_get_addr(dev); + if (pdata->iobase == FDT_ADDR_T_NONE) { + printf("%s: Cannot find XGMAC base address\n", __func__); + return -EINVAL; + } + if (pdata->iobase >= (1ULL << 32)) { + printf("%s: MMIO base address cannot be above 4GB\n", __func__); + return -EINVAL; } - dev->iobase = (int)base_addr; - dev->priv = priv; - priv->dev = dev; - sprintf(dev->name, "xgmac%d", id); + return 0; +} - /* The MAC address is already configured, so read it from registers. */ - macaddr[1] = readl(®s->macaddr[0].hi); - macaddr[0] = readl(®s->macaddr[0].lo); - memcpy(dev->enetaddr, macaddr, 6); +static int xgmac_eth_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct xgmac_regs *regs = xgmac_get_regs(pdata); - dev->init = xgmac_init; - dev->send = xgmac_tx; - dev->recv = xgmac_rx; - dev->halt = xgmac_halt; + /* check hardware version */ + if (readl(®s->version) != 0x1012) + return -ENODEV; - eth_register(dev); + xgmac_eth_read_rom_hwaddr(dev); - return 1; + return 0; } + +static const struct eth_ops xgmac_eth_ops = { + .start = xgmac_eth_start, + .send = xgmac_tx, + .recv = xgmac_rx, + .free_pkt = xgmac_free_pkt, + .stop = xgmac_eth_stop, + .write_hwaddr = xgmac_eth_write_hwaddr, + .read_rom_hwaddr = xgmac_eth_read_rom_hwaddr, +}; + +static const struct udevice_id xgmac_eth_ids[] = { + { .compatible = "calxeda,hb-xgmac" }, + { } +}; + +U_BOOT_DRIVER(eth_xgmac) = { + .name = "eth_xgmac", + .id = UCLASS_ETH, + .of_match = xgmac_eth_ids, + .of_to_plat = xgmac_ofdata_to_platdata, + .probe = xgmac_eth_probe, + .ops = &xgmac_eth_ops, + .plat_auto = sizeof(struct eth_pdata), +}; diff --git a/include/configs/highbank.h b/include/configs/highbank.h index 7f37c81..fbd26dd 100644 --- a/include/configs/highbank.h +++ b/include/configs/highbank.h @@ -27,8 +27,6 @@ #define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ CONFIG_SYS_SCSI_MAX_LUN) -#define CONFIG_CALXEDA_XGMAC - #define CONFIG_BOOT_RETRY_TIME -1 #define CONFIG_RESET_TO_RETRY diff --git a/include/netdev.h b/include/netdev.h index 0ad9f8d..b960c42 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -33,7 +33,6 @@ int at91emac_register(struct bd_info *bis, unsigned long iobase); int ax88180_initialize(struct bd_info *bis); int bcm_sf2_eth_register(struct bd_info *bis, u8 dev_num); int bfin_EMAC_initialize(struct bd_info *bis); -int calxedaxgmac_initialize(u32 id, ulong base_addr); int cs8900_initialize(u8 dev_num, int base_addr); int dc21x4x_initialize(struct bd_info *bis); int designware_initialize(ulong base_addr, u32 interface); diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index b24fa36..a2fcafd 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -149,7 +149,6 @@ CONFIG_BTB CONFIG_BUFNO_AUTO_INCR_BIT CONFIG_BUILD_ENVCRC CONFIG_BUS_WIDTH -CONFIG_CALXEDA_XGMAC CONFIG_CDP_APPLIANCE_VLAN_TYPE CONFIG_CDP_CAPABILITIES CONFIG_CDP_DEVICE_ID -- cgit v1.1 From ff47d539f28bcae15bc680d2e32fec6cc9551eb4 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 12 Apr 2021 01:04:53 +0100 Subject: arm: highbank: Remove artificial SDRAM size So far we were defining a somewhat confusing PHYS_SDRAM_1_SIZE variable, which originally was only used for setting the memtest boundaries. This definition in highbank.h has been removed about a year ago (moved to Kconfig), so we also don't need the hard-coded size definition any longer. Get rid of the misleading memory size definition, which was actually wrong anyway (it's 4088 MB for those machines with just 4GB of DRAM). Signed-off-by: Andre Przywara --- include/configs/highbank.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/configs/highbank.h b/include/configs/highbank.h index fbd26dd..ff92c4f 100644 --- a/include/configs/highbank.h +++ b/include/configs/highbank.h @@ -39,12 +39,6 @@ #define CONFIG_SYS_LOAD_ADDR 0x800000 #define CONFIG_SYS_64BIT_LBA -/*----------------------------------------------------------------------- - * Physical Memory Map - * The DRAM is already setup, so do not touch the DT node later. - */ -#define PHYS_SDRAM_1_SIZE (4089 << 20) - /* Environment data setup */ #define CONFIG_SYS_NVRAM_BASE_ADDR 0xfff88000 /* NVRAM base address */ -- cgit v1.1 From 1238d0143ab8e8c75e6de97b4c5475077c1abbbf Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 12 Apr 2021 01:04:54 +0100 Subject: arm: highbank: Do DRAM init from DT So far U-Boot was hard coding a (surely sufficient) memory size of 512 MB, even though all machines out there have at least 4GB of DRAM. Since U-Boot uses its memory knowledge to populate the EFI memory map, we are missing out here, at best losing everything beyond 4GB on Midway boxes (which typically come with 8GB of DRAM). Since the management processor populated the DT memory node already with the detected DRAM size and configuration, we use that to populate U-Boot's memory bank information, which is the base for the UEFI memory map. This finally allows us to get rid of the NR_DRAM_BANKS=0 hack, that we had in place to avoid U-Boot messing up the DT memory node before loading the kernel. Also, to cover the whole of memory, we need to enable PHYS_64BIT. Signed-off-by: Andre Przywara --- arch/arm/Kconfig | 1 + board/highbank/highbank.c | 9 +++++++-- configs/highbank_defconfig | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e9f72b1..31d687e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -720,6 +720,7 @@ config ARCH_HIGHBANK select CLK_CCF select AHCI select DM_ETH + select PHYS_64BIT config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c index 0667a48..ffb6fd9 100644 --- a/board/highbank/highbank.c +++ b/board/highbank/highbank.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -84,8 +85,12 @@ int misc_init_r(void) int dram_init(void) { - gd->ram_size = SZ_512M; - return 0; + return fdtdec_setup_mem_size_base(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); } #if defined(CONFIG_OF_BOARD_SETUP) diff --git a/configs/highbank_defconfig b/configs/highbank_defconfig index c3352b8..5d65049 100644 --- a/configs/highbank_defconfig +++ b/configs/highbank_defconfig @@ -3,7 +3,7 @@ CONFIG_SYS_DCACHE_OFF=y CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_HIGHBANK=y CONFIG_SYS_TEXT_BASE=0x00008000 -CONFIG_NR_DRAM_BANKS=0 +CONFIG_NR_DRAM_BANKS=2 CONFIG_ENV_SIZE=0x2000 CONFIG_SYS_BOOTCOUNT_ADDR=0xfff3cf0c CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y -- cgit v1.1 From 9f4b53436c7385d4800645eb1158dd4d56cc32f4 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 12 Apr 2021 01:04:55 +0100 Subject: arm: highbank: Update maintainership Rob does not have access to any Calxeda systems anymore, also has expressed a lack of interest in those systems in the past. I have multiple working Midway nodes under my desk in the office, so am happy to take over maintainership. Signed-off-by: Andre Przywara --- board/highbank/MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/highbank/MAINTAINERS b/board/highbank/MAINTAINERS index 69ddedd..a542bd1 100644 --- a/board/highbank/MAINTAINERS +++ b/board/highbank/MAINTAINERS @@ -1,5 +1,5 @@ HIGHBANK BOARD -M: Rob Herring +M: Andre Przywara S: Maintained F: board/highbank/ F: include/configs/highbank.h -- cgit v1.1 From 56a3433ef559512e731a943d8af7965973d090df Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 19 Apr 2021 16:18:49 -0400 Subject: sysinfo.h: Add re-inclusion guard Add #ifndef __SYSINFO_H__ ... #endif to prevent re-inclusion of this file. Signed-off-by: Tom Rini --- include/sysinfo.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/sysinfo.h b/include/sysinfo.h index 68fad25..8054d4d 100644 --- a/include/sysinfo.h +++ b/include/sysinfo.h @@ -4,6 +4,9 @@ * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc */ +#ifndef __SYSINFO_H__ +#define __SYSINFO_H__ + struct udevice; /* @@ -228,3 +231,4 @@ static inline int sysinfo_get_fit_loadable(struct udevice *dev, int index, } #endif +#endif -- cgit v1.1 From 2963d606bc6bbaf7b097ec8a42abec7f71339a9d Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Thu, 1 Apr 2021 02:01:52 +0300 Subject: psci: add v1.0/v1.1 definitions from Linux Sync and add PSCI API versions 1.0/1.1 definitions from Linux. Signed-off-by: Igor Opaniuk --- include/linux/psci.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/linux/psci.h b/include/linux/psci.h index 841dbc8..38edde3 100644 --- a/include/linux/psci.h +++ b/include/linux/psci.h @@ -46,6 +46,14 @@ #define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5) #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) +#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) +#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) +#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) +#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) + +#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) +#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) + /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff #define PSCI_0_2_POWER_STATE_ID_SHIFT 0 @@ -56,6 +64,13 @@ #define PSCI_0_2_POWER_STATE_AFFL_MASK \ (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) +/* PSCI extended power state encoding for CPU_SUSPEND function */ +#define PSCI_1_0_EXT_POWER_STATE_ID_MASK 0xfffffff +#define PSCI_1_0_EXT_POWER_STATE_ID_SHIFT 0 +#define PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT 30 +#define PSCI_1_0_EXT_POWER_STATE_TYPE_MASK \ + (0x1 << PSCI_1_0_EXT_POWER_STATE_TYPE_SHIFT) + /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ #define PSCI_0_2_AFFINITY_LEVEL_ON 0 #define PSCI_0_2_AFFINITY_LEVEL_OFF 1 @@ -75,6 +90,18 @@ (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) #define PSCI_VERSION_MINOR(ver) \ ((ver) & PSCI_VERSION_MINOR_MASK) +#define PSCI_VERSION(maj, min) \ + ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ + ((min) & PSCI_VERSION_MINOR_MASK)) + +/* PSCI features decoding (>=1.0) */ +#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 +#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK \ + (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT) + +#define PSCI_1_0_OS_INITIATED BIT(0) +#define PSCI_1_0_SUSPEND_MODE_PC 0 +#define PSCI_1_0_SUSPEND_MODE_OSI 1 /* PSCI return values (inclusive of all PSCI versions) */ #define PSCI_RET_SUCCESS 0 @@ -86,6 +113,7 @@ #define PSCI_RET_INTERNAL_FAILURE -6 #define PSCI_RET_NOT_PRESENT -7 #define PSCI_RET_DISABLED -8 +#define PSCI_RET_INVALID_ADDRESS -9 #ifdef CONFIG_ARM_PSCI_FW unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, -- cgit v1.1 From b7135b034f9f19a89516bb53535891e14a545395 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Thu, 1 Apr 2021 02:01:53 +0300 Subject: psci: add features/reset2 support Adds support for: * PSCI_FEATURES, which was introduced in PSCI 1.0. This provides API that allows discovering whether a specific PSCI function is implemented and its features. * SYSTEM_RESET2, which was introduced in PSCI 1.1, which extends existing SYSTEM_RESET. It provides support for vendor-specific resets, providing reset_type as an additional param. For additional details visit [1]. Implementations of some functions were borrowed from Linux PSCI driver code [2]. [1] https://developer.arm.com/documentation/den0022/latest/ [2] drivers/firmware/psci/psci.c Signed-off-by: Igor Opaniuk --- drivers/firmware/psci.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/psci.h | 3 +++ 2 files changed, 71 insertions(+) diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 68953cc..be57552 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,18 @@ #define PSCI_METHOD_HVC 1 #define PSCI_METHOD_SMC 2 +/* + * While a 64-bit OS can make calls with SMC32 calling conventions, for some + * calls it is necessary to use SMC64 to pass or return 64-bit values. + * For such calls PSCI_FN_NATIVE(version, name) will choose the appropriate + * (native-width) function ID. + */ +#if defined(CONFIG_ARM64) +#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name +#else +#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN_##name +#endif + #if CONFIG_IS_ENABLED(EFI_LOADER) int __efi_runtime_data psci_method; #else @@ -53,6 +66,34 @@ unsigned long __efi_runtime invoke_psci_fn return res.a0; } +static int psci_features(u32 psci_func_id) +{ + return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES, + psci_func_id, 0, 0); +} + +static u32 psci_0_2_get_version(void) +{ + return invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); +} + +static bool psci_is_system_reset2_supported(void) +{ + int ret; + u32 ver; + + ver = psci_0_2_get_version(); + + if (PSCI_VERSION_MAJOR(ver) >= 1) { + ret = psci_features(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2)); + + if (ret != PSCI_RET_NOT_SUPPORTED) + return true; + } + + return false; +} + static int psci_bind(struct udevice *dev) { /* No SYSTEM_RESET support for PSCI 0.1 */ @@ -141,6 +182,33 @@ void reset_misc(void) } #endif /* CONFIG_PSCI_RESET */ +void psci_sys_reset(u32 type) +{ + bool reset2_supported; + + do_psci_probe(); + + reset2_supported = psci_is_system_reset2_supported(); + + if (type == SYSRESET_WARM && reset2_supported) { + /* + * reset_type[31] = 0 (architectural) + * reset_type[30:0] = 0 (SYSTEM_WARM_RESET) + * cookie = 0 (ignored by the implementation) + */ + invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), 0, 0, 0); + } else { + invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0); + } +} + +void psci_sys_poweroff(void) +{ + do_psci_probe(); + + invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); +} + #ifdef CONFIG_CMD_POWEROFF int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { diff --git a/include/linux/psci.h b/include/linux/psci.h index 38edde3..c78c107 100644 --- a/include/linux/psci.h +++ b/include/linux/psci.h @@ -118,6 +118,9 @@ #ifdef CONFIG_ARM_PSCI_FW unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); +void psci_sys_reset(u32 type); +void psci_sys_poweroff(void); + #else static inline unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) -- cgit v1.1 From 91f00ba2c1c980236ba526b5e8f34e982e7b48d8 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Thu, 1 Apr 2021 02:01:54 +0300 Subject: sysreset: psci: use psci driver exported functions Use psci driver exported functions for reset/poweroff, instead of invoking directly invoke_psci_fn. Signed-off-by: Igor Opaniuk --- drivers/sysreset/sysreset_psci.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c index c7907b3..83ecbcb 100644 --- a/drivers/sysreset/sysreset_psci.c +++ b/drivers/sysreset/sysreset_psci.c @@ -11,22 +11,18 @@ static int psci_sysreset_request(struct udevice *dev, enum sysreset_t type) { - unsigned long function_id; - switch (type) { case SYSRESET_WARM: case SYSRESET_COLD: - function_id = PSCI_0_2_FN_SYSTEM_RESET; + psci_sys_reset(type); break; case SYSRESET_POWER_OFF: - function_id = PSCI_0_2_FN_SYSTEM_OFF; + psci_sys_poweroff(); break; default: return -ENOSYS; } - invoke_psci_fn(function_id, 0, 0, 0); - return -EINPROGRESS; } -- cgit v1.1 From a6713b3a3c7adf4a99e9ad8c04356fce200fb83f Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Thu, 1 Apr 2021 02:01:55 +0300 Subject: sysreset: provide type of reset in do_reset cmd Add additional param for reset cmd, which provides type of reset. Signed-off-by: Igor Opaniuk --- cmd/boot.c | 2 +- drivers/sysreset/sysreset-uclass.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/boot.c b/cmd/boot.c index 36aba22..b84c0ed 100644 --- a/cmd/boot.c +++ b/cmd/boot.c @@ -56,7 +56,7 @@ U_BOOT_CMD( #endif U_BOOT_CMD( - reset, 1, 0, do_reset, + reset, 2, 0, do_reset, "Perform RESET of the CPU", "" ); diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index 9512f68..279b087 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -122,10 +122,19 @@ void reset_cpu(void) #if IS_ENABLED(CONFIG_SYSRESET_CMD_RESET) int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + enum sysreset_t reset_type = SYSRESET_COLD; + + if (argc > 2) + return CMD_RET_USAGE; + + if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'w') { + reset_type = SYSRESET_WARM; + } + printf("resetting ...\n"); mdelay(100); - sysreset_walk_halt(SYSRESET_COLD); + sysreset_walk_halt(reset_type); return 0; } -- cgit v1.1 From 1aa2a745c5e652689626b5cccd758fa9cdb56f9d Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Thu, 1 Apr 2021 02:01:56 +0300 Subject: doc: usage: add usage details for reset cmd Add usage details for reset command. Signed-off-by: Igor Opaniuk --- doc/usage/index.rst | 1 + doc/usage/reset.rst | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 doc/usage/reset.rst diff --git a/doc/usage/index.rst b/doc/usage/index.rst index b64cfe4..528b3c7 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -40,3 +40,4 @@ Shell commands sbi true scp03 + reset diff --git a/doc/usage/reset.rst b/doc/usage/reset.rst new file mode 100644 index 0000000..384d5d6 --- /dev/null +++ b/doc/usage/reset.rst @@ -0,0 +1,26 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +reset command +============= + +Synopsis +-------- + +:: + + reset [-w] + +Description +----------- + +Perform reset of the CPU. By default does COLD reset, which resets CPU, +DDR and peripherals, on some boards also resets external PMIC. + +-w + Do warm WARM, reset CPU but keep peripheral/DDR/PMIC active. + + +Return value +------------ + +The return value $? is always set to 0 (true). -- cgit v1.1 From fd90aca329a37eade4187ca886a8dea5c60aaba0 Mon Sep 17 00:00:00 2001 From: Denys Drozdov Date: Wed, 7 Apr 2021 15:28:24 +0300 Subject: toradex: configblock: fix module revision in config block U-boot might display wrong module revision information for modules with an assembly version 'K'. "cfgblock create" does not takes into account all revision digits from PID8. This fix takes into account all digits of PID8 to store module revision. Signed-off-by: Denys Drozdov Reviewed-by: Oleksandr Suvorov --- board/toradex/common/tdx-cfg-block.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index b00467f..93eb20c 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -556,6 +556,8 @@ static int get_cfgblock_interactive(void) static int get_cfgblock_barcode(char *barcode, struct toradex_hw *tag, u32 *serial) { + char revision[3] = {barcode[6], barcode[7], '\0'}; + if (strlen(barcode) < 16) { printf("Argument too short, barcode is 16 chars long\n"); return -1; @@ -564,7 +566,7 @@ static int get_cfgblock_barcode(char *barcode, struct toradex_hw *tag, /* Get hardware information from the first 8 digits */ tag->ver_major = barcode[4] - '0'; tag->ver_minor = barcode[5] - '0'; - tag->ver_assembly = barcode[7] - '0'; + tag->ver_assembly = simple_strtoul(revision, NULL, 10); barcode[4] = '\0'; tag->prodid = simple_strtoul(barcode, NULL, 10); -- cgit v1.1 From 1b8897c63e4c4eedd55f69f9728cd49f2a1cddba Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 11 Apr 2021 11:21:56 +0200 Subject: test: fix test/dm/regmap.c regmap_read() only fills the first two bytes of val. The last two bytes are random data from the stack. This means the test will fail randomly. For low endian systems we could simply initialize val to 0 and get correct results. But tests should not depend on endianness. So let's use a pointer conversion instead. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- test/dm/regmap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/dm/regmap.c b/test/dm/regmap.c index 22a2930..372a73c 100644 --- a/test/dm/regmap.c +++ b/test/dm/regmap.c @@ -286,7 +286,8 @@ U_BOOT_DRIVER(regmap_test) = { static int dm_test_devm_regmap(struct unit_test_state *uts) { int i = 0; - u32 val; + u16 val; + void *valp = &val; u16 pattern[REGMAP_TEST_BUF_SZ]; u16 *buffer; struct udevice *dev; @@ -311,7 +312,7 @@ static int dm_test_devm_regmap(struct unit_test_state *uts) ut_assertok(regmap_write(priv->cfg_regmap, i, pattern[i])); } for (i = 0; i < REGMAP_TEST_BUF_SZ; i++) { - ut_assertok(regmap_read(priv->cfg_regmap, i, &val)); + ut_assertok(regmap_read(priv->cfg_regmap, i, valp)); ut_asserteq(val, buffer[i]); ut_asserteq(val, pattern[i]); } @@ -319,9 +320,9 @@ static int dm_test_devm_regmap(struct unit_test_state *uts) ut_asserteq(-ERANGE, regmap_write(priv->cfg_regmap, REGMAP_TEST_BUF_SZ, val)); ut_asserteq(-ERANGE, regmap_read(priv->cfg_regmap, REGMAP_TEST_BUF_SZ, - &val)); + valp)); ut_asserteq(-ERANGE, regmap_write(priv->cfg_regmap, -1, val)); - ut_asserteq(-ERANGE, regmap_read(priv->cfg_regmap, -1, &val)); + ut_asserteq(-ERANGE, regmap_read(priv->cfg_regmap, -1, valp)); return 0; } -- cgit v1.1 From 1598c83ecec64619379834ec21de8efe2536ac3d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 11 Apr 2021 11:21:57 +0200 Subject: x86: correct usage of CFLAGS_NON_EFI The current usage of the variable CFLAGS_NON_EFI on the x86 architecture deviates from other architectures. Variable CFLAGS_NON_EFI is the list of compiler flags to be removed when building UEFI applications. It is not a list of flags to be added anywhere. Signed-off-by: Heinrich Schuchardt --- arch/x86/config.mk | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 27d8412..3067702 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -39,10 +39,10 @@ LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined -s OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \ -j .rel -j .rela -j .reloc -ifeq ($(IS_32BIT),y) -CFLAGS_NON_EFI := -mregparm=3 -endif +# Compiler flags to be added when building UEFI applications CFLAGS_EFI := -fpic -fshort-wchar +# Compiler flags to be removed when building UEFI applications +CFLAGS_NON_EFI := -mregparm=3 ifeq ($(CONFIG_EFI_STUB_64BIT),) CFLAGS_EFI += $(call cc-option, -mno-red-zone) @@ -70,7 +70,9 @@ LDSCRIPT := $(LDSCRIPT_EFI) else -PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI) +ifeq ($(IS_32BIT),y) +PLATFORM_CPPFLAGS += -mregparm=3 +endif KBUILD_LDFLAGS += --emit-relocs LDFLAGS_FINAL += --gc-sections $(if $(CONFIG_SPL_BUILD),,-pie) -- cgit v1.1 From 4e9bce12432492aa7a7c2121d9fae1640606ace5 Mon Sep 17 00:00:00 2001 From: Joel Peshkin Date: Sun, 11 Apr 2021 11:21:58 +0200 Subject: Add support for stack-protector Add support for stack protector for UBOOT, SPL, and TPL as well as new pytest for stackprotector Signed-off-by: Joel Peshkin Adjust UEFI build flags. Signed-off-by: Heinrich Schuchardt --- MAINTAINERS | 7 +++++++ Makefile | 5 +++++ arch/arm/config.mk | 3 ++- arch/riscv/lib/Makefile | 1 + arch/x86/config.mk | 2 +- cmd/Kconfig | 9 +++++++++ cmd/Makefile | 1 + cmd/stackprot_test.c | 19 +++++++++++++++++++ common/Kconfig | 17 +++++++++++++++++ common/Makefile | 1 + common/stackprot.c | 20 ++++++++++++++++++++ configs/sandbox_defconfig | 2 ++ scripts/Makefile.spl | 6 ++++++ test/py/tests/test_stackprotector.py | 14 ++++++++++++++ 14 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 cmd/stackprot_test.c create mode 100644 common/stackprot.c create mode 100644 test/py/tests/test_stackprotector.py diff --git a/MAINTAINERS b/MAINTAINERS index c6dd9bf..2d267ae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1062,6 +1062,13 @@ F: include/sqfs.h F: cmd/sqfs.c F: test/py/tests/test_fs/test_squashfs/ +STACKPROTECTOR +M: Joel Peshkin +S: Maintained +F: common/stackprot.c +F: cmd/stackprot_test.c +F: test/py/tests/test_stackprotector.py + TARGET_BCMNS3 M: Bharat Gooty M: Rayagonda Kokatanur diff --git a/Makefile b/Makefile index e423f6d..3fc9777 100644 --- a/Makefile +++ b/Makefile @@ -676,7 +676,12 @@ else KBUILD_CFLAGS += -O2 endif +ifeq ($(CONFIG_STACKPROTECTOR),y) +KBUILD_CFLAGS += $(call cc-option,-fstack-protector-strong) +CFLAGS_EFI += $(call cc-option,-fno-stack-protector) +else KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) +endif KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) # disable stringop warnings in gcc 8+ diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 4153f7e..e79f010 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -11,7 +11,8 @@ CONFIG_STANDALONE_LOAD_ADDR = 0xc100000 endif endif -CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections +CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \ + -fstack-protector-strong CFLAGS_EFI := -fpic -fshort-wchar LDFLAGS_FINAL += --gc-sections diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index ff0677a..d08cbe9 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SPL_BUILD) += spl.o obj-y += fdt_fixup.o # For building EFI apps +CFLAGS_NON_EFI := -fstack-protector-strong CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI) CFLAGS_REMOVE_$(EFI_CRT0) := $(CFLAGS_NON_EFI) diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 3067702..7a82425 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -42,7 +42,7 @@ OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \ # Compiler flags to be added when building UEFI applications CFLAGS_EFI := -fpic -fshort-wchar # Compiler flags to be removed when building UEFI applications -CFLAGS_NON_EFI := -mregparm=3 +CFLAGS_NON_EFI := -mregparm=3 -fstack-protector-strong ifeq ($(CONFIG_EFI_STUB_64BIT),) CFLAGS_EFI += $(call cc-option, -mno-red-zone) diff --git a/cmd/Kconfig b/cmd/Kconfig index 2b66285..9e8b692 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2325,6 +2325,15 @@ config CMD_AVB avb read_part_hex - read data from partition and output to stdout avb write_part - write data to partition avb verify - run full verification chain + +config CMD_STACKPROTECTOR_TEST + bool "Test command for stack protector" + depends on STACKPROTECTOR + help + Enable stackprot_test command + The stackprot_test command will force a stack overrun to test + the stack smashing detection mechanisms. + endmenu config CMD_UBI diff --git a/cmd/Makefile b/cmd/Makefile index e606ac4..4977fa1 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -144,6 +144,7 @@ obj-$(CONFIG_CMD_SPI) += spi.o obj-$(CONFIG_CMD_STRINGS) += strings.o obj-$(CONFIG_CMD_SMC) += smccc.o obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o pxe_utils.o +obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o obj-$(CONFIG_CMD_TERMINAL) += terminal.o obj-$(CONFIG_CMD_TIME) += time.o obj-$(CONFIG_CMD_TIMER) += timer.o diff --git a/cmd/stackprot_test.c b/cmd/stackprot_test.c new file mode 100644 index 0000000..36f5bac --- /dev/null +++ b/cmd/stackprot_test.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Broadcom + */ + +#include +#include + +static int do_test_stackprot_fail(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + char a[128]; + + memset(a, 0xa5, 512); + return 0; +} + +U_BOOT_CMD(stackprot_test, 1, 1, do_test_stackprot_fail, + "test stack protector fail", ""); diff --git a/common/Kconfig b/common/Kconfig index 0e36dfd..26496f9 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -618,6 +618,23 @@ config TPL_HASH and the algorithms it supports are defined in common/hash.c. See also CMD_HASH for command-line access. +config STACKPROTECTOR + bool "Stack Protector buffer overflow detection" + default n + help + Enable stack smash detection through compiler's stack-protector + canary logic + +config SPL_STACKPROTECTOR + bool "Stack Protector buffer overflow detection for SPL" + depends on STACKPROTECTOR && SPL + default n + +config TPL_STACKPROTECTOR + bool "Stack Protector buffer overflow detection for TPL" + depends on STACKPROTECTOR && TPL + default n + endmenu menu "Update support" diff --git a/common/Makefile b/common/Makefile index 0952ae2..829ea5f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -137,6 +137,7 @@ obj-$(CONFIG_CMD_LOADB) += xyzModem.o obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_AVB_VERIFY) += avb_verify.o +obj-$(CONFIG_$(SPL_TPL_)STACKPROTECTOR) += stackprot.o obj-$(CONFIG_SCP03) += scp03.o obj-$(CONFIG_QFW) += qfw.o diff --git a/common/stackprot.c b/common/stackprot.c new file mode 100644 index 0000000..d5b7061 --- /dev/null +++ b/common/stackprot.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Broadcom + */ + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long __stack_chk_guard = (unsigned long)(0xfeedf00ddeadbeef & ~0UL); + +void __stack_chk_fail(void) +{ + void *ra; + + ra = __builtin_extract_return_addr(__builtin_return_address(0)); + panic("Stack smashing detected in function:\n%p relocated from %p", + ra, ra - gd->reloc_off); +} diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 12af9be..d3de9c3 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -25,6 +25,7 @@ CONFIG_LOG_SYSLOG=y CONFIG_LOG_ERROR_RETURN=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_MISC_INIT_F=y +CONFIG_STACKPROTECTOR=y CONFIG_ANDROID_AB=y CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y @@ -97,6 +98,7 @@ CONFIG_CMD_CRAMFS=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_SQUASHFS=y CONFIG_CMD_MTDPARTS=y +CONFIG_CMD_STACKPROTECTOR_TEST=y CONFIG_MAC_PARTITION=y CONFIG_AMIGA_PARTITION=y CONFIG_OF_CONTROL=y diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index ca98822..c69525f 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -67,6 +67,12 @@ include $(srctree)/scripts/Makefile.lib KBUILD_CFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections +ifeq ($(CONFIG_$(SPL_TPL_)STACKPROTECTOR),y) +KBUILD_CFLAGS += -fstack-protector-strong +else +KBUILD_CFLAGS += -fno-stack-protector +endif + # FIX ME cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \ $(NOSTDINC_FLAGS) diff --git a/test/py/tests/test_stackprotector.py b/test/py/tests/test_stackprotector.py new file mode 100644 index 0000000..b009437 --- /dev/null +++ b/test/py/tests/test_stackprotector.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2021 Broadcom + +import pytest +import signal + +@pytest.mark.buildconfigspec('cmd_stackprotector_test') +def test_stackprotector(u_boot_console): + """Test that the stackprotector function works.""" + + u_boot_console.run_command('stackprot_test',wait_for_prompt=False) + expected_response = 'Stack smashing detected' + u_boot_console.wait_for(expected_response) + u_boot_console.restart_uboot() -- cgit v1.1