All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikita Shubin via B4 Relay  <devnull+nikita.shubin.maquefel.me@kernel.org>
To: "Arnd Bergmann" <arnd@arndb.de>,
	"Conor Dooley" <conor.dooley@microchip.com>,
	"Joel Stanley" <joel@jms.id.au>,
	"Alexander Sverdlin" <alexander.sverdlin@gmail.com>,
	"Paul Menzel" <pmenzel@molgen.mpg.de>,
	"Yinbo Zhu" <zhuyinbo@loongson.cn>,
	"Jonathan Neuschäfer" <j.neuschaefer@gmx.net>,
	"Nikita Shubin" <nikita.shubin@maquefel.me>,
	"Walker Chen" <walker.chen@starfivetech.com>,
	"Emil Renner Berthing" <kernel@esmil.dk>,
	"Linus Walleij" <linus.walleij@linaro.org>,
	"Thierry Reding" <thierry.reding@gmail.com>,
	"Sergey Shtylyov" <s.shtylyov@omp.ru>,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: Damien Le Moal <dlemoal@kernel.org>,
	linux-kernel@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
	Alexander Sverdlin <alexander.sverdlin@gmail.com>
Subject: [PATCH v4 10/42] soc: Add SoC driver for Cirrus ep93xx
Date: Fri, 15 Sep 2023 11:10:52 +0300	[thread overview]
Message-ID: <20230915-ep93xx-v4-10-a1d779dcec10@maquefel.me> (raw)
In-Reply-To: <20230915-ep93xx-v4-0-a1d779dcec10@maquefel.me>

From: Nikita Shubin <nikita.shubin@maquefel.me>

Add an SoC driver for the ep93xx. Currently there is only one thing
not fitting into any other framework, and that is the swlock setting.

Used for clock settings, pinctrl and restart.

Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/soc/Kconfig               |   1 +
 drivers/soc/Makefile              |   1 +
 drivers/soc/cirrus/Kconfig        |  12 +++
 drivers/soc/cirrus/Makefile       |   2 +
 drivers/soc/cirrus/soc-ep93xx.c   | 215 ++++++++++++++++++++++++++++++++++++++
 include/linux/soc/cirrus/ep93xx.h |  11 +-
 6 files changed, 240 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 4e176280113a..16327b63b773 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -8,6 +8,7 @@ source "drivers/soc/aspeed/Kconfig"
 source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/canaan/Kconfig"
+source "drivers/soc/cirrus/Kconfig"
 source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 3b0f9fb3b5c8..b76a03fe808e 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -9,6 +9,7 @@ obj-y				+= aspeed/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
 obj-y				+= bcm/
 obj-$(CONFIG_SOC_CANAAN)	+= canaan/
+obj-$(CONFIG_EP93XX_SOC)        += cirrus/
 obj-$(CONFIG_ARCH_DOVE)		+= dove/
 obj-$(CONFIG_MACH_DOVE)		+= dove/
 obj-y				+= fsl/
diff --git a/drivers/soc/cirrus/Kconfig b/drivers/soc/cirrus/Kconfig
new file mode 100644
index 000000000000..408f3343a265
--- /dev/null
+++ b/drivers/soc/cirrus/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_EP93XX
+
+config EP93XX_SOC
+	bool "Cirrus EP93xx chips SoC"
+	select SOC_BUS
+	default y if !EP93XX_SOC_COMMON
+	help
+	  Support SoC for Cirrus EP93xx chips.
+
+endif
diff --git a/drivers/soc/cirrus/Makefile b/drivers/soc/cirrus/Makefile
new file mode 100644
index 000000000000..ed6752844c6f
--- /dev/null
+++ b/drivers/soc/cirrus/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y	+= soc-ep93xx.o
diff --git a/drivers/soc/cirrus/soc-ep93xx.c b/drivers/soc/cirrus/soc-ep93xx.c
new file mode 100644
index 000000000000..b8b23ee56f9f
--- /dev/null
+++ b/drivers/soc/cirrus/soc-ep93xx.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SoC driver for Cirrus EP93xx chips.
+ * Copyright (C) 2022 Nikita Shubin <nikita.shubin@maquefel.me>
+ *
+ * Based on a rewrite of arch/arm/mach-ep93xx/core.c
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * Thanks go to Michael Burian and Ray Lehtiniemi for their key
+ * role in the ep93xx Linux community
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/soc/cirrus/ep93xx.h>
+
+#define EP93XX_EXT_CLK_RATE		14745600
+
+#define EP93XX_SYSCON_DEVCFG		0x80
+
+#define EP93XX_SWLOCK_MAGICK		0xaa
+#define EP93XX_SYSCON_SWLOCK		0xc0
+#define EP93XX_SYSCON_SYSCFG		0x9c
+#define EP93XX_SYSCON_SYSCFG_REV_MASK	GENMASK(31, 28)
+#define EP93XX_SYSCON_SYSCFG_REV_SHIFT	28
+
+#define EP93XX_SYSCON_CLKSET1		0x20
+#define EP93XX_SYSCON_CLKSET1_NBYP1	BIT(23)
+#define EP93XX_SYSCON_CLKSET2		0x24
+#define EP93XX_SYSCON_CLKSET2_NBYP2	BIT(19)
+#define EP93XX_SYSCON_CLKSET2_PLL2_EN	BIT(18)
+
+static DEFINE_SPINLOCK(ep93xx_swlock);
+
+/*
+ * EP93xx System Controller software locked register write
+ *
+ * Logic safeguards are included to condition the control signals for
+ * power connection to the matrix to prevent part damage. In addition, a
+ * software lock register is included that must be written with 0xAA
+ * before each register write to change the values of the four switch
+ * matrix control registers.
+ */
+void ep93xx_regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep93xx_swlock, flags);
+
+	regmap_write(map, EP93XX_SYSCON_SWLOCK, EP93XX_SWLOCK_MAGICK);
+	regmap_write(map, reg, val);
+
+	spin_unlock_irqrestore(&ep93xx_swlock, flags);
+}
+
+void ep93xx_regmap_update_bits(struct regmap *map, unsigned int reg,
+			       unsigned int mask, unsigned int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep93xx_swlock, flags);
+
+	regmap_write(map, EP93XX_SYSCON_SWLOCK, EP93XX_SWLOCK_MAGICK);
+	/* force write is required to clear swlock if is no changes are made */
+	regmap_update_bits_base(map, reg, mask, val, NULL, false, true);
+
+	spin_unlock_irqrestore(&ep93xx_swlock, flags);
+}
+
+static unsigned int __init ep93xx_soc_revision(struct regmap *map)
+{
+	unsigned int val;
+
+	regmap_read(map, EP93XX_SYSCON_SYSCFG, &val);
+	val &= EP93XX_SYSCON_SYSCFG_REV_MASK;
+	val >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
+	return val;
+}
+
+static const char __init *ep93xx_get_soc_rev(struct regmap *map)
+{
+	switch (ep93xx_soc_revision(map)) {
+	case EP93XX_CHIP_REV_D0:
+		return "D0";
+	case EP93XX_CHIP_REV_D1:
+		return "D1";
+	case EP93XX_CHIP_REV_E0:
+		return "E0";
+	case EP93XX_CHIP_REV_E1:
+		return "E1";
+	case EP93XX_CHIP_REV_E2:
+		return "E2";
+	default:
+		return "unknown";
+	}
+}
+
+/*
+ * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
+ */
+static unsigned long __init calc_pll_rate(u64 rate, u32 config_word)
+{
+	rate *= ((config_word >> 11) & GENMASK(4, 0)) + 1;	/* X1FBD */
+	rate *= ((config_word >> 5) & GENMASK(5, 0)) + 1;	/* X2FBD */
+	do_div(rate, (config_word & GENMASK(4, 0)) + 1);	/* X2IPD */
+	rate >>= ((config_word >> 16) & GENMASK(1, 0));		/* PS */
+
+	return rate;
+}
+
+static int __init ep93xx_syscon_probe(struct platform_device *pdev)
+{
+	unsigned int clk_f_div, clk_h_div, clk_p_div, clk_usb_div;
+	const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+	const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+	const char pclk_divisors[] = { 1, 2, 4, 8 };
+	unsigned long clk_pll1_rate, clk_pll2_rate;
+	struct soc_device_attribute *attrs;
+	struct soc_device *soc_dev;
+	struct device *dev = &pdev->dev;
+	struct regmap *map;
+	struct clk_hw *hw;
+	u32 value;
+
+	map = device_node_to_regmap(dev->of_node);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+
+	/* Determine the bootloader configured pll1 rate */
+	regmap_read(map, EP93XX_SYSCON_CLKSET1, &value);
+
+	if (value & EP93XX_SYSCON_CLKSET1_NBYP1)
+		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
+	else
+		clk_pll1_rate = EP93XX_EXT_CLK_RATE;
+
+	hw = clk_hw_register_fixed_rate(dev, "pll1", "xtali", 0, clk_pll1_rate);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	/* Initialize the pll1 derived clocks */
+	clk_f_div = fclk_divisors[(value >> 25) & GENMASK(2, 0)];
+	clk_h_div = hclk_divisors[(value >> 20) & GENMASK(2, 0)];
+	clk_p_div = pclk_divisors[(value >> 18) & GENMASK(1, 0)];
+
+	hw = clk_hw_register_fixed_factor(dev, "fclk", "pll1", 0, 1, clk_f_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	hw = clk_hw_register_fixed_factor(dev, "hclk", "pll1", 0, 1, clk_h_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	hw = clk_hw_register_fixed_factor(dev, "pclk", "hclk", 0, 1, clk_p_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	/* Determine the bootloader configured pll2 rate */
+	regmap_read(map, EP93XX_SYSCON_CLKSET2, &value);
+	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
+		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
+	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
+		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
+	else
+		clk_pll2_rate = 0;
+
+	hw = clk_hw_register_fixed_rate(dev, "pll2", "xtali", 0, clk_pll2_rate);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	regmap_read(map, EP93XX_SYSCON_CLKSET2, &value);
+	clk_usb_div = (((value >> 28) & GENMASK(3, 0)) + 1);
+	hw = clk_hw_register_fixed_factor(dev, "usb_clk", "pll2", 0, 1, clk_usb_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	attrs = devm_kzalloc(dev, sizeof(*attrs), GFP_KERNEL);
+	if (!attrs)
+		return -ENOMEM;
+
+	attrs->machine = of_flat_dt_get_machine_name();
+	attrs->family = "Cirrus Logic EP93xx";
+	attrs->revision = ep93xx_get_soc_rev(map);
+
+	soc_dev = soc_device_register(attrs);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	dev_info(dev, "EP93xx SoC revision %s\n", attrs->revision);
+
+	return 0;
+}
+
+static const struct of_device_id ep9301_syscon_of_device_ids[] = {
+	{ .compatible	= "cirrus,ep9301-syscon" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver ep9301_syscon_driver = {
+	.driver = {
+		.name = "ep9301-syscon",
+		.of_match_table = ep9301_syscon_of_device_ids,
+	},
+};
+builtin_platform_driver_probe(ep9301_syscon_driver, ep93xx_syscon_probe);
diff --git a/include/linux/soc/cirrus/ep93xx.h b/include/linux/soc/cirrus/ep93xx.h
index 8b4b8221ed4c..267529ee2b3d 100644
--- a/include/linux/soc/cirrus/ep93xx.h
+++ b/include/linux/soc/cirrus/ep93xx.h
@@ -11,7 +11,7 @@ struct regmap;
 #define EP93XX_CHIP_REV_E1	6
 #define EP93XX_CHIP_REV_E2	7
 
-#ifdef CONFIG_ARCH_EP93XX
+#if defined(CONFIG_EP93XX_SOC_COMMON)
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
 void ep93xx_pwm_release_gpio(struct platform_device *pdev);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
@@ -33,11 +33,18 @@ static inline int ep93xx_i2s_acquire(void) { return 0; }
 static inline void ep93xx_i2s_release(void) {}
 static inline unsigned int ep93xx_chip_revision(void) { return 0; }
 
-#endif
+#if defined(CONFIG_EP93XX_SOC)
+void ep93xx_regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
+void ep93xx_regmap_update_bits(struct regmap *map, unsigned int reg,
+			       unsigned int mask, unsigned int val);
 
+#else
 static inline void ep93xx_regmap_write(struct regmap *map, unsigned int reg, unsigned int val) {}
 static inline void ep93xx_regmap_update_bits(struct regmap *map, unsigned int reg,
 					     unsigned int mask, unsigned int val)
 { }
 
 #endif
+#endif
+
+#endif

-- 
2.39.2


WARNING: multiple messages have this Message-ID (diff)
From: Nikita Shubin <nikita.shubin@maquefel.me>
To: "Arnd Bergmann" <arnd@arndb.de>,
	"Conor Dooley" <conor.dooley@microchip.com>,
	"Joel Stanley" <joel@jms.id.au>,
	"Alexander Sverdlin" <alexander.sverdlin@gmail.com>,
	"Paul Menzel" <pmenzel@molgen.mpg.de>,
	"Yinbo Zhu" <zhuyinbo@loongson.cn>,
	"Jonathan Neuschäfer" <j.neuschaefer@gmx.net>,
	"Nikita Shubin" <nikita.shubin@maquefel.me>,
	"Walker Chen" <walker.chen@starfivetech.com>,
	"Emil Renner Berthing" <kernel@esmil.dk>,
	"Linus Walleij" <linus.walleij@linaro.org>,
	"Thierry Reding" <thierry.reding@gmail.com>,
	"Sergey Shtylyov" <s.shtylyov@omp.ru>,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: Damien Le Moal <dlemoal@kernel.org>,
	linux-kernel@vger.kernel.org,  Arnd Bergmann <arnd@arndb.de>,
	 Alexander Sverdlin <alexander.sverdlin@gmail.com>
Subject: [PATCH v4 10/42] soc: Add SoC driver for Cirrus ep93xx
Date: Fri, 15 Sep 2023 11:10:52 +0300	[thread overview]
Message-ID: <20230915-ep93xx-v4-10-a1d779dcec10@maquefel.me> (raw)
In-Reply-To: <20230915-ep93xx-v4-0-a1d779dcec10@maquefel.me>

Add an SoC driver for the ep93xx. Currently there is only one thing
not fitting into any other framework, and that is the swlock setting.

Used for clock settings, pinctrl and restart.

Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/soc/Kconfig               |   1 +
 drivers/soc/Makefile              |   1 +
 drivers/soc/cirrus/Kconfig        |  12 +++
 drivers/soc/cirrus/Makefile       |   2 +
 drivers/soc/cirrus/soc-ep93xx.c   | 215 ++++++++++++++++++++++++++++++++++++++
 include/linux/soc/cirrus/ep93xx.h |  11 +-
 6 files changed, 240 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 4e176280113a..16327b63b773 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -8,6 +8,7 @@ source "drivers/soc/aspeed/Kconfig"
 source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/canaan/Kconfig"
+source "drivers/soc/cirrus/Kconfig"
 source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/fujitsu/Kconfig"
 source "drivers/soc/imx/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 3b0f9fb3b5c8..b76a03fe808e 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -9,6 +9,7 @@ obj-y				+= aspeed/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
 obj-y				+= bcm/
 obj-$(CONFIG_SOC_CANAAN)	+= canaan/
+obj-$(CONFIG_EP93XX_SOC)        += cirrus/
 obj-$(CONFIG_ARCH_DOVE)		+= dove/
 obj-$(CONFIG_MACH_DOVE)		+= dove/
 obj-y				+= fsl/
diff --git a/drivers/soc/cirrus/Kconfig b/drivers/soc/cirrus/Kconfig
new file mode 100644
index 000000000000..408f3343a265
--- /dev/null
+++ b/drivers/soc/cirrus/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_EP93XX
+
+config EP93XX_SOC
+	bool "Cirrus EP93xx chips SoC"
+	select SOC_BUS
+	default y if !EP93XX_SOC_COMMON
+	help
+	  Support SoC for Cirrus EP93xx chips.
+
+endif
diff --git a/drivers/soc/cirrus/Makefile b/drivers/soc/cirrus/Makefile
new file mode 100644
index 000000000000..ed6752844c6f
--- /dev/null
+++ b/drivers/soc/cirrus/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y	+= soc-ep93xx.o
diff --git a/drivers/soc/cirrus/soc-ep93xx.c b/drivers/soc/cirrus/soc-ep93xx.c
new file mode 100644
index 000000000000..b8b23ee56f9f
--- /dev/null
+++ b/drivers/soc/cirrus/soc-ep93xx.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SoC driver for Cirrus EP93xx chips.
+ * Copyright (C) 2022 Nikita Shubin <nikita.shubin@maquefel.me>
+ *
+ * Based on a rewrite of arch/arm/mach-ep93xx/core.c
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * Thanks go to Michael Burian and Ray Lehtiniemi for their key
+ * role in the ep93xx Linux community
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/soc/cirrus/ep93xx.h>
+
+#define EP93XX_EXT_CLK_RATE		14745600
+
+#define EP93XX_SYSCON_DEVCFG		0x80
+
+#define EP93XX_SWLOCK_MAGICK		0xaa
+#define EP93XX_SYSCON_SWLOCK		0xc0
+#define EP93XX_SYSCON_SYSCFG		0x9c
+#define EP93XX_SYSCON_SYSCFG_REV_MASK	GENMASK(31, 28)
+#define EP93XX_SYSCON_SYSCFG_REV_SHIFT	28
+
+#define EP93XX_SYSCON_CLKSET1		0x20
+#define EP93XX_SYSCON_CLKSET1_NBYP1	BIT(23)
+#define EP93XX_SYSCON_CLKSET2		0x24
+#define EP93XX_SYSCON_CLKSET2_NBYP2	BIT(19)
+#define EP93XX_SYSCON_CLKSET2_PLL2_EN	BIT(18)
+
+static DEFINE_SPINLOCK(ep93xx_swlock);
+
+/*
+ * EP93xx System Controller software locked register write
+ *
+ * Logic safeguards are included to condition the control signals for
+ * power connection to the matrix to prevent part damage. In addition, a
+ * software lock register is included that must be written with 0xAA
+ * before each register write to change the values of the four switch
+ * matrix control registers.
+ */
+void ep93xx_regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep93xx_swlock, flags);
+
+	regmap_write(map, EP93XX_SYSCON_SWLOCK, EP93XX_SWLOCK_MAGICK);
+	regmap_write(map, reg, val);
+
+	spin_unlock_irqrestore(&ep93xx_swlock, flags);
+}
+
+void ep93xx_regmap_update_bits(struct regmap *map, unsigned int reg,
+			       unsigned int mask, unsigned int val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep93xx_swlock, flags);
+
+	regmap_write(map, EP93XX_SYSCON_SWLOCK, EP93XX_SWLOCK_MAGICK);
+	/* force write is required to clear swlock if is no changes are made */
+	regmap_update_bits_base(map, reg, mask, val, NULL, false, true);
+
+	spin_unlock_irqrestore(&ep93xx_swlock, flags);
+}
+
+static unsigned int __init ep93xx_soc_revision(struct regmap *map)
+{
+	unsigned int val;
+
+	regmap_read(map, EP93XX_SYSCON_SYSCFG, &val);
+	val &= EP93XX_SYSCON_SYSCFG_REV_MASK;
+	val >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
+	return val;
+}
+
+static const char __init *ep93xx_get_soc_rev(struct regmap *map)
+{
+	switch (ep93xx_soc_revision(map)) {
+	case EP93XX_CHIP_REV_D0:
+		return "D0";
+	case EP93XX_CHIP_REV_D1:
+		return "D1";
+	case EP93XX_CHIP_REV_E0:
+		return "E0";
+	case EP93XX_CHIP_REV_E1:
+		return "E1";
+	case EP93XX_CHIP_REV_E2:
+		return "E2";
+	default:
+		return "unknown";
+	}
+}
+
+/*
+ * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
+ */
+static unsigned long __init calc_pll_rate(u64 rate, u32 config_word)
+{
+	rate *= ((config_word >> 11) & GENMASK(4, 0)) + 1;	/* X1FBD */
+	rate *= ((config_word >> 5) & GENMASK(5, 0)) + 1;	/* X2FBD */
+	do_div(rate, (config_word & GENMASK(4, 0)) + 1);	/* X2IPD */
+	rate >>= ((config_word >> 16) & GENMASK(1, 0));		/* PS */
+
+	return rate;
+}
+
+static int __init ep93xx_syscon_probe(struct platform_device *pdev)
+{
+	unsigned int clk_f_div, clk_h_div, clk_p_div, clk_usb_div;
+	const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+	const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+	const char pclk_divisors[] = { 1, 2, 4, 8 };
+	unsigned long clk_pll1_rate, clk_pll2_rate;
+	struct soc_device_attribute *attrs;
+	struct soc_device *soc_dev;
+	struct device *dev = &pdev->dev;
+	struct regmap *map;
+	struct clk_hw *hw;
+	u32 value;
+
+	map = device_node_to_regmap(dev->of_node);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+
+	/* Determine the bootloader configured pll1 rate */
+	regmap_read(map, EP93XX_SYSCON_CLKSET1, &value);
+
+	if (value & EP93XX_SYSCON_CLKSET1_NBYP1)
+		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
+	else
+		clk_pll1_rate = EP93XX_EXT_CLK_RATE;
+
+	hw = clk_hw_register_fixed_rate(dev, "pll1", "xtali", 0, clk_pll1_rate);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	/* Initialize the pll1 derived clocks */
+	clk_f_div = fclk_divisors[(value >> 25) & GENMASK(2, 0)];
+	clk_h_div = hclk_divisors[(value >> 20) & GENMASK(2, 0)];
+	clk_p_div = pclk_divisors[(value >> 18) & GENMASK(1, 0)];
+
+	hw = clk_hw_register_fixed_factor(dev, "fclk", "pll1", 0, 1, clk_f_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	hw = clk_hw_register_fixed_factor(dev, "hclk", "pll1", 0, 1, clk_h_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	hw = clk_hw_register_fixed_factor(dev, "pclk", "hclk", 0, 1, clk_p_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	/* Determine the bootloader configured pll2 rate */
+	regmap_read(map, EP93XX_SYSCON_CLKSET2, &value);
+	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
+		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
+	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
+		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
+	else
+		clk_pll2_rate = 0;
+
+	hw = clk_hw_register_fixed_rate(dev, "pll2", "xtali", 0, clk_pll2_rate);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	regmap_read(map, EP93XX_SYSCON_CLKSET2, &value);
+	clk_usb_div = (((value >> 28) & GENMASK(3, 0)) + 1);
+	hw = clk_hw_register_fixed_factor(dev, "usb_clk", "pll2", 0, 1, clk_usb_div);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	attrs = devm_kzalloc(dev, sizeof(*attrs), GFP_KERNEL);
+	if (!attrs)
+		return -ENOMEM;
+
+	attrs->machine = of_flat_dt_get_machine_name();
+	attrs->family = "Cirrus Logic EP93xx";
+	attrs->revision = ep93xx_get_soc_rev(map);
+
+	soc_dev = soc_device_register(attrs);
+	if (IS_ERR(soc_dev))
+		return PTR_ERR(soc_dev);
+
+	dev_info(dev, "EP93xx SoC revision %s\n", attrs->revision);
+
+	return 0;
+}
+
+static const struct of_device_id ep9301_syscon_of_device_ids[] = {
+	{ .compatible	= "cirrus,ep9301-syscon" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver ep9301_syscon_driver = {
+	.driver = {
+		.name = "ep9301-syscon",
+		.of_match_table = ep9301_syscon_of_device_ids,
+	},
+};
+builtin_platform_driver_probe(ep9301_syscon_driver, ep93xx_syscon_probe);
diff --git a/include/linux/soc/cirrus/ep93xx.h b/include/linux/soc/cirrus/ep93xx.h
index 8b4b8221ed4c..267529ee2b3d 100644
--- a/include/linux/soc/cirrus/ep93xx.h
+++ b/include/linux/soc/cirrus/ep93xx.h
@@ -11,7 +11,7 @@ struct regmap;
 #define EP93XX_CHIP_REV_E1	6
 #define EP93XX_CHIP_REV_E2	7
 
-#ifdef CONFIG_ARCH_EP93XX
+#if defined(CONFIG_EP93XX_SOC_COMMON)
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
 void ep93xx_pwm_release_gpio(struct platform_device *pdev);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
@@ -33,11 +33,18 @@ static inline int ep93xx_i2s_acquire(void) { return 0; }
 static inline void ep93xx_i2s_release(void) {}
 static inline unsigned int ep93xx_chip_revision(void) { return 0; }
 
-#endif
+#if defined(CONFIG_EP93XX_SOC)
+void ep93xx_regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
+void ep93xx_regmap_update_bits(struct regmap *map, unsigned int reg,
+			       unsigned int mask, unsigned int val);
 
+#else
 static inline void ep93xx_regmap_write(struct regmap *map, unsigned int reg, unsigned int val) {}
 static inline void ep93xx_regmap_update_bits(struct regmap *map, unsigned int reg,
 					     unsigned int mask, unsigned int val)
 { }
 
 #endif
+#endif
+
+#endif

-- 
2.39.2


  parent reply	other threads:[~2023-09-15  8:12 UTC|newest]

Thread overview: 137+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-15  8:10 [PATCH v4 00/42] ep93xx device tree conversion Nikita Shubin via B4 Relay
2023-09-15  8:10 ` Nikita Shubin via B4 Relay
2023-09-15  8:10 ` Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 01/42] gpio: ep93xx: split device in multiple Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-18  7:37   ` Andy Shevchenko
2023-09-18  7:37     ` Andy Shevchenko
2023-09-15  8:10 ` [PATCH v4 02/42] ARM: ep93xx: add swlocked prototypes Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-16 15:38   ` Alexander Sverdlin
2023-09-18 13:04     ` Alexander Sverdlin
2023-09-15  8:10 ` [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:36   ` Krzysztof Kozlowski
2023-09-15  8:10 ` [PATCH v4 04/42] clk: ep93xx: add DT support for " Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-10-24  2:50   ` Stephen Boyd
2023-09-15  8:10 ` [PATCH v4 05/42] dt-bindings: pinctrl: Add " Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:37   ` Krzysztof Kozlowski
2023-09-15  8:10 ` [PATCH v4 06/42] pinctrl: add a Cirrus ep93xx SoC pin controller Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 07/42] dt-bindings: power: reset: Add ep93xx reset Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:39   ` Krzysztof Kozlowski
2023-09-15  8:10 ` [PATCH v4 08/42] power: reset: Add a driver for the " Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 09/42] dt-bindings: soc: Add Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:42   ` Krzysztof Kozlowski
2023-09-15  8:10 ` Nikita Shubin via B4 Relay [this message]
2023-09-15  8:10   ` [PATCH v4 10/42] soc: Add SoC driver for Cirrus ep93xx Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 11/42] dt-bindings: timers: Add Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-10-15 21:40   ` Daniel Lezcano
2023-10-27 18:23   ` [tip: timers/core] " tip-bot2 for Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 12/42] clocksource: ep93xx: Add driver for Cirrus Logic EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-10-11 13:30   ` Daniel Lezcano
2023-10-15 21:40   ` Daniel Lezcano
2023-10-27 18:23   ` [tip: timers/core] " tip-bot2 for Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 13/42] dt-bindings: rtc: Add Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:43   ` Krzysztof Kozlowski
2023-09-15  8:10 ` [PATCH v4 14/42] rtc: ep93xx: add DT support for " Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 15/42] dt-bindings: watchdog: Add Cirrus EP93x Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:43   ` Krzysztof Kozlowski
2023-09-15  8:10 ` [PATCH v4 16/42] watchdog: ep93xx: add DT support for Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15  8:10 ` [PATCH v4 17/42] dt-bindings: pwm: Add " Nikita Shubin via B4 Relay
2023-09-15  8:10   ` Nikita Shubin
2023-09-15 10:45   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 18/42] pwm: ep93xx: add DT support for " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 10:43   ` Uwe Kleine-König
2023-09-15  8:11 ` [PATCH v4 19/42] dt-bindings: spi: Add " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 10:47   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 20/42] spi: ep93xx: add DT support for " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 12:38   ` Mark Brown
2023-09-15  8:11 ` [PATCH v4 21/42] dt-bindings: net: Add " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 10:49   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 22/42] net: cirrus: add DT support for " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15  8:11 ` [PATCH v4 23/42] dt-bindings: dma: Add " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 10:58   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 24/42] dma: cirrus: add DT support for " Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15  8:11 ` [PATCH v4 25/42] dt-bindings: mtd: Add ts7200 nand-controller Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 11:00   ` Krzysztof Kozlowski
2023-09-15 11:00     ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 26/42] mtd: nand: add support for ts72xx Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-18 12:58   ` Miquel Raynal
2023-09-18 12:58     ` Miquel Raynal
2023-09-15  8:11 ` [PATCH v4 27/42] dt-bindings: ata: Add Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 11:00   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 28/42] ata: pata_ep93xx: add device tree support Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15  8:17   ` Damien Le Moal
2023-09-15  8:53   ` Sergey Shtylyov
2023-09-15  8:11 ` [PATCH v4 29/42] dt-bindings: input: Add Cirrus EP93xx keypad Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 11:05   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 30/42] input: keypad: ep93xx: add DT support for Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-18  7:27   ` Andy Shevchenko
2023-09-18  7:27     ` Andy Shevchenko
2023-09-15  8:11 ` [PATCH v4 31/42] dt-bindings: wdt: Add ts72xx Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 11:18   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 32/42] wdt: ts72xx: add DT support for ts72xx Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11 ` [PATCH v4 33/42] gpio: ep93xx: add DT support for gpio-ep93xx Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11 ` [PATCH v4 34/42] ARM: dts: add Cirrus EP93XX SoC .dtsi Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15 11:24   ` Krzysztof Kozlowski
2023-09-15  8:11 ` [PATCH v4 35/42] ARM: dts: ep93xx: add ts7250 board Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15  8:11 ` [PATCH v4 36/42] ARM: ep93xx: DT for the Cirrus ep93xx SoC platforms Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11 ` [PATCH v4 37/42] pwm: ep93xx: drop legacy pinctrl Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15  8:46   ` Linus Walleij
2023-09-15  8:46     ` Linus Walleij
2023-09-15  8:11 ` [PATCH v4 38/42] ata: pata_ep93xx: remove legacy pinctrl use Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:47   ` Linus Walleij
2023-09-15  8:47     ` Linus Walleij
2023-09-15  8:11 ` [PATCH v4 39/42] ARM: ep93xx: delete all boardfiles Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11 ` [PATCH v4 40/42] ARM: ep93xx: soc: drop defines Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15  8:11 ` [PATCH v4 41/42] ARM: dts: ep93xx: Add EDB9302 DT Nikita Shubin via B4 Relay
2023-09-15  8:11   ` Nikita Shubin
2023-09-15  8:11 ` [PATCH v4 42/42] ASoC: cirrus: edb93xx: Delete driver Nikita Shubin
2023-09-15  8:11   ` Nikita Shubin via B4 Relay
2023-09-15 12:26   ` Mark Brown
2023-09-18  7:39 ` [PATCH v4 00/42] ep93xx device tree conversion Andy Shevchenko
2023-09-18  7:39   ` Andy Shevchenko
2023-10-15 21:17 ` (subset) " Alexandre Belloni
2023-10-15 21:17   ` Alexandre Belloni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230915-ep93xx-v4-10-a1d779dcec10@maquefel.me \
    --to=devnull+nikita.shubin.maquefel.me@kernel.org \
    --cc=alexander.sverdlin@gmail.com \
    --cc=arnd@arndb.de \
    --cc=conor.dooley@microchip.com \
    --cc=dlemoal@kernel.org \
    --cc=j.neuschaefer@gmx.net \
    --cc=joel@jms.id.au \
    --cc=kernel@esmil.dk \
    --cc=linus.walleij@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nikita.shubin@maquefel.me \
    --cc=pmenzel@molgen.mpg.de \
    --cc=s.shtylyov@omp.ru \
    --cc=thierry.reding@gmail.com \
    --cc=u.kleine-koenig@pengutronix.de \
    --cc=walker.chen@starfivetech.com \
    --cc=zhuyinbo@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.