Devicetree
 help / color / mirror / Atom feed
* [PATCH v4 3/8] ARM: mstar: Add cpupll to base dtsi
From: Romain Perier @ 2022-01-26 17:55 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, linux-clk, Arnd Bergmann,
	Daniel Palmer, Romain Perier, Rob Herring
  Cc: devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>

From: Daniel Palmer <daniel@0x0f.com>

All MStar/SigmaStar ARMv7 SoCs have the CPU PLL at the same
place so add it to the base dtsi.

Signed-off-by: Daniel Palmer <daniel@0x0f.com>
Reviewed-by: Romain Perier <romain.perier@gmail.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 89ebfe4f29da..2249faaa3aa7 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -155,6 +155,13 @@ mpll: mpll@206000 {
 				clocks = <&xtal>;
 			};
 
+			cpupll: cpupll@206400 {
+				compatible = "mstar,msc313-cpupll";
+				reg = <0x206400 0x200>;
+				#clock-cells = <0>;
+				clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+			};
+
 			gpio: gpio@207800 {
 				#gpio-cells = <2>;
 				reg = <0x207800 0x200>;
-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 2/8] clk: mstar: msc313 cpupll clk driver
From: Romain Perier @ 2022-01-26 17:55 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, linux-clk, Arnd Bergmann,
	Daniel Palmer, Romain Perier, Rob Herring
  Cc: devicetree, linux-arm-kernel, linux-kernel, Willy Tarreau
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>

From: Daniel Palmer <daniel@0x0f.com>

Add a driver for the CPU pll/ARM pll/MIPS pll that is present
in MStar SoCs.

Currently there is no documentation for this block so it's possible
this driver isn't entirely correct.

Only tested on the version of this IP in the MStar/SigmaStar
ARMv7 SoCs.

Co-authored-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Daniel Palmer <daniel@0x0f.com>
---
 drivers/clk/mstar/Kconfig             |   8 +
 drivers/clk/mstar/Makefile            |   2 +-
 drivers/clk/mstar/clk-msc313-cpupll.c | 221 ++++++++++++++++++++++++++
 3 files changed, 230 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

diff --git a/drivers/clk/mstar/Kconfig b/drivers/clk/mstar/Kconfig
index de37e1bce2d2..146eeb637318 100644
--- a/drivers/clk/mstar/Kconfig
+++ b/drivers/clk/mstar/Kconfig
@@ -1,4 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config MSTAR_MSC313_CPUPLL
+	bool "MStar CPUPLL driver"
+	depends on ARCH_MSTARV7 || COMPILE_TEST
+	default ARCH_MSTARV7
+	help
+	  Support for the CPU PLL present on MStar/Sigmastar SoCs.
+
 config MSTAR_MSC313_MPLL
 	bool "MStar MPLL driver"
 	depends on ARCH_MSTARV7 || COMPILE_TEST
@@ -7,3 +14,4 @@ config MSTAR_MSC313_MPLL
 	help
 	  Support for the MPLL PLL and dividers block present on
 	  MStar/Sigmastar SoCs.
+
diff --git a/drivers/clk/mstar/Makefile b/drivers/clk/mstar/Makefile
index f8dcd25ede1d..21296a04e65a 100644
--- a/drivers/clk/mstar/Makefile
+++ b/drivers/clk/mstar/Makefile
@@ -2,5 +2,5 @@
 #
 # Makefile for mstar specific clk
 #
-
+obj-$(CONFIG_MSTAR_MSC313_CPUPLL) += clk-msc313-cpupll.o
 obj-$(CONFIG_MSTAR_MSC313_MPLL) += clk-msc313-mpll.o
diff --git a/drivers/clk/mstar/clk-msc313-cpupll.c b/drivers/clk/mstar/clk-msc313-cpupll.c
new file mode 100644
index 000000000000..c57b509e8c20
--- /dev/null
+++ b/drivers/clk/mstar/clk-msc313-cpupll.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Daniel Palmer <daniel@thingy.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+/*
+ * This IP is not documented outside of the messy vendor driver.
+ * Below is what we think the registers look like based on looking at
+ * the vendor code and poking at the hardware:
+ *
+ * 0x140 -- LPF low. Seems to store one half of the clock transition
+ * 0x144 /
+ * 0x148 -- LPF high. Seems to store one half of the clock transition
+ * 0x14c /
+ * 0x150 -- vendor code says "toggle lpf enable"
+ * 0x154 -- mu?
+ * 0x15c -- lpf_update_count?
+ * 0x160 -- vendor code says "switch to LPF". Clock source config? Register bank?
+ * 0x164 -- vendor code says "from low to high" which seems to mean transition from LPF low to
+ * LPF high.
+ * 0x174 -- Seems to be the PLL lock status bit
+ * 0x180 -- Seems to be the current frequency, this might need to be populated by software?
+ * 0x184 /  The vendor driver uses these to set the initial value of LPF low
+ *
+ * Frequency seems to be calculated like this:
+ * (parent clock (432mhz) / register_magic_value) * 16 * 524288
+ * Only the lower 24 bits of the resulting value will be used. In addition, the
+ * PLL doesn't seem to be able to lock on frequencies lower than 220 MHz, as
+ * divisor 0xfb586f (220 MHz) works but 0xfb7fff locks up.
+ *
+ * Vendor values:
+ * frequency - register value
+ *
+ * 400000000  - 0x0067AE14
+ * 600000000  - 0x00451EB8,
+ * 800000000  - 0x0033D70A,
+ * 1000000000 - 0x002978d4,
+ */
+
+#define REG_LPF_LOW_L		0x140
+#define REG_LPF_LOW_H		0x144
+#define REG_LPF_HIGH_BOTTOM	0x148
+#define REG_LPF_HIGH_TOP	0x14c
+#define REG_LPF_TOGGLE		0x150
+#define REG_LPF_MYSTERYTWO	0x154
+#define REG_LPF_UPDATE_COUNT	0x15c
+#define REG_LPF_MYSTERYONE	0x160
+#define REG_LPF_TRANSITIONCTRL	0x164
+#define REG_LPF_LOCK		0x174
+#define REG_CURRENT		0x180
+
+#define LPF_LOCK_TIMEOUT	100000000
+
+#define MULTIPLIER_1		16
+#define MULTIPLIER_2		524288
+#define MULTIPLIER		(MULTIPLIER_1 * MULTIPLIER_2)
+
+struct msc313_cpupll {
+	void __iomem *base;
+	struct clk_hw clk_hw;
+};
+
+#define to_cpupll(_hw) container_of(_hw, struct msc313_cpupll, clk_hw)
+
+static u32 msc313_cpupll_reg_read32(struct msc313_cpupll *cpupll, unsigned int reg)
+{
+	u32 value;
+
+	value = ioread16(cpupll->base + reg + 4) << 16;
+	value |= ioread16(cpupll->base + reg);
+
+	return value;
+}
+
+static void msc313_cpupll_reg_write32(struct msc313_cpupll *cpupll, unsigned int reg, u32 value)
+{
+	u16 l = value & 0xffff, h = (value >> 16) & 0xffff;
+
+	iowrite16(l, cpupll->base + reg);
+	iowrite16(h, cpupll->base + reg + 4);
+}
+
+static void msc313_cpupll_setfreq(struct msc313_cpupll *cpupll, u32 regvalue)
+{
+	ktime_t timeout;
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_HIGH_BOTTOM, regvalue);
+
+	iowrite16(0x1, cpupll->base + REG_LPF_MYSTERYONE);
+	iowrite16(0x6, cpupll->base + REG_LPF_MYSTERYTWO);
+	iowrite16(0x8, cpupll->base + REG_LPF_UPDATE_COUNT);
+	iowrite16(BIT(12), cpupll->base + REG_LPF_TRANSITIONCTRL);
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+	iowrite16(1, cpupll->base + REG_LPF_TOGGLE);
+
+	timeout = ktime_add_ns(ktime_get(), LPF_LOCK_TIMEOUT);
+	while (!(ioread16(cpupll->base + REG_LPF_LOCK))) {
+		if (ktime_after(ktime_get(), timeout)) {
+			pr_err("timeout waiting for LPF_LOCK\n");
+			return;
+		}
+		cpu_relax();
+	}
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L, regvalue);
+}
+
+static unsigned long msc313_cpupll_frequencyforreg(u32 reg, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+
+	if (prescaled == 0 || reg == 0)
+		return 0;
+	return DIV_ROUND_DOWN_ULL(prescaled, reg);
+}
+
+static u32 msc313_cpupll_regforfrequecy(unsigned long rate, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+
+	if (prescaled == 0 || rate == 0)
+		return 0;
+	return DIV_ROUND_UP_ULL(prescaled, rate);
+}
+
+static unsigned long msc313_cpupll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+
+	return msc313_cpupll_frequencyforreg(msc313_cpupll_reg_read32(cpupll, REG_LPF_LOW_L),
+					     parent_rate);
+}
+
+static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate);
+	long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	/*
+	 * This is my poor attempt at making sure the resulting
+	 * rate doesn't overshoot the requested rate.
+	 */
+	for (; rounded >= rate && reg > 0; reg--)
+		rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	return rounded;
+}
+
+static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+	u32 reg = msc313_cpupll_regforfrequecy(rate, parent_rate);
+
+	msc313_cpupll_setfreq(cpupll, reg);
+
+	return 0;
+}
+
+static const struct clk_ops msc313_cpupll_ops = {
+	.recalc_rate	= msc313_cpupll_recalc_rate,
+	.round_rate	= msc313_cpupll_round_rate,
+	.set_rate	= msc313_cpupll_set_rate,
+};
+
+static const struct of_device_id msc313_cpupll_of_match[] = {
+	{ .compatible = "mstar,msc313-cpupll" },
+	{}
+};
+
+static const struct clk_parent_data cpupll_parent = {
+	.index	= 0,
+};
+
+static int msc313_cpupll_probe(struct platform_device *pdev)
+{
+	struct clk_init_data clk_init = {};
+	struct device *dev = &pdev->dev;
+	struct msc313_cpupll *cpupll;
+	int ret;
+
+	cpupll = devm_kzalloc(&pdev->dev, sizeof(*cpupll), GFP_KERNEL);
+	if (!cpupll)
+		return -ENOMEM;
+
+	cpupll->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(cpupll->base))
+		return PTR_ERR(cpupll->base);
+
+	/* LPF might not contain the current frequency so fix that up */
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L,
+				  msc313_cpupll_reg_read32(cpupll, REG_CURRENT));
+
+	clk_init.name = dev_name(dev);
+	clk_init.ops = &msc313_cpupll_ops;
+	clk_init.parent_data = &cpupll_parent;
+	clk_init.num_parents = 1;
+	cpupll->clk_hw.init = &clk_init;
+
+	ret = devm_clk_hw_register(dev, &cpupll->clk_hw);
+	if (ret)
+		return ret;
+
+	return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get, &cpupll->clk_hw);
+}
+
+static struct platform_driver msc313_cpupll_driver = {
+	.driver = {
+		.name = "mstar-msc313-cpupll",
+		.of_match_table = msc313_cpupll_of_match,
+	},
+	.probe = msc313_cpupll_probe,
+};
+builtin_platform_driver(msc313_cpupll_driver);
-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 1/8] dt-bindings: clk: mstar msc313 cpupll binding description
From: Romain Perier @ 2022-01-26 17:55 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, linux-clk, Arnd Bergmann,
	Daniel Palmer, Romain Perier, Rob Herring
  Cc: devicetree, linux-arm-kernel, linux-kernel, Rob Herring
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>

From: Daniel Palmer <daniel@0x0f.com>

Add a binding description for the MStar/SigmaStar CPU PLL block.

Signed-off-by: Daniel Palmer <daniel@0x0f.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/clock/mstar,msc313-cpupll.yaml   | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml

diff --git a/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
new file mode 100644
index 000000000000..a9ad7ab5230c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mstar,msc313-cpupll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MStar/Sigmastar MSC313 CPU PLL
+
+maintainers:
+  - Daniel Palmer <daniel@thingy.jp>
+
+description: |
+  The MStar/SigmaStar MSC313 and later ARMv7 chips have a scalable
+  PLL that can be used as the clock source for the CPU(s).
+
+properties:
+  compatible:
+    const: mstar,msc313-cpupll
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mstar-msc313-mpll.h>
+    cpupll: cpupll@206400 {
+        compatible = "mstar,msc313-cpupll";
+        reg = <0x206400 0x200>;
+        #clock-cells = <1>;
+        clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+    };
-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 0/8] ARM: mstar: cpupll
From: Romain Perier @ 2022-01-26 17:55 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, linux-clk, Arnd Bergmann,
	Daniel Palmer, Romain Perier, Rob Herring
  Cc: devicetree, linux-arm-kernel, linux-kernel

This series adds a basic driver for the PLL that generates
the cpu clock on MStar/SigmaStar ARMv7 SoCs.

Unfortunately there isn't much documentation for this thing
so there are few magic values and guesses.

This needs to come after the MPLL DT changes.

Changes since v3:
- Added Reviewed-by on Daniel's patches
- Removed "[PATCH v3 8/9] ARM: mstar: Add OPP table for mercury5"

Changes since v2:
- Re-ordered Kconfig by name
- Re-ordered includes alphabetically and removed useless ones
- Used timeout for cpu_relax
- Returned DIV_ROUND_DOWN_ULL() directly in
  msc313_cpupll_frequencyforreg()
- Returned DIV_ROUND_DOWN_ULL() directly in
  msc313_cpupll_regforfrequecy()
- Reduced the number of lines for msc313_cpupll_of_match
- Removed CLK_IS_CRITICAL

Changes since v1:
- Re-worked the series and ensure that 'make dt_binding_check' passes.
  The required commit is merged now, so it is okay.
- Fixed coding style issues in the driver and makes check_patch.pl happy
- Added one more commit for extending the opp_table for infinity2m.

Daniel Palmer (7):
  dt-bindings: clk: mstar msc313 cpupll binding description
  clk: mstar: msc313 cpupll clk driver
  ARM: mstar: Add cpupll to base dtsi
  ARM: mstar: Link cpupll to cpu
  ARM: mstar: Link cpupll to second core
  ARM: mstar: Add OPP table for infinity
  ARM: mstar: Add OPP table for infinity3

Romain Perier (1):
  ARM: mstar: Extend opp_table for infinity2m

 .../bindings/clock/mstar,msc313-cpupll.yaml   |  45 ++++
 arch/arm/boot/dts/mstar-infinity.dtsi         |  34 +++
 arch/arm/boot/dts/mstar-infinity2m.dtsi       |  17 ++
 arch/arm/boot/dts/mstar-infinity3.dtsi        |  58 +++++
 arch/arm/boot/dts/mstar-v7.dtsi               |   9 +
 drivers/clk/mstar/Kconfig                     |   8 +
 drivers/clk/mstar/Makefile                    |   2 +-
 drivers/clk/mstar/clk-msc313-cpupll.c         | 221 ++++++++++++++++++
 8 files changed, 393 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

-- 
2.34.1


^ permalink raw reply

* Re: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
From: Robin Murphy @ 2022-01-26 17:56 UTC (permalink / raw)
  To: Peter Geis, Sascha Hauer
  Cc: dri-devel, arm-mail-list, open list:ARM/Rockchip SoC...,
	devicetree, kernel, Andy Yan, Benjamin Gaignard, Michael Riesch,
	Sandy Huang, Heiko Stübner
In-Reply-To: <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>

On 2022-01-26 16:04, Peter Geis wrote:
> On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>>
>> Add support for the HDMI port found on RK3568.
>>
>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>> ---
>>   arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
>>   1 file changed, 36 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> index 4008bd666d01..e38fb223e9b8 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> @@ -10,7 +10,6 @@
>>   #include <dt-bindings/pinctrl/rockchip.h>
>>   #include <dt-bindings/power/rk3568-power.h>
>>   #include <dt-bindings/soc/rockchip,boot-mode.h>
>> -#include <dt-bindings/soc/rockchip,vop2.h>
>>   #include <dt-bindings/thermal/thermal.h>
>>
>>   / {
>> @@ -502,6 +501,42 @@ vop_mmu: iommu@fe043e00 {
>>                  status = "disabled";
>>          };
>>
>> +       hdmi: hdmi@fe0a0000 {
>> +               compatible = "rockchip,rk3568-dw-hdmi";
>> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
>> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
>> +               clocks = <&cru PCLK_HDMI_HOST>,
>> +                        <&cru CLK_HDMI_SFR>,
>> +                        <&cru CLK_HDMI_CEC>,
>> +                        <&pmucru CLK_HDMI_REF>,
>> +                        <&cru HCLK_VOP>;
>> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
>> +               pinctrl-names = "default";
>> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;
> 
> I looked into CEC support here, and it seems that it does work with one change.
> Please add the two following lines to your patch:
> assigned-clocks = <&cru CLK_HDMI_CEC>;
> assigned-clock-rates = <32768>;
> 
> The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
> feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
> function.

Wouldn't it make far more sense to just stick a suitable clk_set_rate() 
call in the driver? AFAICS it's already explicitly aware of the CEC clock.

Robin.

>> +               power-domains = <&power RK3568_PD_VO>;
>> +               reg-io-width = <4>;
>> +               rockchip,grf = <&grf>;
>> +               #sound-dai-cells = <0>;
>> +               status = "disabled";
>> +
>> +               ports {
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +
>> +                       hdmi_in: port@0 {
>> +                               reg = <0>;
>> +                               #address-cells = <1>;
>> +                               #size-cells = <0>;
>> +                       };
>> +
>> +                       hdmi_out: port@1 {
>> +                               reg = <1>;
>> +                               #address-cells = <1>;
>> +                               #size-cells = <0>;
>> +                       };
>> +               };
>> +       };
>> +
>>          qos_gpu: qos@fe128000 {
>>                  compatible = "rockchip,rk3568-qos", "syscon";
>>                  reg = <0x0 0xfe128000 0x0 0x20>;
>> --
>> 2.30.2
>>
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

^ permalink raw reply

* [RESEND, third time][PATCH] arm64: dts: intel: socfpga_agilex_socdk: align LED node names with dtschema
From: Krzysztof Kozlowski @ 2022-01-26 17:41 UTC (permalink / raw)
  To: Dinh Nguyen, Rob Herring, devicetree, linux-kernel; +Cc: Krzysztof Kozlowski

From: Krzysztof Kozlowski <krzk@kernel.org>

Align the LED node names with dtschema to silence dtbs_check warnings
like:

    leds: 'hps0', 'hps1', 'hps2' do not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

---

This patch waits for a year. Dinh, you previously acked it but can you
apply it?
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
index ea37ba7ccff9..26cd3c121757 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
@@ -21,17 +21,17 @@ chosen {
 
 	leds {
 		compatible = "gpio-leds";
-		hps0 {
+		led0 {
 			label = "hps_led0";
 			gpios = <&portb 20 GPIO_ACTIVE_HIGH>;
 		};
 
-		hps1 {
+		led1 {
 			label = "hps_led1";
 			gpios = <&portb 19 GPIO_ACTIVE_HIGH>;
 		};
 
-		hps2 {
+		led2 {
 			label = "hps_led2";
 			gpios = <&portb 21 GPIO_ACTIVE_HIGH>;
 		};
-- 
2.32.0


^ permalink raw reply related

* [PATCH v1 7/7] clk: starfive: Add JH7100 audio clock driver
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

Add a driver for the audio clocks on the Starfive JH7100 RISC-V SoC.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 MAINTAINERS                                   |   8 +-
 drivers/clk/starfive/Kconfig                  |   8 +
 drivers/clk/starfive/Makefile                 |   1 +
 .../clk/starfive/clk-starfive-jh7100-audio.c  | 170 ++++++++++++++++++
 4 files changed, 183 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7100-audio.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..19a855f3fdca 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18376,12 +18376,12 @@ M:	Ion Badulescu <ionut@badula.org>
 S:	Odd Fixes
 F:	drivers/net/ethernet/adaptec/starfire*
 
-STARFIVE JH7100 CLOCK DRIVER
+STARFIVE JH7100 CLOCK DRIVERS
 M:	Emil Renner Berthing <kernel@esmil.dk>
 S:	Maintained
-F:	Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml
-F:	drivers/clk/starfive/clk-starfive-jh7100.c
-F:	include/dt-bindings/clock/starfive-jh7100.h
+F:	Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
+F:	drivers/clk/starfive/clk-starfive-jh7100*
+F:	include/dt-bindings/clock/starfive-jh7100*.h
 
 STARFIVE JH7100 PINCTRL DRIVER
 M:	Emil Renner Berthing <kernel@esmil.dk>
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index c0fa9d5e641f..003bd2d56ce7 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -7,3 +7,11 @@ config CLK_STARFIVE_JH7100
 	help
 	  Say yes here to support the clock controller on the StarFive JH7100
 	  SoC.
+
+config CLK_STARFIVE_JH7100_AUDIO
+	tristate "StarFive JH7100 audio clock support"
+	depends on CLK_STARFIVE_JH7100
+	default m if SOC_STARFIVE
+	help
+	  Say Y or M here to support the audio clocks on the StarFive JH7100
+	  SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 09759cc73530..0fa8ecb9ec1c 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 # StarFive Clock
 obj-$(CONFIG_CLK_STARFIVE_JH7100)	+= clk-starfive-jh7100.o
+obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)	+= clk-starfive-jh7100-audio.o
diff --git a/drivers/clk/starfive/clk-starfive-jh7100-audio.c b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
new file mode 100644
index 000000000000..8473a65e219b
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JH7100 Audio Clock Driver
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/starfive-jh7100-audio.h>
+
+#include "clk-starfive-jh7100.h"
+
+/* external clocks */
+#define JH7100_AUDCLK_AUDIO_SRC			(JH7100_AUDCLK_END + 0)
+#define JH7100_AUDCLK_AUDIO_12288		(JH7100_AUDCLK_END + 1)
+#define JH7100_AUDCLK_DOM7AHB_BUS		(JH7100_AUDCLK_END + 2)
+#define JH7100_AUDCLK_I2SADC_BCLK_IOPAD		(JH7100_AUDCLK_END + 3)
+#define JH7100_AUDCLK_I2SADC_LRCLK_IOPAD	(JH7100_AUDCLK_END + 4)
+#define JH7100_AUDCLK_I2SDAC_BCLK_IOPAD		(JH7100_AUDCLK_END + 5)
+#define JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD	(JH7100_AUDCLK_END + 6)
+#define JH7100_AUDCLK_VAD_INTMEM                (JH7100_AUDCLK_END + 7)
+
+static const struct jh7100_clk_data jh7100_audclk_data[] = {
+	JH7100__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
+		    JH7100_AUDCLK_AUDIO_SRC,
+		    JH7100_AUDCLK_AUDIO_12288),
+	JH7100__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
+		    JH7100_AUDCLK_AUDIO_SRC,
+		    JH7100_AUDCLK_AUDIO_12288),
+	JH7100_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
+		    JH7100_AUDCLK_ADC_MCLK,
+		    JH7100_AUDCLK_I2SADC_BCLK_IOPAD),
+	JH7100__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
+	JH7100_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
+		    JH7100_AUDCLK_I2SADC_BCLK_N,
+		    JH7100_AUDCLK_I2SADC_LRCLK_IOPAD,
+		    JH7100_AUDCLK_I2SADC_BCLK),
+	JH7100_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
+		    JH7100_AUDCLK_AUDIO_SRC,
+		    JH7100_AUDCLK_AUDIO_12288),
+	JH7100_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
+		    JH7100_AUDCLK_AUDIO_SRC,
+		    JH7100_AUDCLK_AUDIO_12288),
+	JH7100_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
+		    JH7100_AUDCLK_AUDIO_SRC,
+		    JH7100_AUDCLK_AUDIO_12288),
+	JH7100_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
+		    JH7100_AUDCLK_DAC_MCLK,
+		    JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
+	JH7100__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
+	JH7100_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
+		    JH7100_AUDCLK_I2S1_MCLK,
+		    JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
+	JH7100_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
+		    JH7100_AUDCLK_I2S1_MCLK,
+		    JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
+	JH7100__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
+	JH7100_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
+		    JH7100_AUDCLK_I2S1_BCLK_N,
+		    JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD),
+	JH7100_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
+	JH7100__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+	JH7100_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
+	JH7100_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
+	JH7100_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
+	JH7100_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
+	JH7100__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+	JH7100__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
+		    JH7100_AUDCLK_VAD_INTMEM,
+		    JH7100_AUDCLK_AUDIO_12288),
+};
+
+static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct jh7100_clk_priv *priv = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx < JH7100_AUDCLK_END)
+		return &priv->reg[idx].hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int jh7100_audclk_probe(struct platform_device *pdev)
+{
+	struct jh7100_clk_priv *priv;
+	unsigned int idx;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7100_AUDCLK_END), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->rmw_lock);
+	priv->dev = &pdev->dev;
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	for (idx = 0; idx < JH7100_AUDCLK_END; idx++) {
+		u32 max = jh7100_audclk_data[idx].max;
+		struct clk_parent_data parents[4] = {};
+		struct clk_init_data init = {
+			.name = jh7100_audclk_data[idx].name,
+			.ops = starfive_jh7100_clk_ops(max),
+			.parent_data = parents,
+			.num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
+			.flags = jh7100_audclk_data[idx].flags,
+		};
+		struct jh7100_clk *clk = &priv->reg[idx];
+		unsigned int i;
+
+		for (i = 0; i < init.num_parents; i++) {
+			unsigned int pidx = jh7100_audclk_data[idx].parents[i];
+
+			if (pidx < JH7100_AUDCLK_END)
+				parents[i].hw = &priv->reg[pidx].hw;
+			else if (pidx == JH7100_AUDCLK_AUDIO_SRC)
+				parents[i].fw_name = "audio_src";
+			else if (pidx == JH7100_AUDCLK_AUDIO_12288)
+				parents[i].fw_name = "audio_12288";
+			else if (pidx == JH7100_AUDCLK_DOM7AHB_BUS)
+				parents[i].fw_name = "dom7ahb_bus";
+		}
+
+		clk->hw.init = &init;
+		clk->idx = idx;
+		clk->max_div = max & JH7100_CLK_DIV_MASK;
+
+		ret = devm_clk_hw_register(priv->dev, &clk->hw);
+		if (ret)
+			return ret;
+	}
+
+	return devm_of_clk_add_hw_provider(priv->dev, jh7100_audclk_get, priv);
+}
+
+static const struct of_device_id jh7100_audclk_match[] = {
+	{ .compatible = "starfive,jh7100-audclk" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7100_audclk_match);
+
+static struct platform_driver jh7100_audclk_driver = {
+	.probe = jh7100_audclk_probe,
+	.driver = {
+		.name = "clk-starfive-jh7100-audio",
+		.of_match_table = jh7100_audclk_match,
+	},
+};
+module_platform_driver(jh7100_audclk_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing");
+MODULE_DESCRIPTION("StarFive JH7100 audio clock driver");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 6/7] clk: starfive: jh7100: Support more clock types
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

Unlike the system clocks there are audio clocks that combine both
multiplexer/divider and gate/multiplexer/divider, so add support for
that.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 drivers/clk/starfive/clk-starfive-jh7100.c | 26 ++++++++++++++++++++++
 drivers/clk/starfive/clk-starfive-jh7100.h | 15 +++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
index a6708f9ebf4c..691aeebc7092 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -534,6 +534,27 @@ static const struct clk_ops jh7100_clk_gmux_ops = {
 	.debug_init = jh7100_clk_debug_init,
 };
 
+static const struct clk_ops jh7100_clk_mdiv_ops = {
+	.recalc_rate = jh7100_clk_recalc_rate,
+	.determine_rate = jh7100_clk_determine_rate,
+	.get_parent = jh7100_clk_get_parent,
+	.set_parent = jh7100_clk_set_parent,
+	.set_rate = jh7100_clk_set_rate,
+	.debug_init = jh7100_clk_debug_init,
+};
+
+static const struct clk_ops jh7100_clk_gmd_ops = {
+	.enable = jh7100_clk_enable,
+	.disable = jh7100_clk_disable,
+	.is_enabled = jh7100_clk_is_enabled,
+	.recalc_rate = jh7100_clk_recalc_rate,
+	.determine_rate = jh7100_clk_determine_rate,
+	.get_parent = jh7100_clk_get_parent,
+	.set_parent = jh7100_clk_set_parent,
+	.set_rate = jh7100_clk_set_rate,
+	.debug_init = jh7100_clk_debug_init,
+};
+
 static const struct clk_ops jh7100_clk_inv_ops = {
 	.get_phase = jh7100_clk_get_phase,
 	.set_phase = jh7100_clk_set_phase,
@@ -543,6 +564,11 @@ static const struct clk_ops jh7100_clk_inv_ops = {
 const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
 {
 	if (max & JH7100_CLK_DIV_MASK) {
+		if (max & JH7100_CLK_MUX_MASK) {
+			if (max & JH7100_CLK_ENABLE)
+				return &jh7100_clk_gmd_ops;
+			return &jh7100_clk_mdiv_ops;
+		}
 		if (max & JH7100_CLK_ENABLE)
 			return &jh7100_clk_gdiv_ops;
 		if (max == JH7100_CLK_FRAC_MAX)
diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh7100.h
index 8eccd8c0a746..f116be5740a5 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.h
+++ b/drivers/clk/starfive/clk-starfive-jh7100.h
@@ -70,6 +70,21 @@ struct jh7100_clk_data {
 	.parents = { __VA_ARGS__ },						\
 }
 
+#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = {		\
+	.name = _name,								\
+	.flags = 0,								\
+	.max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max),		\
+	.parents = { __VA_ARGS__ },						\
+}
+
+#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = {	\
+	.name = _name,								\
+	.flags = _flags,							\
+	.max = JH7100_CLK_ENABLE |						\
+		(((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max),		\
+	.parents = { __VA_ARGS__ },						\
+}
+
 #define JH7100__INV(_idx, _name, _parent) [_idx] = {				\
 	.name = _name,								\
 	.flags = CLK_SET_RATE_PARENT,						\
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 5/7] clk: starfive: jh7100: Make hw clock implementation reusable
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

The JH7100 has additional audio and video clocks at different memory
ranges, but they use the same register layout. Add a header and export
the starfive_jh7100_clk_ops function so the clock implementation can be
reused by drivers handling these clocks.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 drivers/clk/starfive/clk-starfive-jh7100.c | 96 ++-------------------
 drivers/clk/starfive/clk-starfive-jh7100.h | 97 ++++++++++++++++++++++
 2 files changed, 104 insertions(+), 89 deletions(-)
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7100.h

diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
index 4b59338b5d7d..a6708f9ebf4c 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -20,83 +20,15 @@
 
 #include <dt-bindings/clock/starfive-jh7100.h>
 
+#include "clk-starfive-jh7100.h"
+
 /* external clocks */
 #define JH7100_CLK_OSC_SYS		(JH7100_CLK_END + 0)
 #define JH7100_CLK_OSC_AUD		(JH7100_CLK_END + 1)
 #define JH7100_CLK_GMAC_RMII_REF	(JH7100_CLK_END + 2)
 #define JH7100_CLK_GMAC_GR_MII_RX	(JH7100_CLK_END + 3)
 
-/* register fields */
-#define JH7100_CLK_ENABLE	BIT(31)
-#define JH7100_CLK_INVERT	BIT(30)
-#define JH7100_CLK_MUX_MASK	GENMASK(27, 24)
-#define JH7100_CLK_MUX_SHIFT	24
-#define JH7100_CLK_DIV_MASK	GENMASK(23, 0)
-#define JH7100_CLK_FRAC_MASK	GENMASK(15, 8)
-#define JH7100_CLK_FRAC_SHIFT	8
-#define JH7100_CLK_INT_MASK	GENMASK(7, 0)
-
-/* fractional divider min/max */
-#define JH7100_CLK_FRAC_MIN	100UL
-#define JH7100_CLK_FRAC_MAX	25599UL
-
-/* clock data */
-#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = {		\
-	.name = _name,							\
-	.flags = CLK_SET_RATE_PARENT | (_flags),			\
-	.max = JH7100_CLK_ENABLE,					\
-	.parents = { [0] = _parent },					\
-}
-
-#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = {		\
-	.name = _name,							\
-	.flags = 0,							\
-	.max = _max,							\
-	.parents = { [0] = _parent },					\
-}
-
-#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = {	\
-	.name = _name,							\
-	.flags = _flags,						\
-	.max = JH7100_CLK_ENABLE | (_max),				\
-	.parents = { [0] = _parent },					\
-}
-
-#define JH7100_FDIV(_idx, _name, _parent) [_idx] = {			\
-	.name = _name,							\
-	.flags = 0,							\
-	.max = JH7100_CLK_FRAC_MAX,					\
-	.parents = { [0] = _parent },					\
-}
-
-#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = {		\
-	.name = _name,							\
-	.flags = 0,							\
-	.max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT,		\
-	.parents = { __VA_ARGS__ },					\
-}
-
-#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = {	\
-	.name = _name,							\
-	.flags = _flags,						\
-	.max = JH7100_CLK_ENABLE |					\
-		(((_nparents) - 1) << JH7100_CLK_MUX_SHIFT),		\
-	.parents = { __VA_ARGS__ },					\
-}
-
-#define JH7100__INV(_idx, _name, _parent) [_idx] = {			\
-	.name = _name,							\
-	.flags = CLK_SET_RATE_PARENT,					\
-	.max = JH7100_CLK_INVERT,					\
-	.parents = { [0] = _parent },					\
-}
-
-static const struct {
-	const char *name;
-	unsigned long flags;
-	u32 max;
-	u8 parents[4];
-} jh7100_clk_data[] __initconst = {
+static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
 	JH7100__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
 		    JH7100_CLK_OSC_SYS,
 		    JH7100_CLK_PLL0_OUT,
@@ -337,21 +269,6 @@ static const struct {
 	JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
 };
 
-struct jh7100_clk {
-	struct clk_hw hw;
-	unsigned int idx;
-	unsigned int max_div;
-};
-
-struct jh7100_clk_priv {
-	/* protect clk enable and set rate/parent from happening at the same time */
-	spinlock_t rmw_lock;
-	struct device *dev;
-	void __iomem *base;
-	struct clk_hw *pll[3];
-	struct jh7100_clk reg[JH7100_CLK_PLL0_OUT];
-};
-
 static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
 {
 	return container_of(hw, struct jh7100_clk, hw);
@@ -623,7 +540,7 @@ static const struct clk_ops jh7100_clk_inv_ops = {
 	.debug_init = jh7100_clk_debug_init,
 };
 
-static const struct clk_ops *__init jh7100_clk_ops(u32 max)
+const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
 {
 	if (max & JH7100_CLK_DIV_MASK) {
 		if (max & JH7100_CLK_ENABLE)
@@ -644,6 +561,7 @@ static const struct clk_ops *__init jh7100_clk_ops(u32 max)
 
 	return &jh7100_clk_inv_ops;
 }
+EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
 
 static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
 {
@@ -665,7 +583,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
 	unsigned int idx;
 	int ret;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7100_CLK_PLL0_OUT), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
@@ -695,7 +613,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
 		struct clk_parent_data parents[4] = {};
 		struct clk_init_data init = {
 			.name = jh7100_clk_data[idx].name,
-			.ops = jh7100_clk_ops(max),
+			.ops = starfive_jh7100_clk_ops(max),
 			.parent_data = parents,
 			.num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
 			.flags = jh7100_clk_data[idx].flags,
diff --git a/drivers/clk/starfive/clk-starfive-jh7100.h b/drivers/clk/starfive/clk-starfive-jh7100.h
new file mode 100644
index 000000000000..8eccd8c0a746
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jh7100.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __CLK_STARFIVE_JH7100_H
+#define __CLK_STARFIVE_JH7100_H
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+
+/* register fields */
+#define JH7100_CLK_ENABLE	BIT(31)
+#define JH7100_CLK_INVERT	BIT(30)
+#define JH7100_CLK_MUX_MASK	GENMASK(27, 24)
+#define JH7100_CLK_MUX_SHIFT	24
+#define JH7100_CLK_DIV_MASK	GENMASK(23, 0)
+#define JH7100_CLK_FRAC_MASK	GENMASK(15, 8)
+#define JH7100_CLK_FRAC_SHIFT	8
+#define JH7100_CLK_INT_MASK	GENMASK(7, 0)
+
+/* fractional divider min/max */
+#define JH7100_CLK_FRAC_MIN	100UL
+#define JH7100_CLK_FRAC_MAX	25599UL
+
+/* clock data */
+struct jh7100_clk_data {
+	const char *name;
+	unsigned long flags;
+	u32 max;
+	u8 parents[4];
+};
+
+#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = {			\
+	.name = _name,								\
+	.flags = CLK_SET_RATE_PARENT | (_flags),				\
+	.max = JH7100_CLK_ENABLE,						\
+	.parents = { [0] = _parent },						\
+}
+
+#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = {			\
+	.name = _name,								\
+	.flags = 0,								\
+	.max = _max,								\
+	.parents = { [0] = _parent },						\
+}
+
+#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = {		\
+	.name = _name,								\
+	.flags = _flags,							\
+	.max = JH7100_CLK_ENABLE | (_max),					\
+	.parents = { [0] = _parent },						\
+}
+
+#define JH7100_FDIV(_idx, _name, _parent) [_idx] = {				\
+	.name = _name,								\
+	.flags = 0,								\
+	.max = JH7100_CLK_FRAC_MAX,						\
+	.parents = { [0] = _parent },						\
+}
+
+#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = {			\
+	.name = _name,								\
+	.flags = 0,								\
+	.max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT,			\
+	.parents = { __VA_ARGS__ },						\
+}
+
+#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = {		\
+	.name = _name,								\
+	.flags = _flags,							\
+	.max = JH7100_CLK_ENABLE |						\
+		(((_nparents) - 1) << JH7100_CLK_MUX_SHIFT),			\
+	.parents = { __VA_ARGS__ },						\
+}
+
+#define JH7100__INV(_idx, _name, _parent) [_idx] = {				\
+	.name = _name,								\
+	.flags = CLK_SET_RATE_PARENT,						\
+	.max = JH7100_CLK_INVERT,						\
+	.parents = { [0] = _parent },						\
+}
+
+struct jh7100_clk {
+	struct clk_hw hw;
+	unsigned int idx;
+	unsigned int max_div;
+};
+
+struct jh7100_clk_priv {
+	/* protect clk enable and set rate/parent from happening at the same time */
+	spinlock_t rmw_lock;
+	struct device *dev;
+	void __iomem *base;
+	struct clk_hw *pll[3];
+	struct jh7100_clk reg[];
+};
+
+const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
+
+#endif
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 4/7] dt-bindings: clock: Add starfive,jh7100-audclk bindings
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

Add bindings for the audio clocks on the StarFive JH7100 RISC-V SoC.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 .../clock/starfive,jh7100-audclk.yaml         | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml

diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml
new file mode 100644
index 000000000000..8f49a1ae03f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jh7100-audclk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7100 Audio Clock Generator
+
+maintainers:
+  - Emil Renner Berthing <kernel@esmil.dk>
+
+properties:
+  compatible:
+    const: starfive,jh7100-audclk
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Audio source clock
+      - description: External 12.288MHz clock
+      - description: Domain 7 AHB bus clock
+
+  clock-names:
+    items:
+      - const: audio_src
+      - const: audio_12288
+      - const: dom7ahb_bus
+
+  '#clock-cells':
+    const: 1
+    description:
+      See <dt-bindings/clock/starfive-jh7100-audio.h> for valid indices.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/starfive-jh7100.h>
+
+    clock-controller@10480000 {
+            compatible = "starfive,jh7100-audclk";
+            reg = <0x10480000 0x10000>;
+            clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
+                     <&clkgen JH7100_CLK_AUDIO_12288>,
+                     <&clkgen JH7100_CLK_DOM7AHB_BUS>;
+            clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
+            #clock-cells = <1>;
+    };
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 3/7] dt-bindings: clock: Add JH7100 audio clock definitions
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

Add all clock outputs for the StarFive JH7100 audio clock generator.

Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 .../dt-bindings/clock/starfive-jh7100-audio.h | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 include/dt-bindings/clock/starfive-jh7100-audio.h

diff --git a/include/dt-bindings/clock/starfive-jh7100-audio.h b/include/dt-bindings/clock/starfive-jh7100-audio.h
new file mode 100644
index 000000000000..fbb4eae6572b
--- /dev/null
+++ b/include/dt-bindings/clock/starfive-jh7100-audio.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_AUDIO_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_AUDIO_H__
+
+#define JH7100_AUDCLK_ADC_MCLK		0
+#define JH7100_AUDCLK_I2S1_MCLK		1
+#define JH7100_AUDCLK_I2SADC_APB	2
+#define JH7100_AUDCLK_I2SADC_BCLK	3
+#define JH7100_AUDCLK_I2SADC_BCLK_N	4
+#define JH7100_AUDCLK_I2SADC_LRCLK	5
+#define JH7100_AUDCLK_PDM_APB		6
+#define JH7100_AUDCLK_PDM_MCLK		7
+#define JH7100_AUDCLK_I2SVAD_APB	8
+#define JH7100_AUDCLK_SPDIF		9
+#define JH7100_AUDCLK_SPDIF_APB		10
+#define JH7100_AUDCLK_PWMDAC_APB	11
+#define JH7100_AUDCLK_DAC_MCLK		12
+#define JH7100_AUDCLK_I2SDAC_APB	13
+#define JH7100_AUDCLK_I2SDAC_BCLK	14
+#define JH7100_AUDCLK_I2SDAC_BCLK_N	15
+#define JH7100_AUDCLK_I2SDAC_LRCLK	16
+#define JH7100_AUDCLK_I2S1_APB		17
+#define JH7100_AUDCLK_I2S1_BCLK		18
+#define JH7100_AUDCLK_I2S1_BCLK_N	19
+#define JH7100_AUDCLK_I2S1_LRCLK	20
+#define JH7100_AUDCLK_I2SDAC16K_APB	21
+#define JH7100_AUDCLK_APB0_BUS		22
+#define JH7100_AUDCLK_DMA1P_AHB		23
+#define JH7100_AUDCLK_USB_APB		24
+#define JH7100_AUDCLK_USB_LPM		25
+#define JH7100_AUDCLK_USB_STB		26
+#define JH7100_AUDCLK_APB_EN		27
+#define JH7100_AUDCLK_VAD_MEM		28
+
+#define JH7100_AUDCLK_END		29
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7100_AUDIO_H__ */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 2/7] clk: starfive: jh7100: Handle audio_div clock properly
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

It turns out the audio_div clock is a fractional divider where the
lowest byte of the ctrl register is the integer part of the divider and
the 2nd byte is the number of 100th added to the divider.

The children of this clock is used by the audio peripherals for their
sample rate clock, so round to the closest possible rate rather than
always rounding down like regular dividers.

Fixes: 4210be668a09 ("clk: starfive: Add JH7100 clock generator driver")
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 drivers/clk/starfive/clk-starfive-jh7100.c | 68 +++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
index db6a4dc203af..4b59338b5d7d 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -32,6 +32,13 @@
 #define JH7100_CLK_MUX_MASK	GENMASK(27, 24)
 #define JH7100_CLK_MUX_SHIFT	24
 #define JH7100_CLK_DIV_MASK	GENMASK(23, 0)
+#define JH7100_CLK_FRAC_MASK	GENMASK(15, 8)
+#define JH7100_CLK_FRAC_SHIFT	8
+#define JH7100_CLK_INT_MASK	GENMASK(7, 0)
+
+/* fractional divider min/max */
+#define JH7100_CLK_FRAC_MIN	100UL
+#define JH7100_CLK_FRAC_MAX	25599UL
 
 /* clock data */
 #define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = {		\
@@ -55,6 +62,13 @@
 	.parents = { [0] = _parent },					\
 }
 
+#define JH7100_FDIV(_idx, _name, _parent) [_idx] = {			\
+	.name = _name,							\
+	.flags = 0,							\
+	.max = JH7100_CLK_FRAC_MAX,					\
+	.parents = { [0] = _parent },					\
+}
+
 #define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = {		\
 	.name = _name,							\
 	.flags = 0,							\
@@ -225,7 +239,7 @@ static const struct {
 	JH7100__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
 		    JH7100_CLK_OSC_SYS,
 		    JH7100_CLK_USBPHY_PLLDIV25M),
-	JH7100__DIV(JH7100_CLK_AUDIO_DIV, "audio_div", 131072, JH7100_CLK_AUDIO_ROOT),
+	JH7100_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
 	JH7100_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
 	JH7100_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
 	JH7100_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
@@ -440,6 +454,49 @@ static int jh7100_clk_set_rate(struct clk_hw *hw,
 	return 0;
 }
 
+static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
+						 unsigned long parent_rate)
+{
+	struct jh7100_clk *clk = jh7100_clk_from(hw);
+	u32 reg = jh7100_clk_reg_get(clk);
+	unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
+			       ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
+
+	return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
+}
+
+static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
+{
+	unsigned long parent100 = 100 * req->best_parent_rate;
+	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
+	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
+				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
+	unsigned long result = parent100 / div100;
+
+	/* clamp the result as in jh7100_clk_determine_rate() above */
+	if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
+		result = parent100 / (div100 + 1);
+	if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
+		result = parent100 / (div100 - 1);
+
+	req->rate = result;
+	return 0;
+}
+
+static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
+				    unsigned long rate,
+				    unsigned long parent_rate)
+{
+	struct jh7100_clk *clk = jh7100_clk_from(hw);
+	unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
+				     JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
+	u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
+
+	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
+	return 0;
+}
+
 static u8 jh7100_clk_get_parent(struct clk_hw *hw)
 {
 	struct jh7100_clk *clk = jh7100_clk_from(hw);
@@ -526,6 +583,13 @@ static const struct clk_ops jh7100_clk_div_ops = {
 	.debug_init = jh7100_clk_debug_init,
 };
 
+static const struct clk_ops jh7100_clk_fdiv_ops = {
+	.recalc_rate = jh7100_clk_frac_recalc_rate,
+	.determine_rate = jh7100_clk_frac_determine_rate,
+	.set_rate = jh7100_clk_frac_set_rate,
+	.debug_init = jh7100_clk_debug_init,
+};
+
 static const struct clk_ops jh7100_clk_gdiv_ops = {
 	.enable = jh7100_clk_enable,
 	.disable = jh7100_clk_disable,
@@ -564,6 +628,8 @@ static const struct clk_ops *__init jh7100_clk_ops(u32 max)
 	if (max & JH7100_CLK_DIV_MASK) {
 		if (max & JH7100_CLK_ENABLE)
 			return &jh7100_clk_gdiv_ops;
+		if (max == JH7100_CLK_FRAC_MAX)
+			return &jh7100_clk_fdiv_ops;
 		return &jh7100_clk_div_ops;
 	}
 
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 1/7] clk: starfive: jh7100: Don't round divisor up twice
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel
In-Reply-To: <20220126173953.1016706-1-kernel@esmil.dk>

The problem is best illustrated by an example. Suppose a consumer wants
a 4MHz clock rate from a divider with a 10MHz parent. It would then
call

  clk_round_rate(clk, 4000000)

which would call into our determine_rate() callback that correctly
rounds up and finds that a divisor of 3 gives the highest possible
frequency below the requested 4MHz and returns 10000000 / 3 = 3333333Hz.

However the consumer would then call

  clk_set_rate(clk, 3333333)

but since 3333333 doesn't divide 10000000 evenly our set_rate() callback
would again round the divisor up and set it to 4 which results in an
unnecessarily low rate of 2.5MHz.

Fix it by using DIV_ROUND_CLOSEST in the set_rate() callback.

Fixes: 4210be668a09 ("clk: starfive: Add JH7100 clock generator driver")
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
 drivers/clk/starfive/clk-starfive-jh7100.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
index 25d31afa0f87..db6a4dc203af 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -399,22 +399,13 @@ static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
 	return div ? parent_rate / div : 0;
 }
 
-static unsigned long jh7100_clk_bestdiv(struct jh7100_clk *clk,
-					unsigned long rate, unsigned long parent)
-{
-	unsigned long max = clk->max_div;
-	unsigned long div = DIV_ROUND_UP(parent, rate);
-
-	return min(div, max);
-}
-
 static int jh7100_clk_determine_rate(struct clk_hw *hw,
 				     struct clk_rate_request *req)
 {
 	struct jh7100_clk *clk = jh7100_clk_from(hw);
 	unsigned long parent = req->best_parent_rate;
 	unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-	unsigned long div = jh7100_clk_bestdiv(clk, rate, parent);
+	unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
 	unsigned long result = parent / div;
 
 	/*
@@ -442,7 +433,8 @@ static int jh7100_clk_set_rate(struct clk_hw *hw,
 			       unsigned long parent_rate)
 {
 	struct jh7100_clk *clk = jh7100_clk_from(hw);
-	unsigned long div = jh7100_clk_bestdiv(clk, rate, parent_rate);
+	unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
+				  1UL, (unsigned long)clk->max_div);
 
 	jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
 	return 0;
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1 0/7] JH7100 Audio Clocks
From: Emil Renner Berthing @ 2022-01-26 17:39 UTC (permalink / raw)
  To: linux-clk, devicetree
  Cc: Emil Renner Berthing, Michael Turquette, Stephen Boyd,
	Rob Herring, Andy Shevchenko, Geert Uytterhoeven, Arnd Bergmann,
	Michael Zhu, Fu Wei, linux-kernel

This series add support for the audio clocks on the StarFive JH7100
RISC-V SoC, although the first two patches are fixes to the original
addition of the basic clock driver. At least the first fix may be
considered for 5.17.

It turns out the SoC has several memory ranges for different clocks, but
they all share the layout of the control registers. This could be
modelled in 3 ways:

1) Model all the clocks as a single peripheral with multiple memory
   ranges and have a single driver for them all. 
2) Model each memory range as different, but related peripherals with a
   single driver handling all of them.
3) Model each memory range as different peripherals with separate
   drivers that can share most code.

Although the first option would require less code this series implements
the 3rd option. The basic clock driver has to be built-in to boot the
SoC, so separate drivers for the other registers means less code needs
to be built-in and can be left as loadable modules.

Emil Renner Berthing (7):
  clk: starfive: jh7100: Don't round divisor up twice
  clk: starfive: jh7100: Handle audio_div clock properly
  dt-bindings: clock: Add JH7100 audio clock definitions
  dt-bindings: clock: Add starfive,jh7100-audclk bindings
  clk: starfive: jh7100: Make hw clock implementation reusable
  clk: starfive: jh7100: Support more clock types
  clk: starfive: Add JH7100 audio clock driver

 .../clock/starfive,jh7100-audclk.yaml         |  57 ++++++
 MAINTAINERS                                   |   8 +-
 drivers/clk/starfive/Kconfig                  |   8 +
 drivers/clk/starfive/Makefile                 |   1 +
 .../clk/starfive/clk-starfive-jh7100-audio.c  | 170 +++++++++++++++++
 drivers/clk/starfive/clk-starfive-jh7100.c    | 176 +++++++++---------
 drivers/clk/starfive/clk-starfive-jh7100.h    | 112 +++++++++++
 .../dt-bindings/clock/starfive-jh7100-audio.h |  41 ++++
 8 files changed, 482 insertions(+), 91 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7100-audio.c
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7100.h
 create mode 100644 include/dt-bindings/clock/starfive-jh7100-audio.h

-- 
2.34.1


^ permalink raw reply

* Aw: [PATCH 27/27] drm: rockchip: Add VOP2 driver
From: Frank Wunderlich @ 2022-01-26 17:10 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: dri-devel, linux-arm-kernel, linux-rockchip, devicetree, kernel,
	Andy Yan, Benjamin Gaignard, Michael Riesch, Sandy Huang,
	Heiko Stübner, Peter Geis, Sascha Hauer
In-Reply-To: <20220126145549.617165-28-s.hauer@pengutronix.de>

Hi Sascha

tested full series on Bananapi r2 Pro V0 prototype (rk3568)

4K@60Hz
1080p@60Hz

both look good

Tested-By: Frank Wunderlich <frank-w@public-files.de>

regards Frank

^ permalink raw reply

* Re: [PATCH 1/5] ASoC: tegra: Update AHUB driver for Tegra234
From: Mark Brown @ 2022-01-26 16:50 UTC (permalink / raw)
  To: Sameer Pujar
  Cc: lgirdwood, tiwai, perex, robh+dt, thierry.reding, jonathanh,
	mkumard, devicetree, linux-tegra, linux-kernel, alsa-devel
In-Reply-To: <1643100491-5398-2-git-send-email-spujar@nvidia.com>

[-- Attachment #1: Type: text/plain, Size: 361 bytes --]

On Tue, Jan 25, 2022 at 02:18:07PM +0530, Sameer Pujar wrote:
> From: Mohan Kumar <mkumard@nvidia.com>
> 
> The register offsets of switches connecting various AHUB internal
> modules have changed from previous chip. Address this variation by
> making use of Tegra234 based compatible.

This doesn't apply against current code, please check and resend.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* RE: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
From: Alim Akhtar @ 2022-01-26 16:47 UTC (permalink / raw)
  To: 'Krzysztof Kozlowski', linux-arm-kernel, linux-kernel
  Cc: soc, linux-clk, devicetree, olof, arnd, linus.walleij,
	catalin.marinas, robh+dt, s.nawrocki, linux-samsung-soc,
	pankaj.dubey, sboyd
In-Reply-To: <4c029f92-ece7-78c1-e64b-cbe438b45a5f@canonical.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski@canonical.com]
>Sent: Wednesday, January 26, 2022 2:50 PM
>To: Alim Akhtar <alim.akhtar@samsung.com>; linux-arm-
>kernel@lists.infradead.org; linux-kernel@vger.kernel.org
>Cc: soc@kernel.org; linux-clk@vger.kernel.org; devicetree@vger.kernel.org;
>olof@lixom.net; arnd@arndb.de; linus.walleij@linaro.org;
>catalin.marinas@arm.com; robh+dt@kernel.org; s.nawrocki@samsung.com;
>linux-samsung-soc@vger.kernel.org; pankaj.dubey@samsung.com;
>sboyd@kernel.org
>Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
>
>On 26/01/2022 07:50, Alim Akhtar wrote:
>> Hi Krzysztof
>>
>>> -----Original Message-----
>>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski@canonical.com]
>>> Sent: Tuesday, January 25, 2022 10:56 PM
>>> To: Alim Akhtar <alim.akhtar@samsung.com>; linux-arm-
>>> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
>>> Cc: soc@kernel.org; linux-clk@vger.kernel.org;
>>> devicetree@vger.kernel.org; olof@lixom.net; arnd@arndb.de;
>>> linus.walleij@linaro.org; catalin.marinas@arm.com;
>>> robh+dt@kernel.org; s.nawrocki@samsung.com;
>>> linux-samsung-soc@vger.kernel.org; pankaj.dubey@samsung.com;
>>> sboyd@kernel.org
>>> Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving
>>> (FSD) SoC
>>>
>>> On 25/01/2022 18:12, Krzysztof Kozlowski wrote:
>>>> On 24/01/2022 15:16, Alim Akhtar wrote:
>>>>> Adds basic support for the Tesla Full Self-Driving (FSD) SoC. This
>>>>> SoC contains three clusters of four Cortex-A72 CPUs, as well as
>>>>> several IPs.
>>>>>
>>>>> Patches 1 to 9 provide support for the clock controller (which is
>>>>> designed similarly to Exynos SoCs).
>>>>>
>>>>> The remaining changes provide pinmux support, initial device tree
>support.
>>>>>
>>>>> - Changes since v4
>>>>> * fixed 'make dtbs_check' warnings on patch 14/16
>>>>>
>>>>> - Changes since v3
>>>>> * Addressed Stefen's review comments on patch 14/16
>>>>> * Fixed kernel test robot warning on patch 04/16
>>>>> * rebsaed this series on Krzysztof's pinmux new binding schema work
>>>>> [1]
>>>>>
>>>>> - Changes since v2
>>>>> * Addressed Krzysztof's and Stephen's review comments
>>>>> * Added Reviewed-by and Acked-by tags
>>>>> * Rebased on next-20220120
>>>>>
>>>>> - Changes since v1
>>>>> * fixed make dt_binding_check error as pointed by Rob
>>>>> * Addressed Krzysztof's and Rob's review comments
>>>>> * Added Reviewed-by and Acked-by tags
>>>>> * Dropped SPI, MCT and ADC from this series (to be posted in small
>>>>> sets)
>>>>>
>>>>> NOTE: These patches are based on Krzysztof's pinmux for-next branch
>>>>> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850
>>>>> and
>>>>> ExynosAutov9 wake-ups") [1]
>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
>>>>> /l
>>>>> og/?h=for-next
>>>>>
>>>>>
>>>>
>>>> Thanks, applied DTS/soc and pinctrl patches.
>>>>
>>>> I expect Sylwester will pick up the clock ones. Otherwise please let
>>>> me know to pick it up as well.
>>>
>>> I forgot that clock macros are used in DTS. This does not compile and
>>> I cannot take drivers into DTS branch.
>>>
>>> Alim,
>>> DTS changes dropped. Please resend with the same trick we did for
>>> Exynos850 board - hard-coded clock IDs as defines. See:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git/diff/a
>>> rch/arm6
>>> 4/boot/dts/exynos/exynos850.dtsi?h=samsung-dt64-5.17-
>>> 2&id=e3493220fd3e474abcdcefbe14fb60485097ce06
>>>
>> Ok, I will resend patch 14 and 15 (DTS changes) only as suggested above.
>
>I see Sylwester acked clock patches, so I will take them. No need to resend, I'll
>organize the patches so they will compile.
>
Awesome, thanks Krzysztof and Sylwester

>
>Best regards,
>Krzysztof


^ permalink raw reply

* [PATCH v2 net-next 5/5] dt-bindings: net: xgmac_mdio: Add "clock-frequency" and "suppress-preamble"
From: Tobias Waldekranz @ 2022-01-26 16:05 UTC (permalink / raw)
  To: davem, kuba
  Cc: netdev, Andrew Lunn, Madalin Bucur, Rob Herring, devicetree,
	linux-kernel
In-Reply-To: <20220126160544.1179489-1-tobias@waldekranz.com>

The driver now supports the standard "clock-frequency" and
"suppress-preamble" properties, do document them in the binding
description.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 .../devicetree/bindings/net/fsl-fman.txt      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt
index cd5288fb4318..801efc7d6818 100644
--- a/Documentation/devicetree/bindings/net/fsl-fman.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -388,6 +388,25 @@ PROPERTIES
 		Value type: <prop-encoded-array>
 		Definition: A standard property.
 
+- clocks
+		Usage: optional
+		Value type: <phandle>
+		Definition: A reference to the input clock of the controller
+		from which the MDC frequency is derived.
+
+- clock-frequency
+		Usage: optional
+		Value type: <u32>
+		Definition: Specifies the external MDC frequency, in Hertz, to
+		be used. Requires that the input clock is specified in the
+		"clocks" property. See also: mdio.yaml.
+
+- suppress-preamble
+		Usage: optional
+		Value type: <boolean>
+		Definition: Disable generation of preamble bits. See also:
+		mdio.yaml.
+
 - interrupts
 		Usage: required for external MDIO
 		Value type: <prop-encoded-array>
-- 
2.25.1


^ permalink raw reply related

* [PATCH v2 net-next 1/5] dt-bindings: net: xgmac_mdio: Remove unsupported "bus-frequency"
From: Tobias Waldekranz @ 2022-01-26 16:05 UTC (permalink / raw)
  To: davem, kuba
  Cc: netdev, Andrew Lunn, Madalin Bucur, Rob Herring, Scott Wood,
	Shaohui Xie, devicetree, linux-kernel
In-Reply-To: <20220126160544.1179489-1-tobias@waldekranz.com>

This property has never been supported by the driver. The kernel has
settled on "clock-frequency" as the standard name for this binding, so
once that is supported we will document that instead.

Fixes: 7f93c9d90f4d ("power/fsl: add MDIO dt binding for FMan")
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/devicetree/bindings/net/fsl-fman.txt | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt
index 020337f3c05f..cd5288fb4318 100644
--- a/Documentation/devicetree/bindings/net/fsl-fman.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -388,15 +388,6 @@ PROPERTIES
 		Value type: <prop-encoded-array>
 		Definition: A standard property.
 
-- bus-frequency
-		Usage: optional
-		Value type: <u32>
-		Definition: Specifies the external MDIO bus clock speed to
-		be used, if different from the standard 2.5 MHz.
-		This may be due to the standard speed being unsupported (e.g.
-		due to a hardware problem), or to advertise that all relevant
-		components in the system support a faster speed.
-
 - interrupts
 		Usage: required for external MDIO
 		Value type: <prop-encoded-array>
-- 
2.25.1


^ permalink raw reply related

* Re: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
From: Peter Geis @ 2022-01-26 16:04 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: dri-devel, arm-mail-list, open list:ARM/Rockchip SoC...,
	devicetree, kernel, Andy Yan, Benjamin Gaignard, Michael Riesch,
	Sandy Huang, Heiko Stübner
In-Reply-To: <20220126145549.617165-22-s.hauer@pengutronix.de>

On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> Add support for the HDMI port found on RK3568.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index 4008bd666d01..e38fb223e9b8 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -10,7 +10,6 @@
>  #include <dt-bindings/pinctrl/rockchip.h>
>  #include <dt-bindings/power/rk3568-power.h>
>  #include <dt-bindings/soc/rockchip,boot-mode.h>
> -#include <dt-bindings/soc/rockchip,vop2.h>
>  #include <dt-bindings/thermal/thermal.h>
>
>  / {
> @@ -502,6 +501,42 @@ vop_mmu: iommu@fe043e00 {
>                 status = "disabled";
>         };
>
> +       hdmi: hdmi@fe0a0000 {
> +               compatible = "rockchip,rk3568-dw-hdmi";
> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&cru PCLK_HDMI_HOST>,
> +                        <&cru CLK_HDMI_SFR>,
> +                        <&cru CLK_HDMI_CEC>,
> +                        <&pmucru CLK_HDMI_REF>,
> +                        <&cru HCLK_VOP>;
> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;

I looked into CEC support here, and it seems that it does work with one change.
Please add the two following lines to your patch:
assigned-clocks = <&cru CLK_HDMI_CEC>;
assigned-clock-rates = <32768>;

The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
function.

> +               power-domains = <&power RK3568_PD_VO>;
> +               reg-io-width = <4>;
> +               rockchip,grf = <&grf>;
> +               #sound-dai-cells = <0>;
> +               status = "disabled";
> +
> +               ports {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       hdmi_in: port@0 {
> +                               reg = <0>;
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +                       };
> +
> +                       hdmi_out: port@1 {
> +                               reg = <1>;
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +                       };
> +               };
> +       };
> +
>         qos_gpu: qos@fe128000 {
>                 compatible = "rockchip,rk3568-qos", "syscon";
>                 reg = <0x0 0xfe128000 0x0 0x20>;
> --
> 2.30.2
>

^ permalink raw reply

* [PATCH v2] dt-bindings: timer: Convert faraday,fttmr010 to yaml
From: Corentin Labbe @ 2022-01-26 16:00 UTC (permalink / raw)
  To: daniel.lezcano, robh+dt, tglx; +Cc: devicetree, linux-kernel, Corentin Labbe

Converts timer/faraday,fttmr010.txt to yaml.

Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
Changes since v1:
- added moxart example
- relaxed some contraints as driver only support one clock and one
  interrupt (as used by moxa,moxart-timer)

 .../bindings/timer/faraday,fttmr010.txt       | 38 --------
 .../bindings/timer/faraday,fttmr010.yaml      | 88 +++++++++++++++++++
 2 files changed, 88 insertions(+), 38 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
 create mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml

diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
deleted file mode 100644
index 3cb2f4c98d64..000000000000
--- a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-Faraday Technology timer
-
-This timer is a generic IP block from Faraday Technology, embedded in the
-Cortina Systems Gemini SoCs and other designs.
-
-Required properties:
-
-- compatible : Must be one of
-  "faraday,fttmr010"
-  "cortina,gemini-timer", "faraday,fttmr010"
-  "moxa,moxart-timer", "faraday,fttmr010"
-  "aspeed,ast2400-timer"
-  "aspeed,ast2500-timer"
-  "aspeed,ast2600-timer"
-
-- reg : Should contain registers location and length
-- interrupts : Should contain the three timer interrupts usually with
-  flags for falling edge
-
-Optionally required properties:
-
-- clocks : a clock to provide the tick rate for "faraday,fttmr010"
-- clock-names : should be "EXTCLK" and "PCLK" for the external tick timer
-  and peripheral clock respectively, for "faraday,fttmr010"
-- syscon : a phandle to the global Gemini system controller if the compatible
-  type is "cortina,gemini-timer"
-
-Example:
-
-timer@43000000 {
-	compatible = "faraday,fttmr010";
-	reg = <0x43000000 0x1000>;
-	interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */
-		   <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */
-		   <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */
-	clocks = <&extclk>, <&pclk>;
-	clock-names = "EXTCLK", "PCLK";
-};
diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml b/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml
new file mode 100644
index 000000000000..db9fb171ea49
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/faraday,fttmr010.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Faraday Technology timer
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  This timer is a generic IP block from Faraday Technology, embedded in the
+  Cortina Systems Gemini SoCs and other designs.
+
+properties:
+  compatible:
+    oneOf:
+      - const: faraday,fttmr010
+      - items:
+          - const: cortina,gemini-timer
+          - const: faraday,fttmr010
+      - items:
+          - const: moxa,moxart-timer
+          - const: faraday,fttmr010
+      - const: aspeed,ast2400-timer
+      - const: aspeed,ast2500-timer
+      - const: aspeed,ast2600-timer
+
+  reg:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 3
+    description: Should contain the three timer interrupts usually with flags for falling edge
+
+  clocks:
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: "PCLK"
+      - const: "EXTCLK"
+
+  syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    /* taken from arch/arm/boot/dts/gemini.dtsi */
+    timer@43000000 {
+      compatible = "faraday,fttmr010";
+      reg = <0x43000000 0x1000>;
+      interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */
+                   <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */
+                   <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */
+      clocks = <&extclk>, <&pclk>;
+      clock-names = "PCLK", "EXTCLK";
+      syscon = <&syscon>;
+    };
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    /* taken from arch/arm/boot/dts/moxart.dtsi */
+    timer: timer@98400000 {
+      compatible = "moxa,moxart-timer", "faraday,fttmr010";
+      reg = <0x98400000 0x42>;
+      interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+      clocks = <&clk_apb>;
+      clock-names = "PCLK";
+    };
+...
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 07/27] drm/rockchip: dw_hdmi: Use auto-generated tables
From: Doug Anderson @ 2022-01-26 15:54 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: dri-devel, Linux ARM, open list:ARM/Rockchip SoC...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Sascha Hauer, Andy Yan, Benjamin Gaignard, Michael Riesch,
	Sandy Huang, Heiko Stübner, Peter Geis, Yakir Yang,
	Stéphane Marchesin
In-Reply-To: <20220126145549.617165-8-s.hauer@pengutronix.de>

Hi,

On Wed, Jan 26, 2022 at 6:58 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> From: Douglas Anderson <dianders at chromium.org>
>
> The previous tables for mpll_cfg and curr_ctrl were created using the
> 20-pages of example settings provided by the PHY vendor.  Those
> example settings weren't particularly dense, so there were places
> where we were guessing what the settings would be for 10-bit and
> 12-bit (not that we use those anyway).  It was also always a lot of
> extra work every time we wanted to add a new clock rate since we had
> to cross-reference several tables.
>
> In <http://crosreview.com/285855> I've gone through the work to figure

The `crosreview.com` syntax doesn't seem to work anymore. Could maybe
update to https://crrev.com/c/285855 ?

> out how to generate this table automatically.  Let's now use the
> automatically generated table and then we'll never need to look at it
> again.
>
> We only support 8-bit mode right now and only support a small number
> of clock rates and and I've verified that the only 8-bit rate that was
> affected was 148.5.  That mode appears to have been wrong in the old
> table.
>
> Changes since v3:
> - new patch
>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>

Should probably change the "at" to "@" ?

> Reviewed-by: Stéphane Marchesin <marcheu at chromium.org>

In general shouldn't carry downstream reviews when posting upstream
unless you're certain that the person intended it...


It's been a long time, but in general I think I was fairly confident
in the numbers that my script pumped out, at least given the caveat of
no pixel repetition and 8-bit only. That being said, I didn't have any
inside knowledge of the hardware and just figured out formulas that
seemed to match the table that I had. YMMV.

I'll also say that when I did a rebase of veyron (rk3288-based
Chromebook) to 4.19 about 2.5 years ago, I ended up squashing several
of these patches into 1. That can be found at
<https://crrev.com/c/1661056>. That also has details about why some of
these patches never made it upstream. The main reason, at least in the
case of rk3288, was the PLL sharing problem that nobody ever solved.
rk3288 didn't have quite enough PLLs and thus, if you were using both
VOPs, one of the VOPs was going to be severely limited in what pixel
clocks it could make. There was no framework deciding which VOP should
be limited and how the system should react to this...


In any case, I'm pretty far disconnected from all this stuff now, but
I wish you the best of luck in trying to get it all solved!

-Doug

^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu device
From: Robin Murphy @ 2022-01-26 15:54 UTC (permalink / raw)
  To: Sergiy Kibrik
  Cc: Stefano Stabellini, Julien Grall, Oleksandr Tyshchenko,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	xen-devel@lists.xenproject.org
In-Reply-To: <PAXPR03MB81144A63E18CAF10E785E2A7F0209@PAXPR03MB8114.eurprd03.prod.outlook.com>

On 2022-01-26 15:09, Sergiy Kibrik wrote:
> Hi Robin,
> 
>>
>> This could break Linux guests, since depending on the deferred probe
>> timeout setting it could lead to drivers never probing because the "IOMMU"
>> never becomes available.
>>
> 
> I've noticed no deferred probe timeouts when booting with this patch. Could you please explain more on how this would break guests?

Right now I think it would actually require command-line intervention, 
e.g. "fw_devlink=on" or "deferred_probe_timeout=3600" (with modules 
enabled for the latter to take full effect), but I'm wary of the 
potential for future config options to control those behaviours by default.

Robin.

> Thank you!
> 
>   -- Sergiy

^ permalink raw reply

* Re: [PATCH 09/27] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always
From: Doug Anderson @ 2022-01-26 15:42 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: dri-devel,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Benjamin Gaignard, Peter Geis, Sandy Huang,
	open list:ARM/Rockchip SoC..., Michael Riesch, Sascha Hauer,
	Yakir Yang, Andy Yan, Linux ARM
In-Reply-To: <20220126145549.617165-10-s.hauer@pengutronix.de>

Hi,

On Wed, Jan 26, 2022 at 6:58 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> From: Douglas Anderson <dianders@chromium.org>
>
> Jitter was improved by lowering the MPLL bandwidth to account for high
> frequency noise in the rk3288 PLL.  In each case MPLL bandwidth was
> lowered only enough to get us a comfortable margin.  We believe that
> lowering the bandwidth like this is safe given sufficient testing.
>
> Changes since v3:
> - new patch
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> Signed-off-by: Yakir Yang <ykk@rock-chips.com>
> (am from https://patchwork.kernel.org/patch/9223301/)

Probably remove the "am from" line? It's not standard in upstream and
that link doesn't seem to go anywhere anymore...


> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++--------------
>  1 file changed, 2 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index c44eb4d2e2d5..77f82a4fd027 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -176,20 +176,8 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
>  static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
>         /*      pixelclk    bpp8    bpp10   bpp12 */
>         {
> -               40000000,  { 0x0018, 0x0018, 0x0018 },
> -       }, {
> -               65000000,  { 0x0028, 0x0028, 0x0028 },
> -       }, {
> -               66000000,  { 0x0038, 0x0038, 0x0038 },
> -       }, {
> -               74250000,  { 0x0028, 0x0038, 0x0038 },
> -       }, {
> -               83500000,  { 0x0028, 0x0038, 0x0038 },
> -       }, {
> -               146250000, { 0x0038, 0x0038, 0x0038 },
> -       }, {
> -               148500000, { 0x0000, 0x0038, 0x0038 },
> -       }, {
> +               600000000, { 0x0000, 0x0000, 0x0000 },
> +       },  {

This is what we did for rk3288. I can't personally vouch for the
effects on other SoCs.

-Doug

^ permalink raw reply

* [PATCH v10 1/1] clk: microchip: Add driver for Microchip PolarFire SoC
From: conor.dooley @ 2022-01-26 15:40 UTC (permalink / raw)
  To: mturquette, sboyd, linux-clk, robh+dt, devicetree
  Cc: krzysztof.kozlowski, geert, david.abdurachmanov, palmer,
	daire.mcnamara, cyril.jean, conor.dooley, Padmarao Bengari
In-Reply-To: <20220126154003.3797323-1-conor.dooley@microchip.com>

From: Daire McNamara <daire.mcnamara@microchip.com>

Add support for clock configuration on Microchip PolarFire SoC

Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>

Co-developed-by: Padmarao Bengari <padmarao.begari@microchip.com>
Signed-off-by: Padmarao Bengari <padmarao.begari@microchip.com>
Signed-off-by: Daire McNamara <daire.mcnamara@microchip.com>
Co-developed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/clk/Kconfig              |   4 +-
 drivers/clk/Makefile             |   2 +-
 drivers/clk/microchip/Kconfig    |  10 +
 drivers/clk/microchip/Makefile   |   1 +
 drivers/clk/microchip/clk-mpfs.c | 382 +++++++++++++++++++++++++++++++
 5 files changed, 395 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/microchip/Kconfig
 create mode 100644 drivers/clk/microchip/clk-mpfs.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index ad4256d54361..678a865021e2 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -330,9 +330,6 @@ config COMMON_CLK_PXA
 	help
 	  Support for the Marvell PXA SoC.
 
-config COMMON_CLK_PIC32
-	def_bool COMMON_CLK && MACH_PIC32
-
 config COMMON_CLK_OXNAS
 	bool "Clock driver for the OXNAS SoC Family"
 	depends on ARCH_OXNAS || COMPILE_TEST
@@ -407,6 +404,7 @@ source "drivers/clk/keystone/Kconfig"
 source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mstar/Kconfig"
+source "drivers/clk/microchip/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/pistachio/Kconfig"
 source "drivers/clk/qcom/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 16e588630472..61271926b16b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -91,7 +91,7 @@ obj-$(CONFIG_ARCH_KEYSTONE)		+= keystone/
 obj-$(CONFIG_MACH_LOONGSON32)		+= loongson1/
 obj-y					+= mediatek/
 obj-$(CONFIG_ARCH_MESON)		+= meson/
-obj-$(CONFIG_MACH_PIC32)		+= microchip/
+obj-y					+= microchip/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
 endif
diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig
new file mode 100644
index 000000000000..e1af380d8c9c
--- /dev/null
+++ b/drivers/clk/microchip/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config COMMON_CLK_PIC32
+	def_bool COMMON_CLK && MACH_PIC32
+
+config MCHP_CLK_MPFS
+	bool "Clk driver for PolarFire SoC"
+	depends on (RISCV && SOC_MICROCHIP_POLARFIRE) || COMPILE_TEST
+	help
+	  Supports Clock Configuration for PolarFire SoC
\ No newline at end of file
diff --git a/drivers/clk/microchip/Makefile b/drivers/clk/microchip/Makefile
index f34b247e870f..5fa6dcf30a9a 100644
--- a/drivers/clk/microchip/Makefile
+++ b/drivers/clk/microchip/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_COMMON_CLK_PIC32) += clk-core.o
 obj-$(CONFIG_PIC32MZDA) += clk-pic32mzda.o
+obj-$(CONFIG_MCHP_CLK_MPFS) += clk-mpfs.o
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c
new file mode 100644
index 000000000000..eec461b906d8
--- /dev/null
+++ b/drivers/clk/microchip/clk-mpfs.c
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Daire McNamara,<daire.mcnamara@microchip.com>
+ * Copyright (C) 2020 Microchip Technology Inc.  All rights reserved.
+ */
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/microchip,mpfs-clock.h>
+
+/* address offset of control registers */
+#define REG_CLOCK_CONFIG_CR	0x08u
+#define REG_SUBBLK_CLOCK_CR	0x84u
+#define REG_SUBBLK_RESET_CR	0x88u
+
+struct mpfs_clock_data {
+	void __iomem *base;
+	struct clk_hw_onecell_data hw_data;
+};
+
+struct mpfs_cfg_clock {
+	const struct clk_div_table *table;
+	unsigned int id;
+	u8 shift;
+	u8 width;
+};
+
+struct mpfs_cfg_hw_clock {
+	struct mpfs_cfg_clock cfg;
+	void __iomem *sys_base;
+	struct clk_hw hw;
+	struct clk_init_data init;
+};
+
+#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
+
+struct mpfs_periph_clock {
+	unsigned int id;
+	u8 shift;
+};
+
+struct mpfs_periph_hw_clock {
+	struct mpfs_periph_clock periph;
+	void __iomem *sys_base;
+	struct clk_hw hw;
+};
+
+#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
+
+/*
+ * mpfs_clk_lock prevents anything else from writing to the
+ * mpfs clk block while a software locked register is being written.
+ */
+static DEFINE_SPINLOCK(mpfs_clk_lock);
+
+static const struct clk_parent_data mpfs_cfg_parent[] = {
+	{ .index = 0 },
+};
+
+static const struct clk_div_table mpfs_div_cpu_axi_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 0, 0 }
+};
+
+static const struct clk_div_table mpfs_div_ahb_table[] = {
+	{ 1, 2 }, { 2, 4}, { 3, 8 },
+	{ 0, 0 }
+};
+
+static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
+{
+	struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+	struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+	void __iomem *base_addr = cfg_hw->sys_base;
+	u32 val;
+
+	val = readl_relaxed(base_addr + REG_CLOCK_CONFIG_CR) >> cfg->shift;
+	val &= clk_div_mask(cfg->width);
+
+	return prate / (1u << val);
+}
+
+static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate)
+{
+	struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+	struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+
+	return divider_round_rate(hw, rate, prate, cfg->table, cfg->width, CLK_DIVIDER_ONE_BASED);
+}
+
+static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
+{
+	struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+	struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+	void __iomem *base_addr = cfg_hw->sys_base;
+	unsigned long flags;
+	u32 val;
+	int divider_setting;
+
+	divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width,
+					  CLK_DIVIDER_ONE_BASED);
+
+	if (divider_setting < 0)
+		return divider_setting;
+
+	spin_lock_irqsave(&mpfs_clk_lock, flags);
+
+	val = readl_relaxed(base_addr + REG_CLOCK_CONFIG_CR);
+	val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
+	val |= divider_setting << cfg->shift;
+	writel_relaxed(val, base_addr + REG_CLOCK_CONFIG_CR);
+
+	spin_unlock_irqrestore(&mpfs_clk_lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops mpfs_clk_cfg_ops = {
+	.recalc_rate = mpfs_cfg_clk_recalc_rate,
+	.round_rate = mpfs_cfg_clk_round_rate,
+	.set_rate = mpfs_cfg_clk_set_rate,
+};
+
+#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags) {		\
+	.cfg.id = _id,								\
+	.cfg.shift = _shift,							\
+	.cfg.width = _width,							\
+	.cfg.table = _table,							\
+	.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, &mpfs_clk_cfg_ops,	\
+					    _flags),				\
+}
+
+static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
+	CLK_CFG(CLK_CPU, "clk_cpu", mpfs_cfg_parent, 0, 2, mpfs_div_cpu_axi_table, 0),
+	CLK_CFG(CLK_AXI, "clk_axi", mpfs_cfg_parent, 2, 2, mpfs_div_cpu_axi_table, 0),
+	CLK_CFG(CLK_AHB, "clk_ahb", mpfs_cfg_parent, 4, 2, mpfs_div_ahb_table, 0),
+};
+
+static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw,
+				 void __iomem *sys_base)
+{
+	cfg_hw->sys_base = sys_base;
+
+	return devm_clk_hw_register(dev, &cfg_hw->hw);
+}
+
+static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hws,
+				  unsigned int num_clks, struct mpfs_clock_data *data)
+{
+	void __iomem *sys_base = data->base;
+	unsigned int i, id;
+	int ret;
+
+	for (i = 0; i < num_clks; i++) {
+		struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
+
+		ret = mpfs_clk_register_cfg(dev, cfg_hw, sys_base);
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
+					     cfg_hw->cfg.id);
+
+		id = cfg_hws[i].cfg.id;
+		data->hw_data.hws[id] = &cfg_hw->hw;
+	}
+
+	return 0;
+}
+
+static int mpfs_periph_clk_enable(struct clk_hw *hw)
+{
+	struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+	struct mpfs_periph_clock *periph = &periph_hw->periph;
+	void __iomem *base_addr = periph_hw->sys_base;
+	u32 reg, val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mpfs_clk_lock, flags);
+
+	reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
+	val = reg & ~(1u << periph->shift);
+	writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR);
+
+	reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+	val = reg | (1u << periph->shift);
+	writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
+
+	spin_unlock_irqrestore(&mpfs_clk_lock, flags);
+
+	return 0;
+}
+
+static void mpfs_periph_clk_disable(struct clk_hw *hw)
+{
+	struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+	struct mpfs_periph_clock *periph = &periph_hw->periph;
+	void __iomem *base_addr = periph_hw->sys_base;
+	u32 reg, val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mpfs_clk_lock, flags);
+
+	reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
+	val = reg | (1u << periph->shift);
+	writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR);
+
+	reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+	val = reg & ~(1u << periph->shift);
+	writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR);
+
+	spin_unlock_irqrestore(&mpfs_clk_lock, flags);
+}
+
+static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
+{
+	struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+	struct mpfs_periph_clock *periph = &periph_hw->periph;
+	void __iomem *base_addr = periph_hw->sys_base;
+	u32 reg;
+
+	reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR);
+	if ((reg & (1u << periph->shift)) == 0u) {
+		reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR);
+		if (reg & (1u << periph->shift))
+			return 1;
+	}
+
+	return 0;
+}
+
+static const struct clk_ops mpfs_periph_clk_ops = {
+	.enable = mpfs_periph_clk_enable,
+	.disable = mpfs_periph_clk_disable,
+	.is_enabled = mpfs_periph_clk_is_enabled,
+};
+
+#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) {			\
+	.periph.id = _id,							\
+	.periph.shift = _shift,							\
+	.hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops,		\
+				  _flags),					\
+}
+
+#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw)
+
+/*
+ * Critical clocks:
+ * - CLK_ENVM: reserved by hart software services (hss) superloop monitor/m mode interrupt
+ *   trap handler
+ * - CLK_MMUART0: reserved by the hss
+ * - CLK_DDRC: provides clock to the ddr subsystem
+ * - CLK_FICx: these provide clocks for sections of the fpga fabric, disabling them would
+ *   cause the fabric to go into reset
+ */
+
+static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
+	CLK_PERIPH(CLK_ENVM, "clk_periph_envm", PARENT_CLK(AHB), 0, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0),
+	CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0),
+	CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0),
+	CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(AHB), 4, 0),
+	CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0),
+	CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0),
+	CLK_PERIPH(CLK_MMUART3, "clk_periph_mmuart3", PARENT_CLK(AHB), 8, 0),
+	CLK_PERIPH(CLK_MMUART4, "clk_periph_mmuart4", PARENT_CLK(AHB), 9, 0),
+	CLK_PERIPH(CLK_SPI0, "clk_periph_spi0", PARENT_CLK(AHB), 10, 0),
+	CLK_PERIPH(CLK_SPI1, "clk_periph_spi1", PARENT_CLK(AHB), 11, 0),
+	CLK_PERIPH(CLK_I2C0, "clk_periph_i2c0", PARENT_CLK(AHB), 12, 0),
+	CLK_PERIPH(CLK_I2C1, "clk_periph_i2c1", PARENT_CLK(AHB), 13, 0),
+	CLK_PERIPH(CLK_CAN0, "clk_periph_can0", PARENT_CLK(AHB), 14, 0),
+	CLK_PERIPH(CLK_CAN1, "clk_periph_can1", PARENT_CLK(AHB), 15, 0),
+	CLK_PERIPH(CLK_USB, "clk_periph_usb", PARENT_CLK(AHB), 16, 0),
+	CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, 0),
+	CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", PARENT_CLK(AHB), 19, 0),
+	CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", PARENT_CLK(AHB), 20, 0),
+	CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0),
+	CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", PARENT_CLK(AHB), 22, 0),
+	CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", PARENT_CLK(AHB), 23, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", PARENT_CLK(AHB), 24, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", PARENT_CLK(AHB), 25, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", PARENT_CLK(AHB), 26, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", PARENT_CLK(AHB), 27, CLK_IS_CRITICAL),
+	CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", PARENT_CLK(AHB), 28, 0),
+	CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0),
+};
+
+static int mpfs_clk_register_periph(struct device *dev, struct mpfs_periph_hw_clock *periph_hw,
+				    void __iomem *sys_base)
+{
+	periph_hw->sys_base = sys_base;
+
+	return devm_clk_hw_register(dev, &periph_hw->hw);
+}
+
+static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_clock *periph_hws,
+				     int num_clks, struct mpfs_clock_data *data)
+{
+	void __iomem *sys_base = data->base;
+	unsigned int i, id;
+	int ret;
+
+	for (i = 0; i < num_clks; i++) {
+		struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
+
+		ret = mpfs_clk_register_periph(dev, periph_hw, sys_base);
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
+					     periph_hw->periph.id);
+
+		id = periph_hws[i].periph.id;
+		data->hw_data.hws[id] = &periph_hw->hw;
+	}
+
+	return 0;
+}
+
+static int mpfs_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mpfs_clock_data *clk_data;
+	unsigned int num_clks;
+	int ret;
+
+	/* CLK_RESERVED is not part of cfg_clks nor periph_clks, so add 1 */
+	num_clks = ARRAY_SIZE(mpfs_cfg_clks) + ARRAY_SIZE(mpfs_periph_clks) + 1;
+
+	clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws, num_clks), GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(clk_data->base))
+		return PTR_ERR(clk_data->base);
+
+	clk_data->hw_data.num = num_clks;
+
+	ret = mpfs_clk_register_cfgs(dev, mpfs_cfg_clks, ARRAY_SIZE(mpfs_cfg_clks), clk_data);
+	if (ret)
+		return ret;
+
+	ret = mpfs_clk_register_periphs(dev, mpfs_periph_clks, ARRAY_SIZE(mpfs_periph_clks),
+					clk_data);
+	if (ret)
+		return ret;
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+static const struct of_device_id mpfs_clk_of_match_table[] = {
+	{ .compatible = "microchip,mpfs-clkcfg", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mpfs_clk_match_table);
+
+static struct platform_driver mpfs_clk_driver = {
+	.probe = mpfs_clk_probe,
+	.driver	= {
+		.name = "microchip-mpfs-clkcfg",
+		.of_match_table = mpfs_clk_of_match_table,
+	},
+};
+
+static int __init clk_mpfs_init(void)
+{
+	return platform_driver_register(&mpfs_clk_driver);
+}
+core_initcall(clk_mpfs_init);
+
+static void __exit clk_mpfs_exit(void)
+{
+	platform_driver_unregister(&mpfs_clk_driver);
+}
+module_exit(clk_mpfs_exit);
+
+MODULE_DESCRIPTION("Microchip PolarFire SoC Clock Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.32.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox