From 89b759469d525f4d5f9c29cd3b1f490311c67f85 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Sat, 24 Apr 2021 14:37:28 +0200 Subject: ARM: imx: pm-imx5: Fix references to imx5_cpu_suspend_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The name of the struct, as defined in arch/arm/mach-imx/pm-imx5.c, is imx5_cpu_suspend_info. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/suspend-imx53.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/suspend-imx53.S b/arch/arm/mach-imx/suspend-imx53.S index 41b8aad65363..46570ec2fbcf 100644 --- a/arch/arm/mach-imx/suspend-imx53.S +++ b/arch/arm/mach-imx/suspend-imx53.S @@ -28,11 +28,11 @@ * ^ * ^ * imx53_suspend code - * PM_INFO structure(imx53_suspend_info) + * PM_INFO structure(imx5_cpu_suspend_info) * ======================== low address ======================= */ -/* Offsets of members of struct imx53_suspend_info */ +/* Offsets of members of struct imx5_cpu_suspend_info */ #define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 #define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 #define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 -- cgit From 22b5059b95e4d3b50bdd3e262182864a5ad7ec12 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Sat, 24 Apr 2021 18:21:27 +0200 Subject: ARM: imx: Initialize SoC ID on i.MX50 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As on i.MX51 and i.MX53, initialize the SoC ID based on the SoC compatible string of the board. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx50.c | 7 +++++++ drivers/soc/imx/soc-imx.c | 3 +++ include/soc/imx/cpu.h | 1 + 3 files changed, 11 insertions(+) diff --git a/arch/arm/mach-imx/mach-imx50.c b/arch/arm/mach-imx/mach-imx50.c index f4da205f57db..a2d35f9ba474 100644 --- a/arch/arm/mach-imx/mach-imx50.c +++ b/arch/arm/mach-imx/mach-imx50.c @@ -9,6 +9,12 @@ #include #include "common.h" +#include "hardware.h" + +static void __init imx50_init_early(void) +{ + mxc_set_cpu_type(MXC_CPU_MX50); +} static const char * const imx50_dt_board_compat[] __initconst = { "fsl,imx50", @@ -16,5 +22,6 @@ static const char * const imx50_dt_board_compat[] __initconst = { }; DT_MACHINE_START(IMX50_DT, "Freescale i.MX50 (Device Tree Support)") + .init_early = imx50_init_early, .dt_compat = imx50_dt_board_compat, MACHINE_END diff --git a/drivers/soc/imx/soc-imx.c b/drivers/soc/imx/soc-imx.c index 0738c0f36792..ac6d856ba228 100644 --- a/drivers/soc/imx/soc-imx.c +++ b/drivers/soc/imx/soc-imx.c @@ -70,6 +70,9 @@ static int __init imx_soc_device_init(void) case MXC_CPU_MX35: soc_id = "i.MX35"; break; + case MXC_CPU_MX50: + soc_id = "i.MX50"; + break; case MXC_CPU_MX51: ocotp_compat = "fsl,imx51-iim"; soc_id = "i.MX51"; diff --git a/include/soc/imx/cpu.h b/include/soc/imx/cpu.h index 42d6aeb951fa..0bf610acafd0 100644 --- a/include/soc/imx/cpu.h +++ b/include/soc/imx/cpu.h @@ -9,6 +9,7 @@ #define MXC_CPU_MX27 27 #define MXC_CPU_MX31 31 #define MXC_CPU_MX35 35 +#define MXC_CPU_MX50 50 #define MXC_CPU_MX51 51 #define MXC_CPU_MX53 53 #define MXC_CPU_IMX6SL 0x60 -- cgit From 66e69d8849e9b0d54686ed12556c0e078e16e056 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:29 +0200 Subject: ARM: imx6q: remove PHY fixup for KSZ9031 Starting with: bcf3440c6dd7 ("net: phy: micrel: add phy-mode support for the KSZ9031 PHY") the micrel phy driver started respecting phy-mode for the KSZ9031 PHY. At least with kernel v5.8 configuration provided by this fixup was overwritten by the micrel driver. This fixup was providing following configuration: RX path: 2.58ns delay rx -0.42 (left shift) + rx_clk +0.96ns (right shift) = 1,38 + 1,2 internal RX delay = 2.58ns TX path: 0.96ns delay tx (no delay) + tx_clk 0.96ns (right shift) = 0.96ns This configuration is outside of the recommended RGMII clock skew delays and about in the middle of: rgmii-idrx and rgmii-id Since most embedded systems do not have enough place to introduce significant clock skew, rgmii-id is the way to go. In case this patch breaks network functionality on your system, build kernel with enabled MICREL_PHY. If it is still not working then try following device tree options: 1. Set (or change) phy-mode in DT to: phy-mode = "rgmii-id"; This actives internal delay for both RX and TX. 1. Set (or change) phy-mode in DT to: phy-mode = "rgmii-idrx"; This actives internal delay for RX only. 3. Use following DT properties: phy-mode = "rgmii"; txen-skew-psec = <0>; rxdv-skew-psec = <0>; rxd0-skew-psec = <0>; rxd1-skew-psec = <0>; rxd2-skew-psec = <0>; rxd3-skew-psec = <0>; rxc-skew-psec = <1860>; txc-skew-psec = <1860>; This activates the internal delays for RX and TX, with the value as the fixup that is removed in this patch. Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 703998ebb52e..78205f90da27 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -40,27 +40,6 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev) return 0; } -static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val) -{ - phy_write(dev, 0x0d, device); - phy_write(dev, 0x0e, reg); - phy_write(dev, 0x0d, (1 << 14) | device); - phy_write(dev, 0x0e, val); -} - -static int ksz9031rn_phy_fixup(struct phy_device *dev) -{ - /* - * min rx data delay, max rx/tx clock delay, - * min rx/tx control delay - */ - mmd_write_reg(dev, 2, 4, 0); - mmd_write_reg(dev, 2, 5, 0); - mmd_write_reg(dev, 2, 8, 0x003ff); - - return 0; -} - /* * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High * as they are used for slots1-7 PERST# @@ -152,8 +131,6 @@ static void __init imx6q_enet_phy_init(void) if (IS_BUILTIN(CONFIG_PHYLIB)) { phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, ksz9021rn_phy_fixup); - phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK, - ksz9031rn_phy_fixup); phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef, ar8031_phy_fixup); phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef, -- cgit From 5fff104f04dca67eb099026e88234b0ed3f8cb27 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:30 +0200 Subject: ARM: imx6q: remove part of ar8031_phy_fixup() This part of this fixup is overwritten by at803x_config_init() in drivers/net/phy/at803x.c. No additional devicetree fixes are needed. Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 78205f90da27..1abefe7e1c3a 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -82,12 +82,6 @@ static int ar8031_phy_fixup(struct phy_device *dev) val |= 0x18; phy_write(dev, 0xe, val); - /* introduce tx clock delay */ - phy_write(dev, 0x1d, 0x5); - val = phy_read(dev, 0x1e); - val |= 0x0100; - phy_write(dev, 0x1e, val); - return 0; } -- cgit From 4d3b70d980c2f7ab9e58c0a2485f9fe052d768ea Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:31 +0200 Subject: ARM: imx6q: remove BMCR_PDOWN handler in ar8035_phy_fixup() BMCR_PDOWN is removed by resume handler at803x_resume() in drivers/net/phy/at803x.c Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 1abefe7e1c3a..4c840e116003 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -110,11 +110,6 @@ static int ar8035_phy_fixup(struct phy_device *dev) */ ar8031_phy_fixup(dev); - /*check phy power*/ - val = phy_read(dev, 0x0); - if (val & BMCR_PDOWN) - phy_write(dev, 0x0, val & ~BMCR_PDOWN); - return 0; } -- cgit From f5d9aa79dfdfed50b9179061b6daeb3971021361 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:32 +0200 Subject: ARM: imx6q: remove clk-out fixup for the Atheros AR8031 and AR8035 PHYs This configuration should be set over device tree. If this patch breaks network functionality on your system, enable the AT803X_PHY driver and set following device tree property in the PHY node: qca,clk-out-frequency = <125000000>; Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 4c840e116003..d12b571a61ac 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -68,25 +68,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup); -static int ar8031_phy_fixup(struct phy_device *dev) -{ - u16 val; - - /* To enable AR8031 output a 125MHz clk from CLK_25M */ - phy_write(dev, 0xd, 0x7); - phy_write(dev, 0xe, 0x8016); - phy_write(dev, 0xd, 0x4007); - - val = phy_read(dev, 0xe); - val &= 0xffe3; - val |= 0x18; - phy_write(dev, 0xe, val); - - return 0; -} - -#define PHY_ID_AR8031 0x004dd074 - static int ar8035_phy_fixup(struct phy_device *dev) { u16 val; @@ -101,15 +82,6 @@ static int ar8035_phy_fixup(struct phy_device *dev) val = phy_read(dev, 0xe); phy_write(dev, 0xe, val & ~(1 << 8)); - /* - * Enable 125MHz clock from CLK_25M on the AR8031. This - * is fed in to the IMX6 on the ENET_REF_CLK (V22) pad. - * Also, introduce a tx clock delay. - * - * This is the same as is the AR8031 fixup. - */ - ar8031_phy_fixup(dev); - return 0; } @@ -120,8 +92,6 @@ static void __init imx6q_enet_phy_init(void) if (IS_BUILTIN(CONFIG_PHYLIB)) { phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, ksz9021rn_phy_fixup); - phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef, - ar8031_phy_fixup); phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef, ar8035_phy_fixup); } -- cgit From 582368377926be5c31660167f40f21d8d6805fd4 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:33 +0200 Subject: ARM: imx6q: remove Atheros AR8035 SmartEEE fixup This fixup removes the Lpi_en bit. If this patch breaks functionality of your board, use following device tree properties: qca,smarteee-tw-us-1g and qca,smarteee-tw-us-100m. For example: ethernet-phy@X { reg = <0xX>; qca,smarteee-tw-us-1g = <24>; .... }; Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index d12b571a61ac..c9d7c29d95e1 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -68,32 +68,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup); -static int ar8035_phy_fixup(struct phy_device *dev) -{ - u16 val; - - /* Ar803x phy SmartEEE feature cause link status generates glitch, - * which cause ethernet link down/up issue, so disable SmartEEE - */ - phy_write(dev, 0xd, 0x3); - phy_write(dev, 0xe, 0x805d); - phy_write(dev, 0xd, 0x4003); - - val = phy_read(dev, 0xe); - phy_write(dev, 0xe, val & ~(1 << 8)); - - return 0; -} - -#define PHY_ID_AR8035 0x004dd072 - static void __init imx6q_enet_phy_init(void) { if (IS_BUILTIN(CONFIG_PHYLIB)) { phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, ksz9021rn_phy_fixup); - phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef, - ar8035_phy_fixup); } } -- cgit From d500c6c42bed524b616d6f99efcb37f6a36ba4be Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:34 +0200 Subject: ARM: imx6sx: remove Atheros AR8031 PHY fixup If this patch breaks your system, enable AT803X_PHY driver and add a PHY node to the board device tree: phy-connection-type = "rgmii-txid"; (or rgmii-id) ethernet-phy@X { reg = <0xX>; qca,clk-out-frequency = <125000000>; vddio-supply = <&vddh>; vddio: vddio-regulator { regulator-name = "VDDIO"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; vddh: vddh-regulator { regulator-name = "VDDH"; }; }; Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6sx.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c index 781e2a94fdd7..e65ed5218f53 100644 --- a/arch/arm/mach-imx/mach-imx6sx.c +++ b/arch/arm/mach-imx/mach-imx6sx.c @@ -15,31 +15,6 @@ #include "common.h" #include "cpuidle.h" -static int ar8031_phy_fixup(struct phy_device *dev) -{ - u16 val; - - /* Set RGMII IO voltage to 1.8V */ - phy_write(dev, 0x1d, 0x1f); - phy_write(dev, 0x1e, 0x8); - - /* introduce tx clock delay */ - phy_write(dev, 0x1d, 0x5); - val = phy_read(dev, 0x1e); - val |= 0x0100; - phy_write(dev, 0x1e, val); - - return 0; -} - -#define PHY_ID_AR8031 0x004dd074 -static void __init imx6sx_enet_phy_init(void) -{ - if (IS_BUILTIN(CONFIG_PHYLIB)) - phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff, - ar8031_phy_fixup); -} - static void __init imx6sx_enet_clk_sel(void) { struct regmap *gpr; @@ -57,7 +32,6 @@ static void __init imx6sx_enet_clk_sel(void) static inline void imx6sx_enet_init(void) { - imx6sx_enet_phy_init(); imx6sx_enet_clk_sel(); } -- cgit From 7a4e95d68970d5a3e0e3da45de56e91e1c61a07e Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 11 May 2021 06:37:35 +0200 Subject: ARM: imx7d: remove Atheros AR8031 PHY fixup This fixup configures the IO voltage and disables the SmartEEE functionality. If this patch breaks your system, enable AT803X_PHY driver and configure the PHY by the device tree: phy-connection-type = "rgmii-id"; ethernet-phy@X { reg = <0xX>; qca,smarteee-tw-us-1g = <24>; vddio-supply = <&vddh>; vddio: vddio-regulator { regulator-name = "VDDIO"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; vddh: vddh-regulator { regulator-name = "VDDH"; }; }; Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx7d.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c index 879c35929a13..ccf64ddf8b7e 100644 --- a/arch/arm/mach-imx/mach-imx7d.c +++ b/arch/arm/mach-imx/mach-imx7d.c @@ -14,25 +14,6 @@ #include "common.h" -static int ar8031_phy_fixup(struct phy_device *dev) -{ - u16 val; - - /* Set RGMII IO voltage to 1.8V */ - phy_write(dev, 0x1d, 0x1f); - phy_write(dev, 0x1e, 0x8); - - /* disable phy AR8031 SmartEEE function. */ - phy_write(dev, 0xd, 0x3); - phy_write(dev, 0xe, 0x805d); - phy_write(dev, 0xd, 0x4003); - val = phy_read(dev, 0xe); - val &= ~(0x1 << 8); - phy_write(dev, 0xe, val); - - return 0; -} - static int bcm54220_phy_fixup(struct phy_device *dev) { /* enable RXC skew select RGMII copper mode */ @@ -44,14 +25,11 @@ static int bcm54220_phy_fixup(struct phy_device *dev) return 0; } -#define PHY_ID_AR8031 0x004dd074 #define PHY_ID_BCM54220 0x600d8589 static void __init imx7d_enet_phy_init(void) { if (IS_BUILTIN(CONFIG_PHYLIB)) { - phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff, - ar8031_phy_fixup); phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff, bcm54220_phy_fixup); } -- cgit From cc8870bf4c3ab0af385538460500a9d342ed945f Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 25 May 2021 12:01:08 +0200 Subject: ARM: imx6q: drop of_platform_default_populate() from init_machine Dropping the machine_init specific of_platform_default_populate() can be done safely due to the following two facts: 1) Since commit 44a7185c2ae6 ("of/platform: Add common method to populate default bus") we have a common method to populate the devices. 2) The machine_init code don't need bounded devices<>drivers since the code uses syscon_regmap_lookup_by_compatible() which register a syscon device on demand. Signed-off-by: Marco Felsch Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index c9d7c29d95e1..11dcc369ec14 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -172,9 +172,6 @@ static void __init imx6q_init_machine(void) imx_get_soc_revision()); imx6q_enet_phy_init(); - - of_platform_default_populate(NULL, NULL, NULL); - imx_anatop_init(); cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init(); imx6q_1588_init(); -- cgit From e34645f45805d8308866de7b69f117f554605bb6 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 25 May 2021 21:14:16 -0300 Subject: ARM: imx: add smp support for imx7d Add SMP support for i.MX7D, including CPU hotplug support, for systems where TFA is not present. The motivation for bringing up the second i.MX7D core inside the kernel is that legacy vendor bootloaders usually do not implement PSCI support. This is a significant blocker for systems in the field that are running old bootloader versions to upgrade to a modern mainline kernel version, as only one CPU of the i.MX7D would be brought up. Bring up the second i.MX7D core inside the kernel to make the migration path to mainline kernel easier for the existing iMX7D users. Signed-off-by: Anson Huang Signed-off-by: Arulpandiyan Vadivel # Fix merge conflicts Signed-off-by: Leonard Crestez Signed-off-by: Marek Vasut # heavy cleanup Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/common.h | 3 ++ arch/arm/mach-imx/headsmp.S | 9 ++++ arch/arm/mach-imx/hotplug.c | 3 ++ arch/arm/mach-imx/mach-imx7d.c | 3 +- arch/arm/mach-imx/platsmp.c | 26 +++++++++++ arch/arm/mach-imx/src.c | 101 +++++++++++++++++++++++++++++++++++++---- 7 files changed, 136 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 9cebd360d58e..d1506ef7a537 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -35,7 +35,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o obj-$(CONFIG_HAVE_IMX_SRC) += src.o -ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),) +ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_IMX7D_CA7)$(CONFIG_SOC_LS1021A),) AFLAGS_headsmp.o :=-Wa,-march=armv7-a obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 474dedb73bc7..f0a073a71401 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -68,11 +68,13 @@ void imx_set_cpu_arg(int cpu, u32 arg); void v7_secondary_startup(void); void imx_scu_map_io(void); void imx_smp_prepare(void); +void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn); #else static inline void imx_scu_map_io(void) {} static inline void imx_smp_prepare(void) {} #endif void imx_src_init(void); +void imx7_src_init(void); void imx_gpc_pre_suspend(bool arm_power_off); void imx_gpc_post_resume(void); void imx_gpc_mask_all(void); @@ -131,6 +133,7 @@ static inline void imx_init_l2cache(void) {} #endif extern const struct smp_operations imx_smp_ops; +extern const struct smp_operations imx7_smp_ops; extern const struct smp_operations ls1021a_smp_ops; #endif diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index 766dbdb2ae27..fcba58be8e79 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -21,6 +21,15 @@ diag_reg_offset: ENTRY(v7_secondary_startup) ARM_BE8(setend be) @ go BE8 if entered LE + mrc p15, 0, r0, c0, c0, 0 + lsl r0, r0, #16 + lsr r0, r0, #20 + /* 0xc07 is cortex A7's ID */ + mov r1, #0xc00 + orr r1, #0x7 + cmp r0, r1 + beq secondary_startup + set_diag_reg b secondary_startup ENDPROC(v7_secondary_startup) diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 82e22398d43d..e24a46dc5703 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -11,6 +11,7 @@ #include #include "common.h" +#include "hardware.h" /* * platform-specific code to shutdown a CPU @@ -40,5 +41,7 @@ int imx_cpu_kill(unsigned int cpu) return 0; imx_enable_cpu(cpu, false); imx_set_cpu_arg(cpu, 0); + if (cpu_is_imx7d()) + imx_gpcv2_set_core1_pdn_pup_by_software(true); return 1; } diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c index ccf64ddf8b7e..6fdd06bcf988 100644 --- a/arch/arm/mach-imx/mach-imx7d.c +++ b/arch/arm/mach-imx/mach-imx7d.c @@ -69,7 +69,7 @@ static void __init imx7d_init_late(void) static void __init imx7d_init_irq(void) { imx_init_revision_from_anatop(); - imx_src_init(); + imx7_src_init(); irqchip_init(); } @@ -80,6 +80,7 @@ static const char *const imx7d_dt_compat[] __initconst = { }; DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)") + .smp = smp_ops(imx7_smp_ops), .init_irq = imx7d_init_irq, .init_machine = imx7d_init_machine, .init_late = imx7d_init_late, diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index cf4e9335831c..972639038be5 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -92,6 +92,32 @@ const struct smp_operations imx_smp_ops __initconst = { #endif }; +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +static void __init imx7_smp_init_cpus(void) +{ + struct device_node *np; + int i, ncores = 0; + + /* The iMX7D SCU does not report core count, get it from DT */ + for_each_of_cpu_node(np) + ncores++; + + for (i = ncores; i < NR_CPUS; i++) + set_cpu_possible(i, false); +} + +const struct smp_operations imx7_smp_ops __initconst = { + .smp_init_cpus = imx7_smp_init_cpus, + .smp_boot_secondary = imx_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = imx_cpu_die, + .cpu_kill = imx_cpu_kill, +#endif +}; + #define DCFG_CCSR_SCRATCHRW1 0x200 static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle) diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index f52f371292ac..95fd1fbb0826 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -6,15 +6,19 @@ #include #include +#include #include #include #include #include #include #include "common.h" +#include "hardware.h" #define SRC_SCR 0x000 -#define SRC_GPR1 0x020 +#define SRC_GPR1_V1 0x020 +#define SRC_GPR1_V2 0x074 +#define SRC_GPR1(gpr_v2) ((gpr_v2) ? SRC_GPR1_V2 : SRC_GPR1_V1) #define BP_SRC_SCR_WARM_RESET_ENABLE 0 #define BP_SRC_SCR_SW_GPU_RST 1 #define BP_SRC_SCR_SW_VPU_RST 2 @@ -23,9 +27,18 @@ #define BP_SRC_SCR_SW_IPU2_RST 12 #define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_ENABLE 22 +/* below is for i.MX7D */ +#define SRC_A7RCR1 0x008 +#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 +#define GPC_CPU_PGC_SW_PUP_REQ 0xf0 +#define GPC_CPU_PGC_SW_PDN_REQ 0xfc +#define GPC_PGC_C1 0x840 +#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2 static void __iomem *src_base; static DEFINE_SPINLOCK(scr_lock); +static bool gpr_v2; +static void __iomem *gpc_base; static const int sw_reset_bits[5] = { BP_SRC_SCR_SW_GPU_RST, @@ -73,17 +86,64 @@ static struct reset_controller_dev imx_reset_controller = { .nr_resets = ARRAY_SIZE(sw_reset_bits), }; +static void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset) +{ + writel_relaxed(enable, gpc_base + offset); +} + +/* + * The motivation for bringing up the second i.MX7D core inside the kernel + * is that legacy vendor bootloaders usually do not implement PSCI support. + * This is a significant blocker for systems in the field that are running old + * bootloader versions to upgrade to a modern mainline kernel version, as only + * one CPU of the i.MX7D would be brought up. + * Bring up the second i.MX7D core inside the kernel to make the migration + * path to mainline kernel easier for the existing iMX7D users. + */ +void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn) +{ + u32 reg = pdn ? GPC_CPU_PGC_SW_PDN_REQ : GPC_CPU_PGC_SW_PUP_REQ; + u32 val, pup; + int ret; + + imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1); + val = readl_relaxed(gpc_base + reg); + val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7; + writel_relaxed(val, gpc_base + reg); + + ret = readl_relaxed_poll_timeout_atomic(gpc_base + reg, pup, + !(pup & BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7), + 5, 1000000); + if (ret < 0) { + pr_err("i.MX7D: CORE1_A7 power up timeout\n"); + val &= ~BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7; + writel_relaxed(val, gpc_base + reg); + } + + imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1); +} + void imx_enable_cpu(int cpu, bool enable) { u32 mask, val; cpu = cpu_logical_map(cpu); - mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); spin_lock(&scr_lock); - val = readl_relaxed(src_base + SRC_SCR); - val = enable ? val | mask : val & ~mask; - val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1); - writel_relaxed(val, src_base + SRC_SCR); + if (gpr_v2) { + if (enable) + imx_gpcv2_set_core1_pdn_pup_by_software(false); + + mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1); + val = readl_relaxed(src_base + SRC_A7RCR1); + val = enable ? val | mask : val & ~mask; + writel_relaxed(val, src_base + SRC_A7RCR1); + } else { + mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); + val = readl_relaxed(src_base + SRC_SCR); + val = enable ? val | mask : val & ~mask; + val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1); + writel_relaxed(val, src_base + SRC_SCR); + } spin_unlock(&scr_lock); } @@ -91,19 +151,19 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) { cpu = cpu_logical_map(cpu); writel_relaxed(__pa_symbol(jump_addr), - src_base + SRC_GPR1 + cpu * 8); + src_base + SRC_GPR1(gpr_v2) + cpu * 8); } u32 imx_get_cpu_arg(int cpu) { cpu = cpu_logical_map(cpu); - return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); + return readl_relaxed(src_base + SRC_GPR1(gpr_v2) + cpu * 8 + 4); } void imx_set_cpu_arg(int cpu, u32 arg) { cpu = cpu_logical_map(cpu); - writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); + writel_relaxed(arg, src_base + SRC_GPR1(gpr_v2) + cpu * 8 + 4); } void __init imx_src_init(void) @@ -131,3 +191,26 @@ void __init imx_src_init(void) writel_relaxed(val, src_base + SRC_SCR); spin_unlock(&scr_lock); } + +void __init imx7_src_init(void) +{ + struct device_node *np; + + gpr_v2 = true; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-src"); + if (!np) + return; + + src_base = of_iomap(np, 0); + if (!src_base) + return; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-gpc"); + if (!np) + return; + + gpc_base = of_iomap(np, 0); + if (!gpc_base) + return; +} -- cgit