devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arturs Artamonovs via B4 Relay <devnull+arturs.artamonovs.analog.com@kernel.org>
To: Catalin Marinas <catalin.marinas@arm.com>,
	 Will Deacon <will@kernel.org>,
	Greg Malysa <greg.malysa@timesys.com>,
	 Philipp Zabel <p.zabel@pengutronix.de>,
	Rob Herring <robh@kernel.org>,
	 Krzysztof Kozlowski <krzk+dt@kernel.org>,
	 Conor Dooley <conor+dt@kernel.org>,
	 Utsav Agarwal <Utsav.Agarwal@analog.com>,
	 Michael Turquette <mturquette@baylibre.com>,
	 Stephen Boyd <sboyd@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	 Bartosz Golaszewski <brgl@bgdev.pl>,
	Thomas Gleixner <tglx@linutronix.de>,
	 Andi Shyti <andi.shyti@kernel.org>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 Jiri Slaby <jirislaby@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
	 Olof Johansson <olof@lixom.net>,
	soc@kernel.org
Cc: linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,  devicetree@vger.kernel.org,
	linux-clk@vger.kernel.org,  linux-gpio@vger.kernel.org,
	linux-i2c@vger.kernel.org,  linux-serial@vger.kernel.org,
	 Arturs Artamonovs <arturs.artamonovs@analog.com>,
	adsp-linux@analog.com,
	 Arturs Artamonovs <Arturs.Artamonovs@analog.com>,
	 Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Subject: [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL
Date: Thu, 12 Sep 2024 19:24:50 +0100	[thread overview]
Message-ID: <20240912-test-v1-5-458fa57c8ccf@analog.com> (raw)
In-Reply-To: <20240912-test-v1-0-458fa57c8ccf@analog.com>

From: Arturs Artamonovs <arturs.artamonovs@analog.com>

Implements clock tree, no dynamic pll rate change.

Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@analog.com>
Co-developed-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Co-developed-by: Greg Malysa <greg.malysa@timesys.com>
Signed-off-by: Greg Malysa <greg.malysa@timesys.com>
---
 drivers/clk/adi/clk-adi-pll.c | 151 ++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/adi/clk.h         |  99 +++++++++++++++++++++++++++
 2 files changed, 250 insertions(+)

diff --git a/drivers/clk/adi/clk-adi-pll.c b/drivers/clk/adi/clk-adi-pll.c
new file mode 100644
index 0000000000000000000000000000000000000000..39fcc78b3170c0aa5962af5268f499082efb3686
--- /dev/null
+++ b/drivers/clk/adi/clk-adi-pll.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CGU PLL driver for ADI SC59X processors
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include "clk.h"
+
+struct clk_sc5xx_cgu_pll {
+	struct clk_hw hw;
+	void __iomem *base;
+	spinlock_t *lock;
+	int prepared;
+	u32 mask;
+	u32 msel;
+	u32 m_offset;
+	u8 shift;
+};
+
+struct clk_sc5xx_cgu_pll *to_clk_sc5xx_cgu_pll(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_sc5xx_cgu_pll, hw);
+}
+
+static long sc5xx_cgu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+	unsigned long *parent_rate)
+{
+	struct clk_sc5xx_cgu_pll *pll = to_clk_sc5xx_cgu_pll(hw);
+	unsigned long m, m2, new_rate, nr2, prate2;
+	unsigned long prate = *parent_rate;
+	struct clk_hw *parent_hw;
+	int parent_inc;
+
+	parent_hw = clk_hw_get_parent(hw);
+
+	m = rate / prate;
+
+	if (m > pll->msel) {
+		/* cannot scale this far, need bigger input */
+		parent_inc = m / pll->msel;
+		prate = clk_hw_round_rate(parent_hw, prate * (parent_inc + 1));
+	} else if (m == 0) {
+		pr_err("%s: Cannot use VCO to reduce parent clock rate, requested %lu, clamping to %lu\n",
+			__func__, rate, prate);
+		return prate;
+	}
+
+	new_rate = prate * m;
+
+	if (new_rate != rate) {
+		/*
+		 * Check if we could get an integer match by halving parent rate since we
+		 * know at least about the DF bit before the VCO, although we don't know
+		 * if we're already using it or not
+		 */
+		prate2 = clk_hw_round_rate(parent_hw, prate / 2);
+		m2 = rate / prate2;
+		nr2 = prate * m2;
+		if (m2 <= pll->msel && nr2 == rate) {
+			m = m2;
+			new_rate = nr2;
+			prate = prate2;
+		}
+	}
+
+	*parent_rate = prate;
+	return new_rate;
+}
+
+static unsigned long sc5xx_cgu_pll_recalc_rate(struct clk_hw *hw,
+	unsigned long parent_rate)
+{
+	struct clk_sc5xx_cgu_pll *pll = to_clk_sc5xx_cgu_pll(hw);
+	u32 reg = readl(pll->base);
+	u32 m = ((reg & pll->mask) >> pll->shift) + pll->m_offset;
+
+	if (m == 0)
+		m = pll->msel;
+
+	return parent_rate * m;
+
+}
+
+static int sc5xx_cgu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+	unsigned long parent_rate)
+{
+	struct clk_sc5xx_cgu_pll *pll = to_clk_sc5xx_cgu_pll(hw);
+	u32 m;
+
+	m = (rate / parent_rate) - pll->m_offset;
+
+	if (m >= pll->msel)
+		m = 0;
+
+	/* reminder for implementation: lock around read/modify to control reg */
+	pr_err("%s: set_rate not permitted yet, but we would write %d to m\n", __func__,
+		m);
+	return -ENOENT;
+}
+
+static const struct clk_ops clk_sc5xx_cgu_pll_ops = {
+	.recalc_rate = sc5xx_cgu_pll_recalc_rate,
+	.round_rate = sc5xx_cgu_pll_round_rate,
+	.set_rate = sc5xx_cgu_pll_set_rate,
+};
+
+struct clk *sc5xx_cgu_pll(const char *name, const char *parent_name,
+	void __iomem *base, u8 shift, u8 width, u32 m_offset,
+		spinlock_t *lock)
+{
+	struct clk_sc5xx_cgu_pll *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.ops = &clk_sc5xx_cgu_pll_ops;
+
+	pll->base = base;
+	pll->hw.init = &init;
+	pll->lock = lock;
+	pll->shift = shift;
+	pll->mask = GENMASK(width-1, 0) << shift;
+	pll->msel = pll->mask + 1;
+	pll->m_offset = m_offset;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: Failed to register, code %lu\n", __func__,
+			PTR_ERR(clk));
+	}
+
+	return clk;
+}
+
+MODULE_DESCRIPTION("Analog Devices CLock PLL driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
+
diff --git a/drivers/clk/adi/clk.h b/drivers/clk/adi/clk.h
new file mode 100644
index 0000000000000000000000000000000000000000..e17aa719c2170149a6a1a60dd4390a29f06e7296
--- /dev/null
+++ b/drivers/clk/adi/clk.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Clock support for ADI processors
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef CLK_ADI_CLK_H
+#define CLK_ADI_CLK_H
+
+#include <linux/clk.h>
+
+#define CGU_CTL         0x00
+#define CGU_PLLCTL      0x04
+#define CGU_STAT        0x08
+#define CGU_DIV         0x0C
+#define CGU_CLKOUTSEL   0x10
+#define CGU_OSCWDCTL    0x14
+#define CGU_TSCTL       0x18
+#define CGU_TSVALUE0    0x1C
+#define CGU_TSVALUE1    0x20
+#define CGU_TSCOUNT0    0x24
+#define CGU_TSCOUNT1    0x28
+#define CGU_CCBF_DIS    0x2C
+#define CGU_CCBF_STAT   0x30
+#define CGU_SCBF_DIS    0x38
+#define CGU_SCBF_STAT   0x3C
+#define CGU_DIVEX       0x40
+#define CGU_REVID       0x48
+
+#define CDU_CFG0     0x00
+#define CDU_CFG1     0x04
+#define CDU_CFG2     0x08
+#define CDU_CFG3     0x0C
+#define CDU_CFG4     0x10
+#define CDU_CFG5     0x14
+#define CDU_CFG6     0x18
+#define CDU_CFG7     0x1C
+#define CDU_CFG8     0x20
+#define CDU_CFG9     0x24
+#define CDU_CFG10    0x28
+#define CDU_CFG11    0x2C
+#define CDU_CFG12    0x30
+#define CDU_CFG13    0x34
+#define CDU_CFG14    0x38
+
+#define PLL3_OFFSET 0x2c
+
+#define CDU_CLKINSEL 0x44
+
+#define CGU_MSEL_SHIFT 8
+#define CGU_MSEL_WIDTH 7
+
+#define PLL3_MSEL_SHIFT 4
+#define PLL3_MSEL_WIDTH 7
+
+#define CDU_MUX_SIZE 4
+#define CDU_MUX_SHIFT 1
+#define CDU_MUX_WIDTH 2
+#define CDU_EN_BIT 0
+
+struct clk_sc5xx_cgu_pll *to_clk_sc5xx_cgu_pll(struct clk_hw *hw);
+
+struct clk *sc5xx_cgu_pll(const char *name, const char *parent_name,
+	void __iomem *base, u8 shift, u8 width, u32 m_offset, spinlock_t *lock);
+
+/**
+ * All CDU clock muxes are the same size
+ */
+static inline struct clk *cdu_mux(const char *name, void __iomem *reg,
+	const char * const *parents, spinlock_t *cdu_lock)
+{
+	return clk_register_mux(NULL, name, parents, CDU_MUX_SIZE,
+		CLK_SET_RATE_PARENT, reg, CDU_MUX_SHIFT, CDU_MUX_WIDTH, 0,
+		cdu_lock);
+}
+
+static inline struct clk *cgu_divider(const char *name, const char *parent,
+	void __iomem *reg, u8 shift, u8 width, u8 extra_flags, spinlock_t *cdu_lock)
+{
+	return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+		reg, shift, width, CLK_DIVIDER_MAX_AT_ZERO | extra_flags, cdu_lock);
+}
+
+static inline struct clk *cdu_gate(const char *name, const char *parent,
+	void __iomem *reg, u32 flags, spinlock_t *cdu_lock)
+{
+	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT | flags,
+		reg, CDU_EN_BIT, 0, cdu_lock);
+}
+
+static inline struct clk *cgu_gate(const char *name, const char *parent,
+	void __iomem *reg, u8 bit, spinlock_t *cdu_lock)
+{
+	return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, bit,
+		CLK_GATE_SET_TO_DISABLE, cdu_lock);
+}
+
+#endif

-- 
2.25.1



  parent reply	other threads:[~2024-09-12 18:20 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
2024-09-12 18:24 ` [PATCH 01/21] arm64: Add ADI " Arturs Artamonovs via B4 Relay
2024-09-13  8:16   ` Arnd Bergmann
2024-09-13  9:54     ` Artamonovs, Arturs
2024-09-14 17:15   ` Markus Elfring
2024-09-14 17:56     ` Greg Kroah-Hartman
2024-09-16  6:42   ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 02/21] reset: Add driver for ADI ADSP-SC5xx reset controller Arturs Artamonovs via B4 Relay
2024-09-13  7:22   ` Arnd Bergmann
2024-09-12 18:24 ` [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings Arturs Artamonovs via B4 Relay
2024-09-13 22:05   ` Rob Herring
2024-09-16  6:44   ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 04/21] dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings Arturs Artamonovs via B4 Relay
2024-09-16  6:45   ` Krzysztof Kozlowski
2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay [this message]
2024-09-13  7:27   ` [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL Arnd Bergmann
2024-09-16  6:46   ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 06/21] include: dt-binding: clock: add adi clock header file Arturs Artamonovs via B4 Relay
2024-09-13  7:35   ` Arnd Bergmann
2024-09-16  6:47   ` Krzysztof Kozlowski
2024-09-16  6:48   ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock Arturs Artamonovs via B4 Relay
2024-09-14 14:18   ` kernel test robot
2024-09-12 18:24 ` [PATCH 08/21] dt-bindings: clock: adi,sc5xx-clocks: add bindings Arturs Artamonovs via B4 Relay
2024-09-13 22:06   ` Rob Herring
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-13  7:38   ` Arnd Bergmann
2024-09-14 14:29   ` kernel test robot
2024-09-16  6:50   ` Krzysztof Kozlowski
2024-10-01 12:44   ` Linus Walleij
2024-10-01 14:29     ` Artamonovs, Arturs
2024-10-01 21:57     ` Greg Malysa
2024-10-02 13:53       ` Linus Walleij
2024-09-12 18:24 ` [PATCH 10/21] dt-bindings: gpio: adi,adsp-port-gpio: add bindings Arturs Artamonovs via B4 Relay
2024-09-16  6:53   ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-13 20:40   ` kernel test robot
2024-09-16  6:56   ` Krzysztof Kozlowski
2024-10-02 10:29   ` Thomas Gleixner
2024-09-12 18:24 ` [PATCH 12/21] dt-bindings: irqchip: adi,adsp-pint: add binding Arturs Artamonovs via B4 Relay
2024-09-16  6:57   ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-14  2:55   ` kernel test robot
2024-09-12 18:24 ` [PATCH 14/21] dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings Arturs Artamonovs via B4 Relay
2024-09-13 22:09   ` Rob Herring
2024-09-12 18:25 ` [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms Arturs Artamonovs via B4 Relay
2024-09-13  7:59   ` Arnd Bergmann
2024-09-16  7:13   ` Krzysztof Kozlowski
2024-09-12 18:25 ` [PATCH 16/21] dt-bindings: i2c: add i2c/twi driver documentation Arturs Artamonovs via B4 Relay
2024-09-13  7:24   ` Arnd Bergmann
2024-09-12 18:25 ` [PATCH 17/21] serial: adi,uart: Add driver for ADI ADSP-SC5xx Arturs Artamonovs via B4 Relay
2024-09-12 18:25 ` [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation Arturs Artamonovs via B4 Relay
2024-09-12 20:02   ` Rob Herring (Arm)
2024-09-13 14:06   ` Rob Herring
2024-09-12 18:25 ` [PATCH 19/21] arm64: dts: adi: sc598: add device tree Arturs Artamonovs via B4 Relay
2024-09-13  8:05   ` Arnd Bergmann
2024-09-16  7:04   ` Krzysztof Kozlowski
2024-09-12 18:25 ` [PATCH 20/21] arm64: defconfig: sc598 add minimal changes Arturs Artamonovs via B4 Relay
2024-09-13  7:44   ` Arnd Bergmann
2024-09-16  6:58   ` Krzysztof Kozlowski
2024-09-12 18:25 ` [PATCH 21/21] MAINTAINERS: add adi sc5xx maintainers Arturs Artamonovs via B4 Relay
2024-09-12 21:04 ` [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Rob Herring (Arm)
2024-09-16  6:57   ` Krzysztof Kozlowski
2024-09-13  8:20 ` Arnd Bergmann
2024-09-16  9:05 ` Krzysztof Kozlowski

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20240912-test-v1-5-458fa57c8ccf@analog.com \
    --to=devnull+arturs.artamonovs.analog.com@kernel.org \
    --cc=Utsav.Agarwal@analog.com \
    --cc=adsp-linux@analog.com \
    --cc=andi.shyti@kernel.org \
    --cc=arnd@arndb.de \
    --cc=arturs.artamonovs@analog.com \
    --cc=brgl@bgdev.pl \
    --cc=catalin.marinas@arm.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=greg.malysa@timesys.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jirislaby@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=nathan.morrison@timesys.com \
    --cc=olof@lixom.net \
    --cc=p.zabel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=soc@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).