* [PATCH 1/8] MIPS: ath79: apply the QCA956x timer workaround in setup
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 2/8] MIPS: ath79: move the bootstrap reference clock to setup Rosen Penev
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
qca956x_clocks_init() enables the MIPS timer interrupt in the misc
interrupt controller, which QCA956x needs before the clocks are set
up, or there are no jiffies. That has nothing to do with the clocks,
and it ties the clock code to ath79_reset_base.
Do it in plat_time_init() right before of_clk_init() instead, which
runs the clock setup. The order is the same. TP9343 boards use the
QCA956x PLL and took this path too, so check for both.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
arch/mips/ath79/clock.c | 10 ----------
arch/mips/ath79/setup.c | 13 +++++++++++++
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index 050f6553f398..8c5eaa4ab6e0 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -523,16 +523,6 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
u32 cpu_pll, ddr_pll;
u32 bootstrap;
- /*
- * QCA956x timer init workaround has to be applied right before setting
- * up the clock. Else, there will be no jiffies
- */
- u32 misc;
-
- misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
- misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
- ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc);
-
bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40)
ref_rate = 40 * 1000 * 1000;
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 4e18cdcf65a0..d9e1cc77ad04 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -241,6 +241,19 @@ void __init plat_time_init(void)
struct clk *clk;
unsigned long cpu_clk_rate;
+ /*
+ * QCA956x needs the MIPS timer interrupt enabled in the misc
+ * interrupt controller before the clocks are set up, or there are
+ * no jiffies.
+ */
+ if (soc_is_qca956x() || soc_is_tp9343()) {
+ u32 misc;
+
+ misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
+ misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
+ ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc);
+ }
+
of_clk_init(NULL);
np = of_get_cpu_node(0, NULL);
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 2/8] MIPS: ath79: move the bootstrap reference clock to setup
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
2026-11-04 5:58 ` [PATCH 1/8] MIPS: ath79: apply the QCA956x timer workaround in setup Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 3/8] clk: ath79: move the ath79 clock driver to drivers/clk Rosen Penev
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
The qca,ath79-pll binding requires the reference clock as an input, and a
rate in the device tree already took precedence over the 25/40 MHz that
the clock code read from the bootstrap pins. Many AR933x boards leave the
rate out, though, and rely on the pins.
Read the pins in plat_time_init() instead, and register the reference
clock from them only when the device tree gives no rate. The clock code
then takes the DT clock or this one through the clk API and no longer
needs ath79_reset_base. When the device tree does give a rate, warn if
it disagrees with the pins: a wrong rate leaves the CPU, DDR and AHB rates
off, the UART baud rate included.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
arch/mips/ath79/clock.c | 71 ++++++++-------------------------
arch/mips/ath79/setup.c | 87 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 54 deletions(-)
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index 8c5eaa4ab6e0..85f747cf37a8 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -25,9 +25,6 @@
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
-#define AR71XX_BASE_FREQ 40000000
-#define AR724X_BASE_FREQ 40000000
-
static struct clk *clks[ATH79_CLK_END];
static struct clk_onecell_data clk_data = {
.clks = clks,
@@ -78,16 +75,12 @@ static struct clk * __init ath79_set_ff_clk(int type, const char *parent,
return clk;
}
-static unsigned long __init ath79_setup_ref_clk(unsigned long rate)
+static unsigned long __init ath79_get_ref_rate(void)
{
- struct clk *clk = clks[ATH79_CLK_REF];
-
- if (clk)
- rate = clk_get_rate(clk);
- else
- clk = ath79_set_clk(ATH79_CLK_REF, rate);
+ if (!clks[ATH79_CLK_REF])
+ panic("ath79: no reference clock");
- return rate;
+ return clk_get_rate(clks[ATH79_CLK_REF]);
}
static void __init ar71xx_clocks_init(void __iomem *pll_base)
@@ -100,7 +93,7 @@ static void __init ar71xx_clocks_init(void __iomem *pll_base)
u32 freq;
u32 div;
- ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ);
+ ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG);
@@ -126,7 +119,7 @@ static void __init ar724x_clocks_init(void __iomem *pll_base)
u32 mult, div, ddr_div, ahb_div;
u32 pll;
- ath79_setup_ref_clk(AR71XX_BASE_FREQ);
+ ath79_get_ref_rate();
pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
@@ -143,7 +136,6 @@ static void __init ar724x_clocks_init(void __iomem *pll_base)
static void __init ar933x_clocks_init(void __iomem *pll_base)
{
- unsigned long ref_rate;
u32 clock_ctrl;
u32 ref_div;
u32 ninit_mul;
@@ -152,15 +144,8 @@ static void __init ar933x_clocks_init(void __iomem *pll_base)
u32 cpu_div;
u32 ddr_div;
u32 ahb_div;
- u32 t;
- t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
- if (t & AR933X_BOOTSTRAP_REF_CLK_40)
- ref_rate = (40 * 1000 * 1000);
- else
- ref_rate = (25 * 1000 * 1000);
-
- ath79_setup_ref_clk(ref_rate);
+ ath79_get_ref_rate();
clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG);
if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
@@ -237,18 +222,11 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
unsigned long ahb_rate;
u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
- u32 bootstrap;
void __iomem *dpll_base;
dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
- if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
- ref_rate = 40 * 1000 * 1000;
- else
- ref_rate = 25 * 1000 * 1000;
-
- ref_rate = ath79_setup_ref_clk(ref_rate);
+ ref_rate = ath79_get_ref_rate();
pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
@@ -355,15 +333,8 @@ static void __init qca953x_clocks_init(void __iomem *pll_base)
unsigned long ahb_rate;
u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
- u32 bootstrap;
-
- bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
- if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40)
- ref_rate = 40 * 1000 * 1000;
- else
- ref_rate = 25 * 1000 * 1000;
- ref_rate = ath79_setup_ref_clk(ref_rate);
+ ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
@@ -438,15 +409,8 @@ static void __init qca955x_clocks_init(void __iomem *pll_base)
unsigned long ahb_rate;
u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
- u32 bootstrap;
- bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
- if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40)
- ref_rate = 40 * 1000 * 1000;
- else
- ref_rate = 25 * 1000 * 1000;
-
- ref_rate = ath79_setup_ref_clk(ref_rate);
+ ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
@@ -521,15 +485,8 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
unsigned long ahb_rate;
u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
- u32 bootstrap;
-
- bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
- if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40)
- ref_rate = 40 * 1000 * 1000;
- else
- ref_rate = 25 * 1000 * 1000;
- ref_rate = ath79_setup_ref_clk(ref_rate);
+ ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG);
out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
@@ -610,7 +567,13 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
struct clk *ref_clk;
void __iomem *pll_base;
+ /*
+ * The board's crystal. Without a rate in the device tree, the arch
+ * code registers it from the bootstrap pins.
+ */
ref_clk = of_clk_get(np, 0);
+ if (IS_ERR(ref_clk))
+ ref_clk = clk_get_sys(NULL, "ref");
if (!IS_ERR(ref_clk))
clks[ATH79_CLK_REF] = ref_clk;
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index d9e1cc77ad04..dff0fbe07b04 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -15,6 +15,9 @@
#include <linux/memblock.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
#include <linux/of_clk.h>
#include <linux/of_fdt.h>
#include <linux/irqchip.h>
@@ -235,6 +238,89 @@ void __init plat_mem_setup(void)
pm_power_off = ath79_halt;
}
+static const struct of_device_id ath79_pll_ids[] __initconst = {
+ { .compatible = "qca,ar7100-pll" },
+ { .compatible = "qca,ar7240-pll" },
+ { .compatible = "qca,ar9130-pll" },
+ { .compatible = "qca,ar9330-pll" },
+ { .compatible = "qca,ar9340-pll" },
+ { .compatible = "qca,qca9530-pll" },
+ { .compatible = "qca,qca9550-pll" },
+ { .compatible = "qca,qca9560-pll" },
+ { /* sentinel */ }
+};
+
+/* the crystal that the bootstrap pins select */
+static unsigned long __init ath79_bootstrap_ref_rate(bool *strapped)
+{
+ unsigned int reg;
+ u32 bit;
+
+ *strapped = true;
+ if (soc_is_ar933x()) {
+ reg = AR933X_RESET_REG_BOOTSTRAP;
+ bit = AR933X_BOOTSTRAP_REF_CLK_40;
+ } else if (soc_is_ar934x()) {
+ reg = AR934X_RESET_REG_BOOTSTRAP;
+ bit = AR934X_BOOTSTRAP_REF_CLK_40;
+ } else if (soc_is_qca953x()) {
+ reg = QCA953X_RESET_REG_BOOTSTRAP;
+ bit = QCA953X_BOOTSTRAP_REF_CLK_40;
+ } else if (soc_is_qca955x()) {
+ reg = QCA955X_RESET_REG_BOOTSTRAP;
+ bit = QCA955X_BOOTSTRAP_REF_CLK_40;
+ } else if (soc_is_qca956x() || soc_is_tp9343()) {
+ reg = QCA956X_RESET_REG_BOOTSTRAP;
+ bit = QCA956X_BOOTSTRAP_REF_CLK_40;
+ } else {
+ /* no bootstrap pin for the crystal on AR71xx, AR724x, AR913x */
+ *strapped = false;
+ return 40000000;
+ }
+
+ return (ath79_reset_rr(reg) & bit) ? 40000000 : 25000000;
+}
+
+/*
+ * The clock code takes the reference clock from the device tree. Many
+ * AR933x boards leave its rate out and rely on the bootstrap pins, so
+ * register it from those for them. Otherwise warn if the device tree
+ * disagrees with the pins, as a wrong rate leaves every derived clock off,
+ * the UART baud rate included.
+ */
+static void __init ath79_setup_ref_clk(void)
+{
+ struct device_node *np, *ref_np;
+ unsigned long rate, strap_rate;
+ struct clk *clk;
+ bool strapped;
+ u32 dt_rate;
+
+ strap_rate = ath79_bootstrap_ref_rate(&strapped);
+
+ np = of_find_matching_node(NULL, ath79_pll_ids);
+ ref_np = np ? of_parse_phandle(np, "clocks", 0) : NULL;
+ of_node_put(np);
+
+ if (ref_np && !of_property_read_u32(ref_np, "clock-frequency", &dt_rate)) {
+ of_node_put(ref_np);
+ rate = dt_rate;
+ if (strapped && rate != strap_rate)
+ pr_warn("ath79: reference clock is %lu Hz in the device tree, but the bootstrap pins select %lu Hz\n",
+ rate, strap_rate);
+ return;
+ }
+ of_node_put(ref_np);
+
+ clk = clk_register_fixed_rate(NULL, "ref", NULL, 0, strap_rate);
+ if (IS_ERR(clk)) {
+ pr_err("ath79: failed to register the reference clock\n");
+ return;
+ }
+
+ clk_register_clkdev(clk, "ref", NULL);
+}
+
void __init plat_time_init(void)
{
struct device_node *np;
@@ -254,6 +340,7 @@ void __init plat_time_init(void)
ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc);
}
+ ath79_setup_ref_clk();
of_clk_init(NULL);
np = of_get_cpu_node(0, NULL);
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 3/8] clk: ath79: move the ath79 clock driver to drivers/clk
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
2026-11-04 5:58 ` [PATCH 1/8] MIPS: ath79: apply the QCA956x timer workaround in setup Rosen Penev
2026-11-04 5:58 ` [PATCH 2/8] MIPS: ath79: move the bootstrap reference clock to setup Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 4/8] clk: ath79: use FIELD_GET() for the PLL register fields Rosen Penev
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
The ath79 PLL clock code only uses the clk API and its own PLL and SRIF
registers now, so move it from arch/mips/ath79 to drivers/clk, like
the Ralink clocks before it. Copy the register definitions it uses
from asm/mach-ath79/ar71xx_regs.h into the driver, so it no longer
needs the mach headers, and drop the unused ath79.h and common.h.
The driver stays a CLK_OF_DECLARE one, as the MIPS timer needs the CPU
clock from plat_time_init(). COMMON_CLK_ATH79 defaults to ATH79.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
MAINTAINERS | 8 +
arch/mips/ath79/Makefile | 2 +-
drivers/clk/Kconfig | 12 ++
drivers/clk/Makefile | 1 +
.../ath79/clock.c => drivers/clk/clk-ath79.c | 6 +-
drivers/clk/clk-ath79.h | 194 ++++++++++++++++++
6 files changed, 218 insertions(+), 5 deletions(-)
rename arch/mips/ath79/clock.c => drivers/clk/clk-ath79.c (99%)
create mode 100644 drivers/clk/clk-ath79.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 46c416cadacd..d1d11bb49875 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4352,6 +4352,14 @@ S: Supported
F: Documentation/devicetree/bindings/rtc/andestech,atcrtc100.yaml
F: drivers/rtc/rtc-atcrtc100.c
+ATHEROS 71XX/9XXX CLOCK DRIVER
+M: Alban Bedel <albeu@free.fr>
+M: Antony Pavlov <antonynpavlov@gmail.com>
+S: Maintained
+F: Documentation/devicetree/bindings/clock/qca,ath79-pll.yaml
+F: drivers/clk/clk-ath79.*
+F: include/dt-bindings/clock/ath79-clk.h
+
ATHEROS 71XX/9XXX GPIO DRIVER
M: Alban Bedel <albeu@free.fr>
S: Maintained
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 0fb3aaf42149..5df55b5e1c15 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -6,6 +6,6 @@
# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
#
-obj-y := prom.o setup.o common.o clock.o
+obj-y := prom.o setup.o common.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 37a8e35d4178..9a3ca7d31c06 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -66,6 +66,18 @@ config COMMON_CLK_APPLE_NCO
found on Apple SoCs such as t8103 (M1). The blocks are typically
generators of audio clocks.
+config COMMON_CLK_ATH79
+ bool "Clock driver for Atheros/Qualcomm ath79 SoCs" if COMPILE_TEST
+ depends on ATH79 || COMPILE_TEST
+ depends on OF
+ default ATH79
+ help
+ Support for the PLL controller of the Atheros/Qualcomm ath79
+ family of MIPS SoCs: AR71xx, AR724x, AR913x, AR933x, AR934x,
+ QCA953x, QCA955x and QCA956x. It provides the CPU, DDR, AHB and
+ MDIO clocks, derived from the board's reference clock. The clocks
+ are set up early, as the MIPS timer needs the CPU clock.
+
config COMMON_CLK_MAX77686
tristate "Clock driver for Maxim 77620/77686/77802 MFD"
depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 52d138d4ffc8..589d2ef9dc89 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -58,6 +58,7 @@ endif
# please keep this section sorted lexicographically by file path name
obj-$(CONFIG_COMMON_CLK_APPLE_NCO) += clk-apple-nco.o
obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
+obj-$(CONFIG_COMMON_CLK_ATH79) += clk-ath79.o
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o
diff --git a/arch/mips/ath79/clock.c b/drivers/clk/clk-ath79.c
similarity index 99%
rename from arch/mips/ath79/clock.c
rename to drivers/clk/clk-ath79.c
index 85f747cf37a8..c5da404c9c48 100644
--- a/arch/mips/ath79/clock.c
+++ b/drivers/clk/clk-ath79.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Atheros AR71XX/AR724X/AR913X common routines
+ * Atheros/Qualcomm ath79 PLL clocks
*
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
* Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
@@ -21,9 +21,7 @@
#include <asm/div64.h>
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "common.h"
+#include "clk-ath79.h"
static struct clk *clks[ATH79_CLK_END];
static struct clk_onecell_data clk_data = {
diff --git a/drivers/clk/clk-ath79.h b/drivers/clk/clk-ath79.h
new file mode 100644
index 000000000000..12d7488eb5d2
--- /dev/null
+++ b/drivers/clk/clk-ath79.h
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Atheros/Qualcomm ath79 PLL and SRIF registers, as in
+ * asm/mach-ath79/ar71xx_regs.h
+ */
+
+#ifndef __CLK_ATH79_H
+#define __CLK_ATH79_H
+
+#include <linux/bits.h>
+
+#define AR71XX_APB_BASE 0x18000000
+#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
+#define AR934X_SRIF_SIZE 0x1000
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_FB_SHIFT 3
+#define AR71XX_PLL_FB_MASK 0x1f
+#define AR71XX_CPU_DIV_SHIFT 16
+#define AR71XX_CPU_DIV_MASK 0x3
+#define AR71XX_DDR_DIV_SHIFT 18
+#define AR71XX_DDR_DIV_MASK 0x3
+#define AR71XX_AHB_DIV_SHIFT 20
+#define AR71XX_AHB_DIV_MASK 0x7
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_FB_SHIFT 0
+#define AR724X_PLL_FB_MASK 0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT 10
+#define AR724X_PLL_REF_DIV_MASK 0xf
+#define AR724X_AHB_DIV_SHIFT 19
+#define AR724X_AHB_DIV_MASK 0x1
+#define AR724X_DDR_DIV_SHIFT 22
+#define AR724X_DDR_DIV_MASK 0x3
+#define AR933X_PLL_CPU_CONFIG_REG 0x00
+#define AR933X_PLL_CLOCK_CTRL_REG 0x08
+#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10
+#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f
+#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16
+#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
+#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2)
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7
+#define AR934X_PLL_CPU_CONFIG_REG 0x00
+#define AR934X_PLL_DDR_CONFIG_REG 0x04
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24
+#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
+#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
+#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6
+#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f
+#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
+#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
+#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
+#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
+#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
+#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10
+#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f
+#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
+#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
+#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
+#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
+#define QCA953X_PLL_CPU_CONFIG_REG 0x00
+#define QCA953X_PLL_DDR_CONFIG_REG 0x04
+#define QCA953X_PLL_CLK_CTRL_REG 0x08
+#define QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
+#define QCA953X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
+#define QCA953X_PLL_CPU_CONFIG_NINT_SHIFT 6
+#define QCA953X_PLL_CPU_CONFIG_NINT_MASK 0x3f
+#define QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
+#define QCA953X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
+#define QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
+#define QCA953X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
+#define QCA953X_PLL_DDR_CONFIG_NINT_SHIFT 10
+#define QCA953X_PLL_DDR_CONFIG_NINT_MASK 0x3f
+#define QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
+#define QCA953X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+#define QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
+#define QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
+#define QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
+#define QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+#define QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define QCA955X_PLL_CPU_CONFIG_REG 0x00
+#define QCA955X_PLL_DDR_CONFIG_REG 0x04
+#define QCA955X_PLL_CLK_CTRL_REG 0x08
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
+#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6
+#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
+#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10
+#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
+#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
+#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
+#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define QCA956X_PLL_CPU_CONFIG_REG 0x00
+#define QCA956X_PLL_CPU_CONFIG1_REG 0x04
+#define QCA956X_PLL_DDR_CONFIG_REG 0x08
+#define QCA956X_PLL_DDR_CONFIG1_REG 0x0c
+#define QCA956X_PLL_CLK_CTRL_REG 0x10
+#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
+#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x1fff
+#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18
+#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff
+#define QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
+#define QCA956X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x1fff
+#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18
+#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff
+#define QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
+#define QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
+#define QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL BIT(20)
+#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
+#define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0
+#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4
+#define AR934X_SRIF_DDR_DPLL1_REG 0x240
+#define AR934X_SRIF_DDR_DPLL2_REG 0x244
+#define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27
+#define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f
+#define AR934X_SRIF_DPLL1_NINT_SHIFT 18
+#define AR934X_SRIF_DPLL1_NINT_MASK 0x1ff
+#define AR934X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff
+#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30)
+#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13
+#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7
+
+#endif /* __CLK_ATH79_H */
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 4/8] clk: ath79: use FIELD_GET() for the PLL register fields
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
` (2 preceding siblings ...)
2026-11-04 5:58 ` [PATCH 3/8] clk: ath79: move the ath79 clock driver to drivers/clk Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 5/8] clk: ath79: convert to clk_hw based registration Rosen Penev
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
Describe the PLL and SRIF register fields with GENMASK() instead of
separate _SHIFT and _MASK pairs, and extract them with FIELD_GET()
instead of open-coded shifts and masks.
No functional change: the generated code is the same, apart from a
register allocation swap in ar933x_clocks_init().
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/clk/clk-ath79.c | 199 +++++++++++---------------------
drivers/clk/clk-ath79.h | 246 ++++++++++++++++------------------------
2 files changed, 165 insertions(+), 280 deletions(-)
diff --git a/drivers/clk/clk-ath79.c b/drivers/clk/clk-ath79.c
index c5da404c9c48..8279d58be318 100644
--- a/drivers/clk/clk-ath79.c
+++ b/drivers/clk/clk-ath79.c
@@ -8,6 +8,7 @@
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
*/
+#include <linux/bitfield.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
@@ -95,16 +96,16 @@ static void __init ar71xx_clocks_init(void __iomem *pll_base)
pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG);
- div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1;
+ div = FIELD_GET(AR71XX_PLL_FB, pll) + 1;
freq = div * ref_rate;
- div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
+ div = FIELD_GET(AR71XX_CPU_DIV, pll) + 1;
cpu_rate = freq / div;
- div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
+ div = FIELD_GET(AR71XX_DDR_DIV, pll) + 1;
ddr_rate = freq / div;
- div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
+ div = (FIELD_GET(AR71XX_AHB_DIV, pll) + 1) * 2;
ahb_rate = cpu_rate / div;
ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
@@ -121,11 +122,11 @@ static void __init ar724x_clocks_init(void __iomem *pll_base)
pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
- mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
- div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
+ mult = FIELD_GET(AR724X_PLL_FB, pll);
+ div = FIELD_GET(AR724X_PLL_REF_DIV, pll) * 2;
- ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
- ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
+ ddr_div = FIELD_GET(AR724X_DDR_DIV, pll) + 1;
+ ahb_div = (FIELD_GET(AR724X_AHB_DIV, pll) + 1) * 2;
ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div);
ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div);
@@ -160,28 +161,18 @@ static void __init ar933x_clocks_init(void __iomem *pll_base)
cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG);
- t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
- AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
- ref_div = t;
+ ref_div = FIELD_GET(AR933X_PLL_CPU_CONFIG_REFDIV, cpu_config);
+ ninit_mul = FIELD_GET(AR933X_PLL_CPU_CONFIG_NINT, cpu_config);
- ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
- AR933X_PLL_CPU_CONFIG_NINT_MASK;
-
- t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
- AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ t = FIELD_GET(AR933X_PLL_CPU_CONFIG_OUTDIV, cpu_config);
if (t == 0)
t = 1;
out_div = (1 << t);
- cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
- AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
-
- ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
- AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
-
- ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
- AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
+ cpu_div = FIELD_GET(AR933X_PLL_CLOCK_CTRL_CPU_DIV, clock_ctrl) + 1;
+ ddr_div = FIELD_GET(AR933X_PLL_CLOCK_CTRL_DDR_DIV, clock_ctrl) + 1;
+ ahb_div = FIELD_GET(AR933X_PLL_CLOCK_CTRL_AHB_DIV, clock_ctrl) + 1;
}
ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul,
@@ -228,25 +219,18 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
- out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
- AR934X_SRIF_DPLL2_OUTDIV_MASK;
+ out_div = FIELD_GET(AR934X_SRIF_DPLL2_OUTDIV, pll);
pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG);
- nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
- AR934X_SRIF_DPLL1_NINT_MASK;
- nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
- ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
- AR934X_SRIF_DPLL1_REFDIV_MASK;
+ nint = FIELD_GET(AR934X_SRIF_DPLL1_NINT, pll);
+ nfrac = FIELD_GET(AR934X_SRIF_DPLL1_NFRAC, pll);
+ ref_div = FIELD_GET(AR934X_SRIF_DPLL1_REFDIV, pll);
frac = 1 << 18;
} else {
pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG);
- out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
- AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
- AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
- nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
- AR934X_PLL_CPU_CONFIG_NINT_MASK;
- nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
- AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
+ out_div = FIELD_GET(AR934X_PLL_CPU_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(AR934X_PLL_CPU_CONFIG_REFDIV, pll);
+ nint = FIELD_GET(AR934X_PLL_CPU_CONFIG_NINT, pll);
+ nfrac = FIELD_GET(AR934X_PLL_CPU_CONFIG_NFRAC, pll);
frac = 1 << 6;
}
@@ -255,25 +239,18 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
- out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
- AR934X_SRIF_DPLL2_OUTDIV_MASK;
+ out_div = FIELD_GET(AR934X_SRIF_DPLL2_OUTDIV, pll);
pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG);
- nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
- AR934X_SRIF_DPLL1_NINT_MASK;
- nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
- ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
- AR934X_SRIF_DPLL1_REFDIV_MASK;
+ nint = FIELD_GET(AR934X_SRIF_DPLL1_NINT, pll);
+ nfrac = FIELD_GET(AR934X_SRIF_DPLL1_NFRAC, pll);
+ ref_div = FIELD_GET(AR934X_SRIF_DPLL1_REFDIV, pll);
frac = 1 << 18;
} else {
pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG);
- out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
- AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
- AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
- nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
- AR934X_PLL_DDR_CONFIG_NINT_MASK;
- nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
- AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
+ out_div = FIELD_GET(AR934X_PLL_DDR_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(AR934X_PLL_DDR_CONFIG_REFDIV, pll);
+ nint = FIELD_GET(AR934X_PLL_DDR_CONFIG_NINT, pll);
+ nfrac = FIELD_GET(AR934X_PLL_DDR_CONFIG_NFRAC, pll);
frac = 1 << 10;
}
@@ -282,8 +259,7 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
- postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
- AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
+ postdiv = FIELD_GET(AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV, clk_ctrl);
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
cpu_rate = ref_rate;
@@ -292,8 +268,7 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
else
cpu_rate = ddr_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
- AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
+ postdiv = FIELD_GET(AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV, clk_ctrl);
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
ddr_rate = ref_rate;
@@ -302,8 +277,7 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
else
ddr_rate = cpu_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
- AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
+ postdiv = FIELD_GET(AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV, clk_ctrl);
if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
ahb_rate = ref_rate;
@@ -335,28 +309,20 @@ static void __init qca953x_clocks_init(void __iomem *pll_base)
ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG);
- out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
- QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
- QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
- nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) &
- QCA953X_PLL_CPU_CONFIG_NINT_MASK;
- frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
- QCA953X_PLL_CPU_CONFIG_NFRAC_MASK;
+ out_div = FIELD_GET(QCA953X_PLL_CPU_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(QCA953X_PLL_CPU_CONFIG_REFDIV, pll);
+ nint = FIELD_GET(QCA953X_PLL_CPU_CONFIG_NINT, pll);
+ frac = FIELD_GET(QCA953X_PLL_CPU_CONFIG_NFRAC, pll);
cpu_pll = nint * ref_rate / ref_div;
cpu_pll += frac * (ref_rate >> 6) / ref_div;
cpu_pll /= (1 << out_div);
pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG);
- out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
- QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
- QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
- nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) &
- QCA953X_PLL_DDR_CONFIG_NINT_MASK;
- frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
- QCA953X_PLL_DDR_CONFIG_NFRAC_MASK;
+ out_div = FIELD_GET(QCA953X_PLL_DDR_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(QCA953X_PLL_DDR_CONFIG_REFDIV, pll);
+ nint = FIELD_GET(QCA953X_PLL_DDR_CONFIG_NINT, pll);
+ frac = FIELD_GET(QCA953X_PLL_DDR_CONFIG_NFRAC, pll);
ddr_pll = nint * ref_rate / ref_div;
ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
@@ -364,8 +330,7 @@ static void __init qca953x_clocks_init(void __iomem *pll_base)
clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG);
- postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
- QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA953X_PLL_CLK_CTRL_CPU_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
cpu_rate = ref_rate;
@@ -374,8 +339,7 @@ static void __init qca953x_clocks_init(void __iomem *pll_base)
else
cpu_rate = ddr_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
- QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA953X_PLL_CLK_CTRL_DDR_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
ddr_rate = ref_rate;
@@ -384,8 +348,7 @@ static void __init qca953x_clocks_init(void __iomem *pll_base)
else
ddr_rate = cpu_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
- QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA953X_PLL_CLK_CTRL_AHB_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
ahb_rate = ref_rate;
@@ -411,28 +374,20 @@ static void __init qca955x_clocks_init(void __iomem *pll_base)
ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG);
- out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
- QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
- QCA955X_PLL_CPU_CONFIG_REFDIV_MASK;
- nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) &
- QCA955X_PLL_CPU_CONFIG_NINT_MASK;
- frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
- QCA955X_PLL_CPU_CONFIG_NFRAC_MASK;
+ out_div = FIELD_GET(QCA955X_PLL_CPU_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(QCA955X_PLL_CPU_CONFIG_REFDIV, pll);
+ nint = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NINT, pll);
+ frac = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NFRAC, pll);
cpu_pll = nint * ref_rate / ref_div;
cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
cpu_pll /= (1 << out_div);
pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG);
- out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
- QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
- QCA955X_PLL_DDR_CONFIG_REFDIV_MASK;
- nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) &
- QCA955X_PLL_DDR_CONFIG_NINT_MASK;
- frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
- QCA955X_PLL_DDR_CONFIG_NFRAC_MASK;
+ out_div = FIELD_GET(QCA955X_PLL_DDR_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(QCA955X_PLL_DDR_CONFIG_REFDIV, pll);
+ nint = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NINT, pll);
+ frac = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NFRAC, pll);
ddr_pll = nint * ref_rate / ref_div;
ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
@@ -440,8 +395,7 @@ static void __init qca955x_clocks_init(void __iomem *pll_base)
clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG);
- postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
- QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA955X_PLL_CLK_CTRL_CPU_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
cpu_rate = ref_rate;
@@ -450,8 +404,7 @@ static void __init qca955x_clocks_init(void __iomem *pll_base)
else
cpu_rate = cpu_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
- QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA955X_PLL_CLK_CTRL_DDR_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
ddr_rate = ref_rate;
@@ -460,8 +413,7 @@ static void __init qca955x_clocks_init(void __iomem *pll_base)
else
ddr_rate = ddr_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
- QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA955X_PLL_CLK_CTRL_AHB_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
ahb_rate = ref_rate;
@@ -487,18 +439,13 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
ref_rate = ath79_get_ref_rate();
pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG);
- out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
- QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
- QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
+ out_div = FIELD_GET(QCA956X_PLL_CPU_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(QCA956X_PLL_CPU_CONFIG_REFDIV, pll);
pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG);
- nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
- QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
- hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
- QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
- lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
- QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
+ nint = FIELD_GET(QCA956X_PLL_CPU_CONFIG1_NINT, pll);
+ hfrac = FIELD_GET(QCA956X_PLL_CPU_CONFIG1_NFRAC_H, pll);
+ lfrac = FIELD_GET(QCA956X_PLL_CPU_CONFIG1_NFRAC_L, pll);
cpu_pll = nint * ref_rate / ref_div;
cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
@@ -506,17 +453,12 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
cpu_pll /= (1 << out_div);
pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG);
- out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
- QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
- ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
- QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
+ out_div = FIELD_GET(QCA956X_PLL_DDR_CONFIG_OUTDIV, pll);
+ ref_div = FIELD_GET(QCA956X_PLL_DDR_CONFIG_REFDIV, pll);
pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG);
- nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
- QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
- hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
- QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
- lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
- QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
+ nint = FIELD_GET(QCA956X_PLL_DDR_CONFIG1_NINT, pll);
+ hfrac = FIELD_GET(QCA956X_PLL_DDR_CONFIG1_NFRAC_H, pll);
+ lfrac = FIELD_GET(QCA956X_PLL_DDR_CONFIG1_NFRAC_L, pll);
ddr_pll = nint * ref_rate / ref_div;
ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
@@ -525,8 +467,7 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG);
- postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
- QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA956X_PLL_CLK_CTRL_CPU_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
cpu_rate = ref_rate;
@@ -535,8 +476,7 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
else
cpu_rate = cpu_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
- QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA956X_PLL_CLK_CTRL_DDR_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
ddr_rate = ref_rate;
@@ -545,8 +485,7 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
else
ddr_rate = ddr_pll / (postdiv + 1);
- postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
- QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+ postdiv = FIELD_GET(QCA956X_PLL_CLK_CTRL_AHB_POST_DIV, clk_ctrl);
if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
ahb_rate = ref_rate;
diff --git a/drivers/clk/clk-ath79.h b/drivers/clk/clk-ath79.h
index 12d7488eb5d2..dbff1b813562 100644
--- a/drivers/clk/clk-ath79.h
+++ b/drivers/clk/clk-ath79.h
@@ -9,186 +9,132 @@
#include <linux/bits.h>
-#define AR71XX_APB_BASE 0x18000000
-#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
-#define AR934X_SRIF_SIZE 0x1000
-#define AR71XX_PLL_REG_CPU_CONFIG 0x00
-#define AR71XX_PLL_FB_SHIFT 3
-#define AR71XX_PLL_FB_MASK 0x1f
-#define AR71XX_CPU_DIV_SHIFT 16
-#define AR71XX_CPU_DIV_MASK 0x3
-#define AR71XX_DDR_DIV_SHIFT 18
-#define AR71XX_DDR_DIV_MASK 0x3
-#define AR71XX_AHB_DIV_SHIFT 20
-#define AR71XX_AHB_DIV_MASK 0x7
-#define AR724X_PLL_REG_CPU_CONFIG 0x00
-#define AR724X_PLL_FB_SHIFT 0
-#define AR724X_PLL_FB_MASK 0x3ff
-#define AR724X_PLL_REF_DIV_SHIFT 10
-#define AR724X_PLL_REF_DIV_MASK 0xf
-#define AR724X_AHB_DIV_SHIFT 19
-#define AR724X_AHB_DIV_MASK 0x1
-#define AR724X_DDR_DIV_SHIFT 22
-#define AR724X_DDR_DIV_MASK 0x3
-#define AR933X_PLL_CPU_CONFIG_REG 0x00
-#define AR933X_PLL_CLOCK_CTRL_REG 0x08
-#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10
-#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f
-#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16
-#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
-#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23
-#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
-#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2)
-#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5
-#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3
-#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10
-#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3
-#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15
-#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7
-#define AR934X_PLL_CPU_CONFIG_REG 0x00
-#define AR934X_PLL_DDR_CONFIG_REG 0x04
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
-#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24
-#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
-#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
-#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6
-#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f
-#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
-#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
-#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
-#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
-#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
-#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
-#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10
-#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f
-#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
-#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
-#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
-#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+#define AR71XX_APB_BASE 0x18000000
+
+#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
+#define AR934X_SRIF_SIZE 0x1000
+
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_FB GENMASK(7, 3)
+#define AR71XX_CPU_DIV GENMASK(17, 16)
+#define AR71XX_DDR_DIV GENMASK(19, 18)
+#define AR71XX_AHB_DIV GENMASK(22, 20)
+
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_FB GENMASK(9, 0)
+#define AR724X_PLL_REF_DIV GENMASK(13, 10)
+#define AR724X_AHB_DIV GENMASK(19, 19)
+#define AR724X_DDR_DIV GENMASK(23, 22)
+
+#define AR933X_PLL_CPU_CONFIG_REG 0x00
+#define AR933X_PLL_CLOCK_CTRL_REG 0x08
+#define AR933X_PLL_CPU_CONFIG_NINT GENMASK(15, 10)
+#define AR933X_PLL_CPU_CONFIG_REFDIV GENMASK(20, 16)
+#define AR933X_PLL_CPU_CONFIG_OUTDIV GENMASK(25, 23)
+#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2)
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV GENMASK(6, 5)
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV GENMASK(11, 10)
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV GENMASK(17, 15)
+
+#define AR934X_PLL_CPU_CONFIG_REG 0x00
+#define AR934X_PLL_DDR_CONFIG_REG 0x04
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24
+#define AR934X_PLL_CPU_CONFIG_NFRAC GENMASK(5, 0)
+#define AR934X_PLL_CPU_CONFIG_NINT GENMASK(11, 6)
+#define AR934X_PLL_CPU_CONFIG_REFDIV GENMASK(16, 12)
+#define AR934X_PLL_CPU_CONFIG_OUTDIV GENMASK(20, 19)
+#define AR934X_PLL_DDR_CONFIG_NFRAC GENMASK(9, 0)
+#define AR934X_PLL_DDR_CONFIG_NINT GENMASK(15, 10)
+#define AR934X_PLL_DDR_CONFIG_REFDIV GENMASK(20, 16)
+#define AR934X_PLL_DDR_CONFIG_OUTDIV GENMASK(25, 23)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15
-#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV GENMASK(9, 5)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV GENMASK(14, 10)
+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV GENMASK(19, 15)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
-#define QCA953X_PLL_CPU_CONFIG_REG 0x00
-#define QCA953X_PLL_DDR_CONFIG_REG 0x04
-#define QCA953X_PLL_CLK_CTRL_REG 0x08
-#define QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
-#define QCA953X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
-#define QCA953X_PLL_CPU_CONFIG_NINT_SHIFT 6
-#define QCA953X_PLL_CPU_CONFIG_NINT_MASK 0x3f
-#define QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
-#define QCA953X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
-#define QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
-#define QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
-#define QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
-#define QCA953X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
-#define QCA953X_PLL_DDR_CONFIG_NINT_SHIFT 10
-#define QCA953X_PLL_DDR_CONFIG_NINT_MASK 0x3f
-#define QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
-#define QCA953X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
-#define QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
-#define QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+
+#define QCA953X_PLL_CPU_CONFIG_REG 0x00
+#define QCA953X_PLL_DDR_CONFIG_REG 0x04
+#define QCA953X_PLL_CLK_CTRL_REG 0x08
+#define QCA953X_PLL_CPU_CONFIG_NFRAC GENMASK(5, 0)
+#define QCA953X_PLL_CPU_CONFIG_NINT GENMASK(11, 6)
+#define QCA953X_PLL_CPU_CONFIG_REFDIV GENMASK(16, 12)
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV GENMASK(21, 19)
+#define QCA953X_PLL_DDR_CONFIG_NFRAC GENMASK(9, 0)
+#define QCA953X_PLL_DDR_CONFIG_NINT GENMASK(15, 10)
+#define QCA953X_PLL_DDR_CONFIG_REFDIV GENMASK(20, 16)
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV GENMASK(25, 23)
#define QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
#define QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
#define QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
-#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
-#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
-#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
-#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
-#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
-#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV GENMASK(9, 5)
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV GENMASK(14, 10)
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV GENMASK(19, 15)
#define QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
#define QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
#define QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
-#define QCA955X_PLL_CPU_CONFIG_REG 0x00
-#define QCA955X_PLL_DDR_CONFIG_REG 0x04
-#define QCA955X_PLL_CLK_CTRL_REG 0x08
-#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
-#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
-#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6
-#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f
-#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
-#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
-#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
-#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
-#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
-#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
-#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10
-#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f
-#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
-#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
-#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
-#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+
+#define QCA955X_PLL_CPU_CONFIG_REG 0x00
+#define QCA955X_PLL_DDR_CONFIG_REG 0x04
+#define QCA955X_PLL_CLK_CTRL_REG 0x08
+#define QCA955X_PLL_CPU_CONFIG_NFRAC GENMASK(5, 0)
+#define QCA955X_PLL_CPU_CONFIG_NINT GENMASK(11, 6)
+#define QCA955X_PLL_CPU_CONFIG_REFDIV GENMASK(16, 12)
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV GENMASK(20, 19)
+#define QCA955X_PLL_DDR_CONFIG_NFRAC GENMASK(9, 0)
+#define QCA955X_PLL_DDR_CONFIG_NINT GENMASK(15, 10)
+#define QCA955X_PLL_DDR_CONFIG_REFDIV GENMASK(20, 16)
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV GENMASK(25, 23)
#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
-#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
-#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
-#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
-#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
-#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
-#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV GENMASK(9, 5)
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV GENMASK(14, 10)
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV GENMASK(19, 15)
#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
#define QCA956X_PLL_CPU_CONFIG_REG 0x00
#define QCA956X_PLL_CPU_CONFIG1_REG 0x04
#define QCA956X_PLL_DDR_CONFIG_REG 0x08
#define QCA956X_PLL_DDR_CONFIG1_REG 0x0c
#define QCA956X_PLL_CLK_CTRL_REG 0x10
-#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
-#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
-#define QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
-#define QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
-#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0
-#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f
-#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5
-#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x1fff
-#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18
-#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff
-#define QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
-#define QCA956X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
-#define QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
-#define QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
-#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0
-#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f
-#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5
-#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x1fff
-#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18
-#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff
+#define QCA956X_PLL_CPU_CONFIG_REFDIV GENMASK(16, 12)
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV GENMASK(21, 19)
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L GENMASK(4, 0)
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H GENMASK(17, 5)
+#define QCA956X_PLL_CPU_CONFIG1_NINT GENMASK(26, 18)
+#define QCA956X_PLL_DDR_CONFIG_REFDIV GENMASK(20, 16)
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV GENMASK(25, 23)
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L GENMASK(4, 0)
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H GENMASK(17, 5)
+#define QCA956X_PLL_DDR_CONFIG1_NINT GENMASK(26, 18)
#define QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
#define QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
#define QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
-#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
-#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
-#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
-#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
-#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
-#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV GENMASK(9, 5)
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV GENMASK(14, 10)
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV GENMASK(19, 15)
#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL BIT(20)
#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
#define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
-#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0
-#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4
-#define AR934X_SRIF_DDR_DPLL1_REG 0x240
-#define AR934X_SRIF_DDR_DPLL2_REG 0x244
-#define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27
-#define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f
-#define AR934X_SRIF_DPLL1_NINT_SHIFT 18
-#define AR934X_SRIF_DPLL1_NINT_MASK 0x1ff
-#define AR934X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff
-#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30)
-#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13
-#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7
+
+#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0
+#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4
+#define AR934X_SRIF_DDR_DPLL1_REG 0x240
+#define AR934X_SRIF_DDR_DPLL2_REG 0x244
+#define AR934X_SRIF_DPLL1_REFDIV GENMASK(31, 27)
+#define AR934X_SRIF_DPLL1_NINT GENMASK(26, 18)
+#define AR934X_SRIF_DPLL1_NFRAC GENMASK(17, 0)
+#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30)
+#define AR934X_SRIF_DPLL2_OUTDIV GENMASK(15, 13)
#endif /* __CLK_ATH79_H */
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 5/8] clk: ath79: convert to clk_hw based registration
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
` (3 preceding siblings ...)
2026-11-04 5:58 ` [PATCH 4/8] clk: ath79: use FIELD_GET() for the PLL register fields Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 6/8] clk: ath79: fix the error handling Rosen Penev
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
Register the clocks with the clk_hw API and provide them with
of_clk_add_hw_provider() and of_clk_hw_onecell_get(), instead of the
struct clk based clk_register_*() and of_clk_src_onecell_get().
The AR724x and AR933x CPU, DDR and AHB clocks are fixed factors of the
reference clock, but named their parent "ref". That only works when the
reference clock is registered under that name, as the fallback from the
bootstrap pins is, or a device tree fixed clock whose node happens to be
called "ref". With any other node name, the clocks were orphans and ran
at 0 Hz. Give them the reference clock's clk_hw as the parent instead.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/clk/clk-ath79.c | 68 ++++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 32 deletions(-)
diff --git a/drivers/clk/clk-ath79.c b/drivers/clk/clk-ath79.c
index 8279d58be318..3afda29377b5 100644
--- a/drivers/clk/clk-ath79.c
+++ b/drivers/clk/clk-ath79.c
@@ -18,17 +18,14 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/slab.h>
#include <dt-bindings/clock/ath79-clk.h>
#include <asm/div64.h>
#include "clk-ath79.h"
-static struct clk *clks[ATH79_CLK_END];
-static struct clk_onecell_data clk_data = {
- .clks = clks,
- .clk_num = ARRAY_SIZE(clks),
-};
+static struct clk_hw_onecell_data *clk_data;
static const char * const clk_names[ATH79_CLK_END] = {
[ATH79_CLK_CPU] = "cpu",
@@ -44,42 +41,44 @@ static const char * __init ath79_clk_name(int type)
return clk_names[type];
}
-static void __init __ath79_set_clk(int type, const char *name, struct clk *clk)
+static void __init __ath79_set_clk(int type, const char *name,
+ struct clk_hw *hw)
{
- if (IS_ERR(clk))
+ if (IS_ERR(hw))
panic("failed to allocate %s clock structure", clk_names[type]);
- clks[type] = clk;
- clk_register_clkdev(clk, name, NULL);
+ clk_data->hws[type] = hw;
+ clk_hw_register_clkdev(hw, name, NULL);
}
-static struct clk * __init ath79_set_clk(int type, unsigned long rate)
+static void __init ath79_set_clk(int type, unsigned long rate)
{
const char *name = ath79_clk_name(type);
- struct clk *clk;
+ struct clk_hw *hw;
- clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate);
- __ath79_set_clk(type, name, clk);
- return clk;
+ hw = clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
+ __ath79_set_clk(type, name, hw);
}
-static struct clk * __init ath79_set_ff_clk(int type, const char *parent,
- unsigned int mult, unsigned int div)
+/* a clock derived from the reference clock by a fixed factor */
+static void __init ath79_set_ff_clk(int type, unsigned int mult,
+ unsigned int div)
{
const char *name = ath79_clk_name(type);
- struct clk *clk;
+ struct clk_hw *hw;
- clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div);
- __ath79_set_clk(type, name, clk);
- return clk;
+ hw = clk_hw_register_fixed_factor_parent_hw(NULL, name,
+ clk_data->hws[ATH79_CLK_REF],
+ 0, mult, div);
+ __ath79_set_clk(type, name, hw);
}
static unsigned long __init ath79_get_ref_rate(void)
{
- if (!clks[ATH79_CLK_REF])
+ if (!clk_data->hws[ATH79_CLK_REF])
panic("ath79: no reference clock");
- return clk_get_rate(clks[ATH79_CLK_REF]);
+ return clk_hw_get_rate(clk_data->hws[ATH79_CLK_REF]);
}
static void __init ar71xx_clocks_init(void __iomem *pll_base)
@@ -128,9 +127,9 @@ static void __init ar724x_clocks_init(void __iomem *pll_base)
ddr_div = FIELD_GET(AR724X_DDR_DIV, pll) + 1;
ahb_div = (FIELD_GET(AR724X_AHB_DIV, pll) + 1) * 2;
- ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div);
- ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div);
- ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div);
+ ath79_set_ff_clk(ATH79_CLK_CPU, mult, div);
+ ath79_set_ff_clk(ATH79_CLK_DDR, mult, div * ddr_div);
+ ath79_set_ff_clk(ATH79_CLK_AHB, mult, div * ahb_div);
}
static void __init ar933x_clocks_init(void __iomem *pll_base)
@@ -175,11 +174,11 @@ static void __init ar933x_clocks_init(void __iomem *pll_base)
ahb_div = FIELD_GET(AR933X_PLL_CLOCK_CTRL_AHB_DIV, clock_ctrl) + 1;
}
- ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul,
+ ath79_set_ff_clk(ATH79_CLK_CPU, ninit_mul,
ref_div * out_div * cpu_div);
- ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul,
+ ath79_set_ff_clk(ATH79_CLK_DDR, ninit_mul,
ref_div * out_div * ddr_div);
- ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul,
+ ath79_set_ff_clk(ATH79_CLK_AHB, ninit_mul,
ref_div * out_div * ahb_div);
}
@@ -504,6 +503,11 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
struct clk *ref_clk;
void __iomem *pll_base;
+ clk_data = kzalloc_flex(*clk_data, hws, ATH79_CLK_END);
+ if (!clk_data)
+ panic("ath79: can't allocate the clock data");
+ clk_data->num = ATH79_CLK_END;
+
/*
* The board's crystal. Without a rate in the device tree, the arch
* code registers it from the bootstrap pins.
@@ -512,7 +516,7 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
if (IS_ERR(ref_clk))
ref_clk = clk_get_sys(NULL, "ref");
if (!IS_ERR(ref_clk))
- clks[ATH79_CLK_REF] = ref_clk;
+ clk_data->hws[ATH79_CLK_REF] = __clk_get_hw(ref_clk);
pll_base = of_iomap(np, 0);
if (!pll_base) {
@@ -536,10 +540,10 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
else if (of_device_is_compatible(np, "qca,qca9560-pll"))
qca956x_clocks_init(pll_base);
- if (!clks[ATH79_CLK_MDIO])
- clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
+ if (!clk_data->hws[ATH79_CLK_MDIO])
+ clk_data->hws[ATH79_CLK_MDIO] = clk_data->hws[ATH79_CLK_REF];
- if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
+ if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data)) {
pr_err("%pOF: could not register clk provider\n", np);
goto err_iounmap;
}
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 6/8] clk: ath79: fix the error handling
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
` (4 preceding siblings ...)
2026-11-04 5:58 ` [PATCH 5/8] clk: ath79: convert to clk_hw based registration Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 7/8] clk: ath79: give each compatible its own init function Rosen Penev
2026-11-04 5:58 ` [PATCH 8/8] clk: ath79: share the fractional PLL calculation Rosen Penev
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
Report errors instead of crashing, and clean up after them:
- Check the ioremap() of the AR934x SRIF block, which was used without
a check.
- Without a reference clock, ath79_clocks_init_dt() called clk_put() on
an error pointer, which warns, and left the stale pointer in the clock
table. Bail out early instead.
- Return registration errors from the SoC init functions instead of
panicking, log them, and free the clock data.
- Drop the BUG_ON() on the clock index, which is always a constant.
The PLL registers aren't needed once the rates are known, so unmap them
after the SoC init in all cases, and unmap the SRIF block as soon as the
DPLLs are read. Registering the CPU, DDR and AHB clocks together also
removes some repetition.
If the clocks can't be set up, plat_time_init() still reports that it
can't get the CPU clock.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/clk/clk-ath79.c | 179 ++++++++++++++++++++++------------------
1 file changed, 100 insertions(+), 79 deletions(-)
diff --git a/drivers/clk/clk-ath79.c b/drivers/clk/clk-ath79.c
index 3afda29377b5..768c9e410b59 100644
--- a/drivers/clk/clk-ath79.c
+++ b/drivers/clk/clk-ath79.c
@@ -35,53 +35,71 @@ static const char * const clk_names[ATH79_CLK_END] = {
[ATH79_CLK_MDIO] = "mdio",
};
-static const char * __init ath79_clk_name(int type)
+static int __init ath79_add_clk(int type, struct clk_hw *hw)
{
- BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]);
- return clk_names[type];
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ clk_data->hws[type] = hw;
+ clk_hw_register_clkdev(hw, clk_names[type], NULL);
+ return 0;
}
-static void __init __ath79_set_clk(int type, const char *name,
- struct clk_hw *hw)
+static int __init ath79_set_clk(int type, unsigned long rate)
{
- if (IS_ERR(hw))
- panic("failed to allocate %s clock structure", clk_names[type]);
+ return ath79_add_clk(type, clk_hw_register_fixed_rate(NULL,
+ clk_names[type], NULL, 0, rate));
+}
- clk_data->hws[type] = hw;
- clk_hw_register_clkdev(hw, name, NULL);
+/* a clock derived from the reference clock by a fixed factor */
+static int __init ath79_set_ff_clk(int type, unsigned int mult,
+ unsigned int div)
+{
+ return ath79_add_clk(type, clk_hw_register_fixed_factor_parent_hw(NULL,
+ clk_names[type],
+ clk_data->hws[ATH79_CLK_REF],
+ 0, mult, div));
}
-static void __init ath79_set_clk(int type, unsigned long rate)
+static int __init ath79_set_clks(unsigned long cpu_rate,
+ unsigned long ddr_rate,
+ unsigned long ahb_rate)
{
- const char *name = ath79_clk_name(type);
- struct clk_hw *hw;
+ int ret;
+
+ ret = ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
+ if (ret)
+ return ret;
- hw = clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
- __ath79_set_clk(type, name, hw);
+ ret = ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
+ if (ret)
+ return ret;
+
+ return ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
}
-/* a clock derived from the reference clock by a fixed factor */
-static void __init ath79_set_ff_clk(int type, unsigned int mult,
- unsigned int div)
+static int __init ath79_set_ff_clks(unsigned int mult, unsigned int cpu_div,
+ unsigned int ddr_div, unsigned int ahb_div)
{
- const char *name = ath79_clk_name(type);
- struct clk_hw *hw;
+ int ret;
- hw = clk_hw_register_fixed_factor_parent_hw(NULL, name,
- clk_data->hws[ATH79_CLK_REF],
- 0, mult, div);
- __ath79_set_clk(type, name, hw);
+ ret = ath79_set_ff_clk(ATH79_CLK_CPU, mult, cpu_div);
+ if (ret)
+ return ret;
+
+ ret = ath79_set_ff_clk(ATH79_CLK_DDR, mult, ddr_div);
+ if (ret)
+ return ret;
+
+ return ath79_set_ff_clk(ATH79_CLK_AHB, mult, ahb_div);
}
static unsigned long __init ath79_get_ref_rate(void)
{
- if (!clk_data->hws[ATH79_CLK_REF])
- panic("ath79: no reference clock");
-
return clk_hw_get_rate(clk_data->hws[ATH79_CLK_REF]);
}
-static void __init ar71xx_clocks_init(void __iomem *pll_base)
+static int __init ar71xx_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -107,18 +125,14 @@ static void __init ar71xx_clocks_init(void __iomem *pll_base)
div = (FIELD_GET(AR71XX_AHB_DIV, pll) + 1) * 2;
ahb_rate = cpu_rate / div;
- ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
- ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
- ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
+ return ath79_set_clks(cpu_rate, ddr_rate, ahb_rate);
}
-static void __init ar724x_clocks_init(void __iomem *pll_base)
+static int __init ar724x_clocks_init(void __iomem *pll_base)
{
u32 mult, div, ddr_div, ahb_div;
u32 pll;
- ath79_get_ref_rate();
-
pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
mult = FIELD_GET(AR724X_PLL_FB, pll);
@@ -127,12 +141,10 @@ static void __init ar724x_clocks_init(void __iomem *pll_base)
ddr_div = FIELD_GET(AR724X_DDR_DIV, pll) + 1;
ahb_div = (FIELD_GET(AR724X_AHB_DIV, pll) + 1) * 2;
- ath79_set_ff_clk(ATH79_CLK_CPU, mult, div);
- ath79_set_ff_clk(ATH79_CLK_DDR, mult, div * ddr_div);
- ath79_set_ff_clk(ATH79_CLK_AHB, mult, div * ahb_div);
+ return ath79_set_ff_clks(mult, div, div * ddr_div, div * ahb_div);
}
-static void __init ar933x_clocks_init(void __iomem *pll_base)
+static int __init ar933x_clocks_init(void __iomem *pll_base)
{
u32 clock_ctrl;
u32 ref_div;
@@ -143,8 +155,6 @@ static void __init ar933x_clocks_init(void __iomem *pll_base)
u32 ddr_div;
u32 ahb_div;
- ath79_get_ref_rate();
-
clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG);
if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
ref_div = 1;
@@ -174,12 +184,9 @@ static void __init ar933x_clocks_init(void __iomem *pll_base)
ahb_div = FIELD_GET(AR933X_PLL_CLOCK_CTRL_AHB_DIV, clock_ctrl) + 1;
}
- ath79_set_ff_clk(ATH79_CLK_CPU, ninit_mul,
- ref_div * out_div * cpu_div);
- ath79_set_ff_clk(ATH79_CLK_DDR, ninit_mul,
- ref_div * out_div * ddr_div);
- ath79_set_ff_clk(ATH79_CLK_AHB, ninit_mul,
- ref_div * out_div * ahb_div);
+ return ath79_set_ff_clks(ninit_mul, ref_div * out_div * cpu_div,
+ ref_div * out_div * ddr_div,
+ ref_div * out_div * ahb_div);
}
static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
@@ -202,7 +209,7 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
return ret;
}
-static void __init ar934x_clocks_init(void __iomem *pll_base)
+static int __init ar934x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -211,8 +218,11 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
u32 cpu_pll, ddr_pll;
void __iomem *dpll_base;
+ int ret;
dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
+ if (!dpll_base)
+ return -ENOMEM;
ref_rate = ath79_get_ref_rate();
@@ -256,6 +266,8 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
nfrac, frac, out_div);
+ iounmap(dpll_base);
+
clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
postdiv = FIELD_GET(AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV, clk_ctrl);
@@ -285,18 +297,18 @@ static void __init ar934x_clocks_init(void __iomem *pll_base)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
- ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
- ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
+ ret = ath79_set_clks(cpu_rate, ddr_rate, ahb_rate);
+ if (ret)
+ return ret;
clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
- ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
+ return ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
- iounmap(dpll_base);
+ return 0;
}
-static void __init qca953x_clocks_init(void __iomem *pll_base)
+static int __init qca953x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -356,12 +368,10 @@ static void __init qca953x_clocks_init(void __iomem *pll_base)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
- ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
- ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
+ return ath79_set_clks(cpu_rate, ddr_rate, ahb_rate);
}
-static void __init qca955x_clocks_init(void __iomem *pll_base)
+static int __init qca955x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -421,12 +431,10 @@ static void __init qca955x_clocks_init(void __iomem *pll_base)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
- ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
- ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
+ return ath79_set_clks(cpu_rate, ddr_rate, ahb_rate);
}
-static void __init qca956x_clocks_init(void __iomem *pll_base)
+static int __init qca956x_clocks_init(void __iomem *pll_base)
{
unsigned long ref_rate;
unsigned long cpu_rate;
@@ -493,19 +501,18 @@ static void __init qca956x_clocks_init(void __iomem *pll_base)
else
ahb_rate = cpu_pll / (postdiv + 1);
- ath79_set_clk(ATH79_CLK_CPU, cpu_rate);
- ath79_set_clk(ATH79_CLK_DDR, ddr_rate);
- ath79_set_clk(ATH79_CLK_AHB, ahb_rate);
+ return ath79_set_clks(cpu_rate, ddr_rate, ahb_rate);
}
static void __init ath79_clocks_init_dt(struct device_node *np)
{
struct clk *ref_clk;
void __iomem *pll_base;
+ int ret = -ENODEV;
clk_data = kzalloc_flex(*clk_data, hws, ATH79_CLK_END);
if (!clk_data)
- panic("ath79: can't allocate the clock data");
+ return;
clk_data->num = ATH79_CLK_END;
/*
@@ -515,8 +522,11 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
ref_clk = of_clk_get(np, 0);
if (IS_ERR(ref_clk))
ref_clk = clk_get_sys(NULL, "ref");
- if (!IS_ERR(ref_clk))
- clk_data->hws[ATH79_CLK_REF] = __clk_get_hw(ref_clk);
+ if (IS_ERR(ref_clk)) {
+ pr_err("%pOF: no reference clock\n", np);
+ goto err_free;
+ }
+ clk_data->hws[ATH79_CLK_REF] = __clk_get_hw(ref_clk);
pll_base = of_iomap(np, 0);
if (!pll_base) {
@@ -525,36 +535,47 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
}
if (of_device_is_compatible(np, "qca,ar7100-pll"))
- ar71xx_clocks_init(pll_base);
+ ret = ar71xx_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,ar7240-pll") ||
of_device_is_compatible(np, "qca,ar9130-pll"))
- ar724x_clocks_init(pll_base);
+ ret = ar724x_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,ar9330-pll"))
- ar933x_clocks_init(pll_base);
+ ret = ar933x_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,ar9340-pll"))
- ar934x_clocks_init(pll_base);
+ ret = ar934x_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,qca9530-pll"))
- qca953x_clocks_init(pll_base);
+ ret = qca953x_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,qca9550-pll"))
- qca955x_clocks_init(pll_base);
+ ret = qca955x_clocks_init(pll_base);
else if (of_device_is_compatible(np, "qca,qca9560-pll"))
- qca956x_clocks_init(pll_base);
+ ret = qca956x_clocks_init(pll_base);
+
+ /* the rates are fixed, so the registers aren't needed any more */
+ iounmap(pll_base);
+
+ if (ret) {
+ pr_err("%pOF: failed to register the clocks: %pe\n", np,
+ ERR_PTR(ret));
+ goto err_clk;
+ }
if (!clk_data->hws[ATH79_CLK_MDIO])
clk_data->hws[ATH79_CLK_MDIO] = clk_data->hws[ATH79_CLK_REF];
- if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data)) {
- pr_err("%pOF: could not register clk provider\n", np);
- goto err_iounmap;
+ ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+ if (ret) {
+ pr_err("%pOF: could not register clk provider: %pe\n", np,
+ ERR_PTR(ret));
+ goto err_clk;
}
return;
-err_iounmap:
- iounmap(pll_base);
-
err_clk:
clk_put(ref_clk);
+err_free:
+ kfree(clk_data);
+ clk_data = NULL;
}
CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt);
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 7/8] clk: ath79: give each compatible its own init function
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
` (5 preceding siblings ...)
2026-11-04 5:58 ` [PATCH 6/8] clk: ath79: fix the error handling Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
2026-11-04 5:58 ` [PATCH 8/8] clk: ath79: share the fractional PLL calculation Rosen Penev
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
Every compatible already has its own CLK_OF_DECLARE(), yet they all
shared one init function, which then matched the compatible again to
pick the SoC code. Have each CLK_OF_DECLARE() call a small wrapper
that passes the SoC init function to the common code instead.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/clk/clk-ath79.c | 72 +++++++++++++++++++++++++++--------------
1 file changed, 47 insertions(+), 25 deletions(-)
diff --git a/drivers/clk/clk-ath79.c b/drivers/clk/clk-ath79.c
index 768c9e410b59..8086b4f6378c 100644
--- a/drivers/clk/clk-ath79.c
+++ b/drivers/clk/clk-ath79.c
@@ -504,11 +504,12 @@ static int __init qca956x_clocks_init(void __iomem *pll_base)
return ath79_set_clks(cpu_rate, ddr_rate, ahb_rate);
}
-static void __init ath79_clocks_init_dt(struct device_node *np)
+static void __init ath79_clocks_init_dt(struct device_node *np,
+ int (*soc_init)(void __iomem *pll_base))
{
struct clk *ref_clk;
void __iomem *pll_base;
- int ret = -ENODEV;
+ int ret;
clk_data = kzalloc_flex(*clk_data, hws, ATH79_CLK_END);
if (!clk_data)
@@ -534,21 +535,7 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
goto err_clk;
}
- if (of_device_is_compatible(np, "qca,ar7100-pll"))
- ret = ar71xx_clocks_init(pll_base);
- else if (of_device_is_compatible(np, "qca,ar7240-pll") ||
- of_device_is_compatible(np, "qca,ar9130-pll"))
- ret = ar724x_clocks_init(pll_base);
- else if (of_device_is_compatible(np, "qca,ar9330-pll"))
- ret = ar933x_clocks_init(pll_base);
- else if (of_device_is_compatible(np, "qca,ar9340-pll"))
- ret = ar934x_clocks_init(pll_base);
- else if (of_device_is_compatible(np, "qca,qca9530-pll"))
- ret = qca953x_clocks_init(pll_base);
- else if (of_device_is_compatible(np, "qca,qca9550-pll"))
- ret = qca955x_clocks_init(pll_base);
- else if (of_device_is_compatible(np, "qca,qca9560-pll"))
- ret = qca956x_clocks_init(pll_base);
+ ret = soc_init(pll_base);
/* the rates are fixed, so the registers aren't needed any more */
iounmap(pll_base);
@@ -578,11 +565,46 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
clk_data = NULL;
}
-CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt);
-CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt);
+static void __init ar71xx_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, ar71xx_clocks_init);
+}
+
+static void __init ar724x_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, ar724x_clocks_init);
+}
+
+static void __init ar933x_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, ar933x_clocks_init);
+}
+
+static void __init ar934x_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, ar934x_clocks_init);
+}
+
+static void __init qca953x_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, qca953x_clocks_init);
+}
+
+static void __init qca955x_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, qca955x_clocks_init);
+}
+
+static void __init qca956x_clocks_init_dt(struct device_node *np)
+{
+ ath79_clocks_init_dt(np, qca956x_clocks_init);
+}
+
+CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ar71xx_clocks_init_dt);
+CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ar724x_clocks_init_dt);
+CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ar724x_clocks_init_dt);
+CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ar933x_clocks_init_dt);
+CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ar934x_clocks_init_dt);
+CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", qca953x_clocks_init_dt);
+CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", qca955x_clocks_init_dt);
+CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", qca956x_clocks_init_dt);
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 8/8] clk: ath79: share the fractional PLL calculation
2026-11-04 5:58 [PATCH 0/8] clk: ath79: move the PLL clock driver to drivers/clk Rosen Penev
` (6 preceding siblings ...)
2026-11-04 5:58 ` [PATCH 7/8] clk: ath79: give each compatible its own init function Rosen Penev
@ 2026-11-04 5:58 ` Rosen Penev
7 siblings, 0 replies; 9+ messages in thread
From: Rosen Penev @ 2026-11-04 5:58 UTC (permalink / raw)
To: linux-mips, Thomas Bogendoerfer, Stephen Boyd
Cc: Brian Masney, Jerome Brunet, Alban Bedel, Antony Pavlov,
open list, open list:COMMON CLK FRAMEWORK
AR934x, QCA953x and QCA955x compute their CPU and DDR PLL rates with the
same formula, ref / ref_div * (nint + nfrac / frac) / 2^out_div, written
three different ways. Use one helper for all of them, with 64-bit
intermediates.
That fixes the QCA955x DDR PLL rate, whose nfrac * ref product could
overflow 32 bits: with a 40 MHz reference clock it did for any nfrac
above 107, and with 25 MHz for any above 171. The other rates are
unchanged, as checked against the old code with random register values.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/clk/clk-ath79.c | 47 +++++++++++++----------------------------
1 file changed, 15 insertions(+), 32 deletions(-)
diff --git a/drivers/clk/clk-ath79.c b/drivers/clk/clk-ath79.c
index 8086b4f6378c..f9a8c9b9aa24 100644
--- a/drivers/clk/clk-ath79.c
+++ b/drivers/clk/clk-ath79.c
@@ -10,6 +10,7 @@
#include <linux/bitfield.h>
#include <linux/kernel.h>
+#include <linux/math64.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/err.h>
@@ -21,7 +22,6 @@
#include <linux/slab.h>
#include <dt-bindings/clock/ath79-clk.h>
-#include <asm/div64.h>
#include "clk-ath79.h"
@@ -189,24 +189,17 @@ static int __init ar933x_clocks_init(void __iomem *pll_base)
ref_div * out_div * ahb_div);
}
-static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
- u32 frac, u32 out_div)
+/* a fractional PLL: ref / ref_div * (nint + nfrac / frac) / 2^out_div */
+static unsigned long __init ath79_pll_rate(unsigned long ref, u32 ref_div,
+ u32 nint, u32 nfrac, u32 frac,
+ u32 out_div)
{
- u64 t;
- u32 ret;
+ unsigned long rate;
- t = ref;
- t *= nint;
- do_div(t, ref_div);
- ret = t;
+ rate = div_u64((u64)ref * nint, ref_div);
+ rate += div_u64((u64)ref * nfrac, ref_div * frac);
- t = ref;
- t *= nfrac;
- do_div(t, ref_div * frac);
- ret += t;
-
- ret /= (1 << out_div);
- return ret;
+ return rate >> out_div;
}
static int __init ar934x_clocks_init(void __iomem *pll_base)
@@ -243,8 +236,7 @@ static int __init ar934x_clocks_init(void __iomem *pll_base)
frac = 1 << 6;
}
- cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
- nfrac, frac, out_div);
+ cpu_pll = ath79_pll_rate(ref_rate, ref_div, nint, nfrac, frac, out_div);
pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
@@ -263,8 +255,7 @@ static int __init ar934x_clocks_init(void __iomem *pll_base)
frac = 1 << 10;
}
- ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint,
- nfrac, frac, out_div);
+ ddr_pll = ath79_pll_rate(ref_rate, ref_div, nint, nfrac, frac, out_div);
iounmap(dpll_base);
@@ -325,9 +316,7 @@ static int __init qca953x_clocks_init(void __iomem *pll_base)
nint = FIELD_GET(QCA953X_PLL_CPU_CONFIG_NINT, pll);
frac = FIELD_GET(QCA953X_PLL_CPU_CONFIG_NFRAC, pll);
- cpu_pll = nint * ref_rate / ref_div;
- cpu_pll += frac * (ref_rate >> 6) / ref_div;
- cpu_pll /= (1 << out_div);
+ cpu_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 6, out_div);
pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG);
out_div = FIELD_GET(QCA953X_PLL_DDR_CONFIG_OUTDIV, pll);
@@ -335,9 +324,7 @@ static int __init qca953x_clocks_init(void __iomem *pll_base)
nint = FIELD_GET(QCA953X_PLL_DDR_CONFIG_NINT, pll);
frac = FIELD_GET(QCA953X_PLL_DDR_CONFIG_NFRAC, pll);
- ddr_pll = nint * ref_rate / ref_div;
- ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
- ddr_pll /= (1 << out_div);
+ ddr_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 10, out_div);
clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG);
@@ -388,9 +375,7 @@ static int __init qca955x_clocks_init(void __iomem *pll_base)
nint = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NINT, pll);
frac = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NFRAC, pll);
- cpu_pll = nint * ref_rate / ref_div;
- cpu_pll += frac * ref_rate / (ref_div * (1 << 6));
- cpu_pll /= (1 << out_div);
+ cpu_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 6, out_div);
pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG);
out_div = FIELD_GET(QCA955X_PLL_DDR_CONFIG_OUTDIV, pll);
@@ -398,9 +383,7 @@ static int __init qca955x_clocks_init(void __iomem *pll_base)
nint = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NINT, pll);
frac = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NFRAC, pll);
- ddr_pll = nint * ref_rate / ref_div;
- ddr_pll += frac * ref_rate / (ref_div * (1 << 10));
- ddr_pll /= (1 << out_div);
+ ddr_pll = ath79_pll_rate(ref_rate, ref_div, nint, frac, 1 << 10, out_div);
clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG);
--
2.56.0
^ permalink raw reply [flat|nested] 9+ messages in thread