From 3e96dcfb96e80d2f7f1edb6a1ac81b12de996fa8 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Feb 2022 23:32:27 +0100 Subject: ARM: ixp4xx: Delete the Goramo MLR boardfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This board is replaced with the corresponding device tree. Also delete dangling platform data file only used by this boardfile and nothing else. Cc: Krzysztof HaƂasa Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20220211223238.648934-3-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- include/linux/platform_data/wan_ixp4xx_hss.h | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 include/linux/platform_data/wan_ixp4xx_hss.h (limited to 'include') diff --git a/include/linux/platform_data/wan_ixp4xx_hss.h b/include/linux/platform_data/wan_ixp4xx_hss.h deleted file mode 100644 index d525a0feb9e1..000000000000 --- a/include/linux/platform_data/wan_ixp4xx_hss.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PLATFORM_DATA_WAN_IXP4XX_HSS_H -#define __PLATFORM_DATA_WAN_IXP4XX_HSS_H - -#include - -/* Information about built-in HSS (synchronous serial) interfaces */ -struct hss_plat_info { - int (*set_clock)(int port, unsigned int clock_type); - int (*open)(int port, void *pdev, - void (*set_carrier_cb)(void *pdev, int carrier)); - void (*close)(int port, void *pdev); - u8 txreadyq; - u32 timer_freq; -}; - -#endif -- cgit v1.2.3 From b50113cbdd1340c31e85e4cfc5f5e81ce9cbb2aa Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Feb 2022 23:32:31 +0100 Subject: soc: ixp4xx: Add features from regmap helper If we want to read the CFG2 register on the expansion bus and apply the inversion and check for some hardcoded versions this helper comes in handy. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20220211223238.648934-7-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- include/linux/soc/ixp4xx/cpu.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/linux/soc/ixp4xx/cpu.h b/include/linux/soc/ixp4xx/cpu.h index 88bd8de0e803..48c2e241ac83 100644 --- a/include/linux/soc/ixp4xx/cpu.h +++ b/include/linux/soc/ixp4xx/cpu.h @@ -9,6 +9,7 @@ #define __SOC_IXP4XX_CPU_H__ #include +#include #ifdef CONFIG_ARM #include #endif @@ -23,6 +24,9 @@ #define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */ #define IXP46X_PROCESSOR_ID_MASK 0xfffffff0 +/* Feature register in the expansion bus controller */ +#define IXP4XX_EXP_CNFG2 0x2c + /* "fuse" bits of IXP_EXP_CFG2 */ /* All IXP4xx CPUs */ #define IXP4XX_FEATURE_RCOMP (1 << 0) @@ -89,6 +93,22 @@ u32 ixp4xx_read_feature_bits(void); void ixp4xx_write_feature_bits(u32 value); +static inline u32 cpu_ixp4xx_features(struct regmap *rmap) +{ + u32 val; + + regmap_read(rmap, IXP4XX_EXP_CNFG2, &val); + /* For some reason this register is inverted */ + val = ~val; + if (cpu_is_ixp42x_rev_a0()) + return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP | + IXP4XX_FEATURE_AES); + if (cpu_is_ixp42x()) + return val & IXP42X_FEATURE_MASK; + if (cpu_is_ixp43x()) + return val & IXP43X_FEATURE_MASK; + return val & IXP46X_FEATURE_MASK; +} #else #define cpu_is_ixp42x_rev_a0() 0 #define cpu_is_ixp42x() 0 @@ -101,6 +121,10 @@ static inline u32 ixp4xx_read_feature_bits(void) static inline void ixp4xx_write_feature_bits(u32 value) { } +static inline u32 cpu_ixp4xx_features(struct regmap *rmap) +{ + return 0; +} #endif #endif /* _ASM_ARCH_CPU_H */ -- cgit v1.2.3 From 8754a7e61c766fbc533c627b56ff181550dca00e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Feb 2022 23:32:32 +0100 Subject: soc: ixp4xx-npe: Access syscon regs using regmap If we access the syscon (expansion bus config registers) using the syscon regmap instead of relying on direct accessor functions, we do not need to call this static code in the machine (arch/arm/mach-ixp4xx/common.c) which makes things less dependent on custom machine-dependent code. Look up the syscon regmap and handle the error: this will make deferred probe work with relation to the syscon. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20220211223238.648934-8-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- drivers/soc/ixp4xx/Kconfig | 1 + drivers/soc/ixp4xx/ixp4xx-npe.c | 33 ++++++++++++++++++++++++--------- include/linux/soc/ixp4xx/npe.h | 2 ++ 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/drivers/soc/ixp4xx/Kconfig b/drivers/soc/ixp4xx/Kconfig index e3eb19b85fa4..c55f0c9ae513 100644 --- a/drivers/soc/ixp4xx/Kconfig +++ b/drivers/soc/ixp4xx/Kconfig @@ -12,6 +12,7 @@ config IXP4XX_QMGR config IXP4XX_NPE tristate "IXP4xx Network Processor Engine support" select FW_LOADER + select MFD_SYSCON help This driver supports IXP4xx built-in network coprocessors and is automatically selected by Ethernet and HSS drivers. diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c index f490c4ca51f5..613935cb6a48 100644 --- a/drivers/soc/ixp4xx/ixp4xx-npe.c +++ b/drivers/soc/ixp4xx/ixp4xx-npe.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -284,6 +285,7 @@ static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr, static int npe_reset(struct npe *npe) { + u32 reset_bit = (IXP4XX_FEATURE_RESET_NPEA << npe->id); u32 val, ctl, exec_count, ctx_reg2; int i; @@ -380,16 +382,19 @@ static int npe_reset(struct npe *npe) __raw_writel(0, &npe->regs->action_points[3]); __raw_writel(0, &npe->regs->watch_count); - val = ixp4xx_read_feature_bits(); + /* + * We need to work on cached values here because the register + * will read inverted but needs to be written non-inverted. + */ + val = cpu_ixp4xx_features(npe->rmap); /* reset the NPE */ - ixp4xx_write_feature_bits(val & - ~(IXP4XX_FEATURE_RESET_NPEA << npe->id)); + regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val & ~reset_bit); /* deassert reset */ - ixp4xx_write_feature_bits(val | - (IXP4XX_FEATURE_RESET_NPEA << npe->id)); + regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val | reset_bit); + for (i = 0; i < MAX_RETRIES; i++) { - if (ixp4xx_read_feature_bits() & - (IXP4XX_FEATURE_RESET_NPEA << npe->id)) + val = cpu_ixp4xx_features(npe->rmap); + if (val & reset_bit) break; /* NPE is back alive */ udelay(1); } @@ -683,6 +688,14 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct resource *res; + struct regmap *rmap; + u32 val; + + /* This system has only one syscon, so fetch it */ + rmap = syscon_regmap_lookup_by_compatible("syscon"); + if (IS_ERR(rmap)) + return dev_err_probe(dev, PTR_ERR(rmap), + "failed to look up syscon\n"); for (i = 0; i < NPE_COUNT; i++) { struct npe *npe = &npe_tab[i]; @@ -691,8 +704,9 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) if (!res) return -ENODEV; - if (!(ixp4xx_read_feature_bits() & - (IXP4XX_FEATURE_RESET_NPEA << i))) { + val = cpu_ixp4xx_features(rmap); + + if (!(val & (IXP4XX_FEATURE_RESET_NPEA << i))) { dev_info(dev, "NPE%d at %pR not available\n", i, res); continue; /* NPE already disabled or not present */ @@ -700,6 +714,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) npe->regs = devm_ioremap_resource(dev, res); if (IS_ERR(npe->regs)) return PTR_ERR(npe->regs); + npe->rmap = rmap; if (npe_reset(npe)) { dev_info(dev, "NPE%d at %pR does not reset\n", diff --git a/include/linux/soc/ixp4xx/npe.h b/include/linux/soc/ixp4xx/npe.h index 2a91f465d456..9efeac777da1 100644 --- a/include/linux/soc/ixp4xx/npe.h +++ b/include/linux/soc/ixp4xx/npe.h @@ -3,6 +3,7 @@ #define __IXP4XX_NPE_H #include +#include extern const char *npe_names[]; @@ -17,6 +18,7 @@ struct npe_regs { struct npe { struct npe_regs __iomem *regs; + struct regmap *rmap; int id; int valid; }; -- cgit v1.2.3 From c8200f4e7267545a384fb86a4630f76958ab9df6 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Feb 2022 23:32:33 +0100 Subject: net: ixp4xx_eth: Drop platform data support All IXP4xx platforms are converted to device tree, the platform data path is no longer used. Drop the code and custom include, confine the driver in its own file. Depend on OF and remove ifdefs around this, as we are all probing from OF now. Cc: David S. Miller Cc: Jakub Kicinski Cc: netdev@vger.kernel.org Signed-off-by: Linus Walleij Acked-by: Jakub Kicinski Link: https://lore.kernel.org/r/20220211223238.648934-9-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- drivers/net/ethernet/xscale/Kconfig | 4 +- drivers/net/ethernet/xscale/ixp4xx_eth.c | 85 +++++++------------------------- include/linux/platform_data/eth_ixp4xx.h | 21 -------- 3 files changed, 21 insertions(+), 89 deletions(-) delete mode 100644 include/linux/platform_data/eth_ixp4xx.h (limited to 'include') diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig index 0e878fa6e322..b33f64c54b0e 100644 --- a/drivers/net/ethernet/xscale/Kconfig +++ b/drivers/net/ethernet/xscale/Kconfig @@ -20,9 +20,9 @@ if NET_VENDOR_XSCALE config IXP4XX_ETH tristate "Intel IXP4xx Ethernet support" - depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR + depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR && OF select PHYLIB - select OF_MDIO if OF + select OF_MDIO select NET_PTP_CLASSIFY help Say Y here if you want to use built-in Ethernet ports diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index df77a22d1b81..d947955621ee 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,11 @@ #include #include #include +#include + +#define IXP4XX_ETH_NPEA 0x00 +#define IXP4XX_ETH_NPEB 0x10 +#define IXP4XX_ETH_NPEC 0x20 #include "ixp46x_ts.h" @@ -147,6 +151,16 @@ typedef void buffer_t; #define free_buffer_irq kfree #endif +/* Information about built-in Ethernet MAC interfaces */ +struct eth_plat_info { + u8 phy; /* MII PHY ID, 0 - 31 */ + u8 rxq; /* configurable, currently 0 - 31 only */ + u8 txreadyq; + u8 hwaddr[6]; + u8 npe; /* NPE instance used by this interface */ + bool has_mdio; /* If this instance has an MDIO bus */ +}; + struct eth_regs { u32 tx_control[2], __res1[2]; /* 000 */ u32 rx_control[2], __res2[2]; /* 010 */ @@ -1366,7 +1380,6 @@ static const struct net_device_ops ixp4xx_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; -#ifdef CONFIG_OF static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev) { struct device_node *np = dev->of_node; @@ -1417,12 +1430,6 @@ static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev) return plat; } -#else -static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev) -{ - return NULL; -} -#endif static int ixp4xx_eth_probe(struct platform_device *pdev) { @@ -1434,49 +1441,9 @@ static int ixp4xx_eth_probe(struct platform_device *pdev) struct port *port; int err; - if (np) { - plat = ixp4xx_of_get_platdata(dev); - if (!plat) - return -ENODEV; - } else { - plat = dev_get_platdata(dev); - if (!plat) - return -ENODEV; - plat->npe = pdev->id; - switch (plat->npe) { - case IXP4XX_ETH_NPEA: - /* If the MDIO bus is not up yet, defer probe */ - break; - case IXP4XX_ETH_NPEB: - /* On all except IXP43x, NPE-B is used for the MDIO bus. - * If there is no NPE-B in the feature set, bail out, - * else we have the MDIO bus here. - */ - if (!cpu_is_ixp43x()) { - if (!(ixp4xx_read_feature_bits() & - IXP4XX_FEATURE_NPEB_ETH0)) - return -ENODEV; - /* Else register the MDIO bus on NPE-B */ - plat->has_mdio = true; - } - break; - case IXP4XX_ETH_NPEC: - /* IXP43x lacks NPE-B and uses NPE-C for the MDIO bus - * access, if there is no NPE-C, no bus, nothing works, - * so bail out. - */ - if (cpu_is_ixp43x()) { - if (!(ixp4xx_read_feature_bits() & - IXP4XX_FEATURE_NPEC_ETH)) - return -ENODEV; - /* Else register the MDIO bus on NPE-B */ - plat->has_mdio = true; - } - break; - default: - return -ENODEV; - } - } + plat = ixp4xx_of_get_platdata(dev); + if (!plat) + return -ENODEV; if (!(ndev = devm_alloc_etherdev(dev, sizeof(struct port)))) return -ENOMEM; @@ -1530,21 +1497,7 @@ static int ixp4xx_eth_probe(struct platform_device *pdev) __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control); udelay(50); - if (np) { - phydev = of_phy_get_and_connect(ndev, np, ixp4xx_adjust_link); - } else { - phydev = mdiobus_get_phy(mdio_bus, plat->phy); - if (!phydev) { - err = -ENODEV; - dev_err(dev, "could not connect phydev (%d)\n", err); - goto err_free_mem; - } - err = phy_connect_direct(ndev, phydev, ixp4xx_adjust_link, - PHY_INTERFACE_MODE_MII); - if (err) - goto err_free_mem; - - } + phydev = of_phy_get_and_connect(ndev, np, ixp4xx_adjust_link); if (!phydev) { err = -ENODEV; dev_err(dev, "no phydev\n"); diff --git a/include/linux/platform_data/eth_ixp4xx.h b/include/linux/platform_data/eth_ixp4xx.h deleted file mode 100644 index 114b0940729f..000000000000 --- a/include/linux/platform_data/eth_ixp4xx.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PLATFORM_DATA_ETH_IXP4XX -#define __PLATFORM_DATA_ETH_IXP4XX - -#include - -#define IXP4XX_ETH_NPEA 0x00 -#define IXP4XX_ETH_NPEB 0x10 -#define IXP4XX_ETH_NPEC 0x20 - -/* Information about built-in Ethernet MAC interfaces */ -struct eth_plat_info { - u8 phy; /* MII PHY ID, 0 - 31 */ - u8 rxq; /* configurable, currently 0 - 31 only */ - u8 txreadyq; - u8 hwaddr[6]; - u8 npe; /* NPE instance used by this interface */ - bool has_mdio; /* If this instance has an MDIO bus */ -}; - -#endif -- cgit v1.2.3 From 3059dfa52c07a9b6d770e87dc21b68f4295239c5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 11 Feb 2022 23:32:35 +0100 Subject: ARM: ixp4xx: Remove feature bit accessors We switched users of the accessors over to using syscon to inspect the bits, or removed the need for checking them. Delete these accessors. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20220211223238.648934-11-linus.walleij@linaro.org Signed-off-by: Linus Walleij --- arch/arm/mach-ixp4xx/common.c | 21 --------------------- include/linux/soc/ixp4xx/cpu.h | 10 ---------- 2 files changed, 31 deletions(-) (limited to 'include') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 5192cf621f5b..4e51514ace6d 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -43,27 +43,6 @@ #include "irqs.h" -u32 ixp4xx_read_feature_bits(void) -{ - u32 val = ~__raw_readl(IXP4XX_EXP_CFG2); - - if (cpu_is_ixp42x_rev_a0()) - return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP | - IXP4XX_FEATURE_AES); - if (cpu_is_ixp42x()) - return val & IXP42X_FEATURE_MASK; - if (cpu_is_ixp43x()) - return val & IXP43X_FEATURE_MASK; - return val & IXP46X_FEATURE_MASK; -} -EXPORT_SYMBOL(ixp4xx_read_feature_bits); - -void ixp4xx_write_feature_bits(u32 value) -{ - __raw_writel(~value, IXP4XX_EXP_CFG2); -} -EXPORT_SYMBOL(ixp4xx_write_feature_bits); - #define IXP4XX_TIMER_FREQ 66666000 /************************************************************************* diff --git a/include/linux/soc/ixp4xx/cpu.h b/include/linux/soc/ixp4xx/cpu.h index 48c2e241ac83..f526ac33afea 100644 --- a/include/linux/soc/ixp4xx/cpu.h +++ b/include/linux/soc/ixp4xx/cpu.h @@ -90,9 +90,6 @@ IXP43X_PROCESSOR_ID_VALUE) #define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \ IXP46X_PROCESSOR_ID_VALUE) - -u32 ixp4xx_read_feature_bits(void); -void ixp4xx_write_feature_bits(u32 value); static inline u32 cpu_ixp4xx_features(struct regmap *rmap) { u32 val; @@ -114,13 +111,6 @@ static inline u32 cpu_ixp4xx_features(struct regmap *rmap) #define cpu_is_ixp42x() 0 #define cpu_is_ixp43x() 0 #define cpu_is_ixp46x() 0 -static inline u32 ixp4xx_read_feature_bits(void) -{ - return 0; -} -static inline void ixp4xx_write_feature_bits(u32 value) -{ -} static inline u32 cpu_ixp4xx_features(struct regmap *rmap) { return 0; -- cgit v1.2.3 From dc3005703f8cd893d325081c20b400e08377d9bb Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 13 Jan 2022 16:48:51 +0200 Subject: ARM: at91: ddr: remove CONFIG_SOC_SAMA7 dependency Remove CONFIG_SOC_SAMA7 dependency to avoid having #ifdef preprocessor directives in driver code (arch/arm/mach-at91/pm.c). This prepares the code for next commits. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20220113144900.906370-2-claudiu.beznea@microchip.com --- include/soc/at91/sama7-ddr.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h index f6542584ca13..13b47e26cdbe 100644 --- a/include/soc/at91/sama7-ddr.h +++ b/include/soc/at91/sama7-ddr.h @@ -11,8 +11,6 @@ #ifndef __SAMA7_DDR_H__ #define __SAMA7_DDR_H__ -#ifdef CONFIG_SOC_SAMA7 - /* DDR3PHY */ #define DDR3PHY_PIR (0x04) /* DDR3PHY PHY Initialization Register */ #define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */ @@ -75,6 +73,4 @@ #define UDDRC_PCTRL_3 (0x6A0) /* UDDRC Port 3 Control Register */ #define UDDRC_PCTRL_4 (0x750) /* UDDRC Port 4 Control Register */ -#endif /* CONFIG_SOC_SAMA7 */ - #endif /* __SAMA7_DDR_H__ */ -- cgit v1.2.3 From 55614e682a2c9fac12a0f121b43b93ff4915d0e6 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 13 Jan 2022 16:48:52 +0200 Subject: ARM: at91: ddr: align macro definitions Align all macro definitions. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20220113144900.906370-3-claudiu.beznea@microchip.com --- include/soc/at91/sama7-ddr.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h index 13b47e26cdbe..817b360efbb8 100644 --- a/include/soc/at91/sama7-ddr.h +++ b/include/soc/at91/sama7-ddr.h @@ -13,11 +13,11 @@ /* DDR3PHY */ #define DDR3PHY_PIR (0x04) /* DDR3PHY PHY Initialization Register */ -#define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */ +#define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */ #define DDR3PHY_PIR_ITMSRST (1 << 4) /* Interface Timing Module Soft Reset */ -#define DDR3PHY_PIR_DLLLOCK (1 << 2) /* DLL Lock */ +#define DDR3PHY_PIR_DLLLOCK (1 << 2) /* DLL Lock */ #define DDR3PHY_PIR_DLLSRST (1 << 1) /* DLL Soft Rest */ -#define DDR3PHY_PIR_INIT (1 << 0) /* Initialization Trigger */ +#define DDR3PHY_PIR_INIT (1 << 0) /* Initialization Trigger */ #define DDR3PHY_PGCR (0x08) /* DDR3PHY PHY General Configuration Register */ #define DDR3PHY_PGCR_CKDV1 (1 << 13) /* CK# Disable Value */ @@ -65,7 +65,7 @@ #define UDDRC_SWSTAT_SW_DONE_ACK (1 << 0) /* Register programming done */ #define UDDRC_PSTAT (0x3FC) /* UDDRC Port Status Register */ -#define UDDRC_PSTAT_ALL_PORTS (0x1F001F) /* Read + writes outstanding transactions on all ports */ +#define UDDRC_PSTAT_ALL_PORTS (0x1F001F) /* Read + writes outstanding transactions on all ports */ #define UDDRC_PCTRL_0 (0x490) /* UDDRC Port 0 Control Register */ #define UDDRC_PCTRL_1 (0x540) /* UDDRC Port 1 Control Register */ -- cgit v1.2.3 From 9a0775c9cd3d89d1fe957a137131681a33f5736b Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 13 Jan 2022 16:48:53 +0200 Subject: ARM: at91: ddr: fix typo to align with datasheet naming Fix typo on UDDRC_PWRCTL.SELFREF_SW bitmask to align with datasheet naming. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20220113144900.906370-4-claudiu.beznea@microchip.com --- arch/arm/mach-at91/pm_suspend.S | 4 ++-- include/soc/at91/sama7-ddr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index fdb4f63ecde4..abe4ced33eda 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -159,7 +159,7 @@ sr_ena_1: /* Switch to self-refresh. */ ldr tmp1, [r2, #UDDRC_PWRCTL] - orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW + orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW str tmp1, [r2, #UDDRC_PWRCTL] sr_ena_2: @@ -276,7 +276,7 @@ sr_dis_5: /* Trigger self-refresh exit. */ ldr tmp1, [r2, #UDDRC_PWRCTL] - bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW + bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW str tmp1, [r2, #UDDRC_PWRCTL] sr_dis_6: diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h index 817b360efbb8..fee1b11bddca 100644 --- a/include/soc/at91/sama7-ddr.h +++ b/include/soc/at91/sama7-ddr.h @@ -53,7 +53,7 @@ #define UDDRC_STAT_OPMODE_MSK (0x7 << 0) /* Operating mode mask */ #define UDDRC_PWRCTL (0x30) /* UDDRC Low Power Control Register */ -#define UDDRC_PWRCTRL_SELFREF_SW (1 << 5) /* Software self-refresh */ +#define UDDRC_PWRCTL_SELFREF_SW (1 << 5) /* Software self-refresh */ #define UDDRC_DFIMISC (0x1B0) /* UDDRC DFI Miscellaneous Control Register */ #define UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN (1 << 0) /* PHY initialization complete enable signal */ -- cgit v1.2.3 From 9584e7263e9ebcd94b184dc3efc847355a624220 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 13 Jan 2022 16:48:54 +0200 Subject: ARM: at91: PM: add cpu idle support for sama7g5 Add CPU idle support for SAMA7G5. Support will make use of PMC_CPU_RATIO register to divide the CPU clock by 16 before switching it to idle and use automatic self-refresh option of DDR controller. Signed-off-by: Claudiu Beznea Acked-by: Stephen Boyd Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20220113144900.906370-5-claudiu.beznea@microchip.com --- arch/arm/mach-at91/pm.c | 27 ++++++++++++++++++++++++++- include/linux/clk/at91_pmc.h | 4 ++++ include/soc/at91/sama7-ddr.h | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index dd6f4ce3f766..0fd609e26615 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -605,6 +605,30 @@ static void at91sam9_sdram_standby(void) at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); } +static void sama7g5_standby(void) +{ + int pwrtmg, ratio; + + pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL); + ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO); + + /* + * Place RAM into self-refresh after a maximum idle clocks. The maximum + * idle clocks is configured by bootloader in + * UDDRC_PWRMGT.SELFREF_TO_X32. + */ + writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN, + soc_pm.data.ramc[0] + UDDRC_PWRCTL); + /* Divide CPU clock by 16. */ + writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO); + + cpu_do_idle(); + + /* Restore previous configuration. */ + writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO); + writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL); +} + struct ramc_info { void (*idle)(void); unsigned int memctrl; @@ -615,6 +639,7 @@ static const struct ramc_info ramc_infos[] __initconst = { { .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC}, { .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR}, { .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR}, + { .idle = sama7g5_standby, }, }; static const struct of_device_id ramc_ids[] __initconst = { @@ -622,7 +647,7 @@ static const struct of_device_id ramc_ids[] __initconst = { { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] }, { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] }, { .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] }, - { .compatible = "microchip,sama7g5-uddrc", }, + { .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], }, { /*sentinel*/ } }; diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index ccb3f034bfa9..3484309b59bf 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h @@ -78,6 +78,10 @@ #define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ #define AT91_CKGR_PLLAR 0x28 /* PLL A Register */ + +#define AT91_PMC_RATIO 0x2c /* Processor clock ratio register [SAMA7G5 only] */ +#define AT91_PMC_RATIO_RATIO (0xf) /* CPU clock ratio. */ + #define AT91_CKGR_PLLBR 0x2c /* PLL B Register */ #define AT91_PMC_DIV (0xff << 0) /* Divider */ #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h index fee1b11bddca..9e17247474fa 100644 --- a/include/soc/at91/sama7-ddr.h +++ b/include/soc/at91/sama7-ddr.h @@ -53,6 +53,7 @@ #define UDDRC_STAT_OPMODE_MSK (0x7 << 0) /* Operating mode mask */ #define UDDRC_PWRCTL (0x30) /* UDDRC Low Power Control Register */ +#define UDDRC_PWRCTL_SELFREF_EN (1 << 0) /* Automatic self-refresh */ #define UDDRC_PWRCTL_SELFREF_SW (1 << 5) /* Software self-refresh */ #define UDDRC_DFIMISC (0x1B0) /* UDDRC DFI Miscellaneous Control Register */ -- cgit v1.2.3 From d0054a470c33902f5ae88835ed8a8ecc3cf8faa4 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Thu, 17 Feb 2022 10:13:50 +0000 Subject: soc: add microchip polarfire soc system controller This driver provides an interface for other drivers to access the functions of the system controller on the Microchip PolarFire SoC. Signed-off-by: Conor Dooley Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20220217101349.2374873-2-conor.dooley@microchip.com --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/microchip/Kconfig | 10 ++ drivers/soc/microchip/Makefile | 1 + drivers/soc/microchip/mpfs-sys-controller.c | 194 ++++++++++++++++++++++++++++ include/soc/microchip/mpfs.h | 4 +- 6 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 drivers/soc/microchip/Kconfig create mode 100644 drivers/soc/microchip/Makefile create mode 100644 drivers/soc/microchip/mpfs-sys-controller.c (limited to 'include') diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index a8562678c437..c5aae42673d3 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -13,6 +13,7 @@ source "drivers/soc/imx/Kconfig" source "drivers/soc/ixp4xx/Kconfig" source "drivers/soc/litex/Kconfig" source "drivers/soc/mediatek/Kconfig" +source "drivers/soc/microchip/Kconfig" source "drivers/soc/qcom/Kconfig" source "drivers/soc/renesas/Kconfig" source "drivers/soc/rockchip/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index adb30c2d4fea..904eec2a7871 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -18,6 +18,7 @@ obj-y += ixp4xx/ obj-$(CONFIG_SOC_XWAY) += lantiq/ obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/ obj-y += mediatek/ +obj-y += microchip/ obj-y += amlogic/ obj-y += qcom/ obj-y += renesas/ diff --git a/drivers/soc/microchip/Kconfig b/drivers/soc/microchip/Kconfig new file mode 100644 index 000000000000..eb656b33156b --- /dev/null +++ b/drivers/soc/microchip/Kconfig @@ -0,0 +1,10 @@ +config POLARFIRE_SOC_SYS_CTRL + tristate "POLARFIRE_SOC_SYS_CTRL" + depends on POLARFIRE_SOC_MAILBOX + help + This driver adds support for the PolarFire SoC (MPFS) system controller. + + To compile this driver as a module, choose M here. the + module will be called mpfs_system_controller. + + If unsure, say N. diff --git a/drivers/soc/microchip/Makefile b/drivers/soc/microchip/Makefile new file mode 100644 index 000000000000..14489919fe4b --- /dev/null +++ b/drivers/soc/microchip/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_POLARFIRE_SOC_SYS_CTRL) += mpfs-sys-controller.o diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c new file mode 100644 index 000000000000..2f4535929762 --- /dev/null +++ b/drivers/soc/microchip/mpfs-sys-controller.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Microchip PolarFire SoC (MPFS) system controller driver + * + * Copyright (c) 2020-2021 Microchip Corporation. All rights reserved. + * + * Author: Conor Dooley + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(transaction_lock); + +struct mpfs_sys_controller { + struct mbox_client client; + struct mbox_chan *chan; + struct completion c; + struct kref consumers; +}; + +int mpfs_blocking_transaction(struct mpfs_sys_controller *sys_controller, struct mpfs_mss_msg *msg) +{ + int ret, err; + + err = mutex_lock_interruptible(&transaction_lock); + if (err) + return err; + + reinit_completion(&sys_controller->c); + + ret = mbox_send_message(sys_controller->chan, msg); + if (ret >= 0) { + if (wait_for_completion_timeout(&sys_controller->c, HZ)) { + ret = 0; + } else { + ret = -ETIMEDOUT; + dev_warn(sys_controller->client.dev, + "MPFS sys controller transaction timeout\n"); + } + } else { + dev_err(sys_controller->client.dev, + "mpfs sys controller transaction returned %d\n", ret); + } + + mutex_unlock(&transaction_lock); + + return ret; +} +EXPORT_SYMBOL(mpfs_blocking_transaction); + +static void rx_callback(struct mbox_client *client, void *msg) +{ + struct mpfs_sys_controller *sys_controller = + container_of(client, struct mpfs_sys_controller, client); + + complete(&sys_controller->c); +} + +static void mpfs_sys_controller_delete(struct kref *kref) +{ + struct mpfs_sys_controller *sys_controller = container_of(kref, struct mpfs_sys_controller, + consumers); + + mbox_free_channel(sys_controller->chan); + kfree(sys_controller); +} + +void mpfs_sys_controller_put(void *data) +{ + struct mpfs_sys_controller *sys_controller = data; + + kref_put(&sys_controller->consumers, mpfs_sys_controller_delete); +} +EXPORT_SYMBOL(mpfs_sys_controller_put); + +static struct platform_device subdevs[] = { + { + .name = "mpfs-rng", + .id = -1, + }, + { + .name = "mpfs-generic-service", + .id = -1, + } +}; + +static int mpfs_sys_controller_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mpfs_sys_controller *sys_controller; + int i; + + sys_controller = devm_kzalloc(dev, sizeof(*sys_controller), GFP_KERNEL); + if (!sys_controller) + return -ENOMEM; + + sys_controller->client.dev = dev; + sys_controller->client.rx_callback = rx_callback; + sys_controller->client.tx_block = 1U; + + sys_controller->chan = mbox_request_channel(&sys_controller->client, 0); + if (IS_ERR(sys_controller->chan)) + return dev_err_probe(dev, PTR_ERR(sys_controller->chan), + "Failed to get mbox channel\n"); + + init_completion(&sys_controller->c); + kref_init(&sys_controller->consumers); + + platform_set_drvdata(pdev, sys_controller); + + dev_info(&pdev->dev, "Registered MPFS system controller\n"); + + for (i = 0; i < ARRAY_SIZE(subdevs); i++) { + subdevs[i].dev.parent = dev; + if (platform_device_register(&subdevs[i])) + dev_warn(dev, "Error registering sub device %s\n", subdevs[i].name); + } + + return 0; +} + +static int mpfs_sys_controller_remove(struct platform_device *pdev) +{ + struct mpfs_sys_controller *sys_controller = platform_get_drvdata(pdev); + + mpfs_sys_controller_put(sys_controller); + + return 0; +} + +static const struct of_device_id mpfs_sys_controller_of_match[] = { + {.compatible = "microchip,mpfs-sys-controller", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mpfs_sys_controller_of_match); + +struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev) +{ + const struct of_device_id *match; + struct mpfs_sys_controller *sys_controller; + int ret; + + if (!dev->parent) + goto err_no_device; + + match = of_match_node(mpfs_sys_controller_of_match, dev->parent->of_node); + of_node_put(dev->parent->of_node); + if (!match) + goto err_no_device; + + sys_controller = dev_get_drvdata(dev->parent); + if (!sys_controller) + goto err_bad_device; + + if (!kref_get_unless_zero(&sys_controller->consumers)) + goto err_bad_device; + + ret = devm_add_action_or_reset(dev, mpfs_sys_controller_put, sys_controller); + if (ret) + return ERR_PTR(ret); + + return sys_controller; + +err_no_device: + dev_dbg(dev, "Parent device was not an MPFS system controller\n"); + return ERR_PTR(-ENODEV); + +err_bad_device: + dev_dbg(dev, "MPFS system controller found but could not register as a sub device\n"); + return ERR_PTR(-EPROBE_DEFER); +} +EXPORT_SYMBOL(mpfs_sys_controller_get); + +static struct platform_driver mpfs_sys_controller_driver = { + .driver = { + .name = "mpfs-sys-controller", + .of_match_table = mpfs_sys_controller_of_match, + }, + .probe = mpfs_sys_controller_probe, + .remove = mpfs_sys_controller_remove, +}; +module_platform_driver(mpfs_sys_controller_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Conor Dooley "); +MODULE_DESCRIPTION("MPFS system controller driver"); diff --git a/include/soc/microchip/mpfs.h b/include/soc/microchip/mpfs.h index 2b64c95f3be5..6466515262bd 100644 --- a/include/soc/microchip/mpfs.h +++ b/include/soc/microchip/mpfs.h @@ -34,9 +34,9 @@ struct mpfs_mss_response { #if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) -int mpfs_blocking_transaction(struct mpfs_sys_controller *mpfs_client, void *msg); +int mpfs_blocking_transaction(struct mpfs_sys_controller *mpfs_client, struct mpfs_mss_msg *msg); -struct mpfs_sys_controller *mpfs_sys_controller_get(struct device_node *mailbox_node); +struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev); #endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */ -- cgit v1.2.3