summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-07-06 18:26:12 -0600
committerTom Rini <[email protected]>2026-07-06 18:26:12 -0600
commitee5d46b45ec0c63f8f9dd1e816e0dac3452ccc3d (patch)
tree800cd9e204ca027144070101884c0d5d3c00130f /drivers/clk
parentece349ade2973e220f524ce59e59711cc919263f (diff)
parenta18265f1ccb7a272721ed4286ed3b5a6182ff424 (diff)
Merge branch 'next'
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Kconfig4
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/altera/clk-mem-n5x.c9
-rw-r--r--drivers/clk/altera/clk-n5x.c8
-rw-r--r--drivers/clk/aspeed/Makefile1
-rw-r--r--drivers/clk/aspeed/clk_ast2500.c8
-rw-r--r--drivers/clk/aspeed/clk_ast2600.c8
-rw-r--r--drivers/clk/aspeed/clk_ast2700.c952
-rw-r--r--drivers/clk/at91/sam9x60.c2
-rw-r--r--drivers/clk/at91/sam9x7.c2
-rw-r--r--drivers/clk/at91/sama7d65.c6
-rw-r--r--drivers/clk/at91/sama7g5.c6
-rw-r--r--drivers/clk/at91/sckc.c5
-rw-r--r--drivers/clk/clk-divider.c16
-rw-r--r--drivers/clk/clk-hsdk-cgu.c4
-rw-r--r--drivers/clk/clk-stub.c6
-rw-r--r--drivers/clk/imx/clk-imx6q.c255
-rw-r--r--drivers/clk/owl/Kconfig8
-rw-r--r--drivers/clk/qcom/Kconfig8
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/clock-qcm2290.c2
-rw-r--r--drivers/clk/qcom/clock-qcs615.c63
-rw-r--r--drivers/clk/qcom/clock-sa8775p.c63
-rw-r--r--drivers/clk/qcom/clock-sc7280.c52
-rw-r--r--drivers/clk/qcom/clock-sm6125.c260
-rw-r--r--drivers/clk/renesas/Kconfig8
-rw-r--r--drivers/clk/sophgo/clk-cv1800b.c5
-rw-r--r--drivers/clk/sunxi/clk_sunxi.c2
-rw-r--r--drivers/clk/ti/clk-ctrl.c48
29 files changed, 1737 insertions, 77 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c2da7b3938b..addcece4da3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -134,8 +134,8 @@ config CLK_CDCE9XX
bool "Enable CDCD9XX clock driver"
depends on CLK && ARCH_OMAP2PLUS
help
- Enable the clock synthesizer driver for CDCE913/925/937/949
- series of chips.
+ Enable the clock synthesizer driver for CDCE913/925/937/949
+ series of chips.
config CLK_ICS8N3QV01
bool "Enable ICS8N3QV01 VCXO driver"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5f0c0d8a5c2..c37ef75d420 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_$(PHASE_)CLK_STUB) += clk-stub.o
obj-y += adi/
obj-y += airoha/
obj-y += analogbits/
-obj-y += imx/
+obj-$(CONFIG_MACH_IMX) += imx/
obj-$(CONFIG_CLK_JH7110) += starfive/
obj-y += tegra/
obj-y += ti/
diff --git a/drivers/clk/altera/clk-mem-n5x.c b/drivers/clk/altera/clk-mem-n5x.c
index ac59571a853..149e3016dd3 100644
--- a/drivers/clk/altera/clk-mem-n5x.c
+++ b/drivers/clk/altera/clk-mem-n5x.c
@@ -103,12 +103,13 @@ static int socfpga_mem_clk_enable(struct clk *clk)
static int socfpga_mem_clk_of_to_plat(struct udevice *dev)
{
struct socfpga_mem_clk_plat *plat = dev_get_plat(dev);
- fdt_addr_t addr;
+ void __iomem *addr;
- addr = devfdt_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_ptr(dev);
+ if (!addr)
return -EINVAL;
- plat->regs = (void __iomem *)addr;
+
+ plat->regs = addr;
return 0;
}
diff --git a/drivers/clk/altera/clk-n5x.c b/drivers/clk/altera/clk-n5x.c
index 185c9028a78..0a3bae38589 100644
--- a/drivers/clk/altera/clk-n5x.c
+++ b/drivers/clk/altera/clk-n5x.c
@@ -454,12 +454,12 @@ static int socfpga_clk_probe(struct udevice *dev)
static int socfpga_clk_of_to_plat(struct udevice *dev)
{
struct socfpga_clk_plat *plat = dev_get_plat(dev);
- fdt_addr_t addr;
+ void __iomem *addr;
- addr = devfdt_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_ptr(dev);
+ if (!addr)
return -EINVAL;
- plat->regs = (void __iomem *)addr;
+ plat->regs = addr;
return 0;
}
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
index 84776e5265e..285180b67cf 100644
--- a/drivers/clk/aspeed/Makefile
+++ b/drivers/clk/aspeed/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
obj-$(CONFIG_ASPEED_AST2600) += clk_ast2600.o
+obj-$(CONFIG_ASPEED_AST2700) += clk_ast2700.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index a330dcda4dc..94c7f662319 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -534,7 +534,7 @@ static int ast2500_clk_enable(struct clk *clk)
return 0;
}
-struct clk_ops ast2500_clk_ops = {
+static const struct clk_ops ast2500_clk_ops = {
.get_rate = ast2500_clk_get_rate,
.set_rate = ast2500_clk_set_rate,
.enable = ast2500_clk_enable,
@@ -544,9 +544,9 @@ static int ast2500_clk_of_to_plat(struct udevice *dev)
{
struct ast2500_clk_priv *priv = dev_get_priv(dev);
- priv->scu = devfdt_get_addr_ptr(dev);
- if (IS_ERR(priv->scu))
- return PTR_ERR(priv->scu);
+ priv->scu = dev_read_addr_ptr(dev);
+ if (!priv->scu)
+ return -EINVAL;
return 0;
}
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
index 535010b7941..74209e947ed 100644
--- a/drivers/clk/aspeed/clk_ast2600.c
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -1161,7 +1161,7 @@ static void ast2600_clk_dump(struct udevice *dev)
}
#endif
-struct clk_ops ast2600_clk_ops = {
+static const struct clk_ops ast2600_clk_ops = {
.get_rate = ast2600_clk_get_rate,
.set_rate = ast2600_clk_set_rate,
.enable = ast2600_clk_enable,
@@ -1174,9 +1174,9 @@ static int ast2600_clk_probe(struct udevice *dev)
{
struct ast2600_clk_priv *priv = dev_get_priv(dev);
- priv->scu = devfdt_get_addr_ptr(dev);
- if (IS_ERR(priv->scu))
- return PTR_ERR(priv->scu);
+ priv->scu = dev_read_addr_ptr(dev);
+ if (!priv->scu)
+ return -EINVAL;
ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
diff --git a/drivers/clk/aspeed/clk_ast2700.c b/drivers/clk/aspeed/clk_ast2700.c
new file mode 100644
index 00000000000..ca76abef48f
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2700.c
@@ -0,0 +1,952 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <asm/arch/scu_ast2700.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <syscon.h>
+#include <linux/bitfield.h>
+
+#include <dt-bindings/clock/aspeed,ast2700-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * RGMII clock source tree
+ * HPLL -->|\
+ * | |---->| divider |---->RGMII 125M for MAC#0 & MAC#1
+ * APLL -->|/
+ */
+#define RGMII_DEFAULT_CLK_SRC SCU1_CLK_HPLL
+
+struct mac_delay_config {
+ u32 tx_delay_1000;
+ u32 rx_delay_1000;
+ u32 tx_delay_100;
+ u32 rx_delay_100;
+ u32 tx_delay_10;
+ u32 rx_delay_10;
+};
+
+typedef int (*ast2700_clk_init_fn)(struct udevice *dev);
+
+struct ast2700_clk_priv {
+ void __iomem *reg;
+ ast2700_clk_init_fn init;
+};
+
+static u32 ast2700_soc1_get_pll_rate(struct ast2700_scu1 *scu, int pll_idx)
+{
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+
+ switch (pll_idx) {
+ case SCU1_CLK_HPLL:
+ pll_reg.w = readl(&scu->hpll);
+ break;
+ case SCU1_CLK_APLL:
+ pll_reg.w = readl(&scu->apll);
+ break;
+ case SCU1_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ }
+
+ if (!pll_reg.b.bypass) {
+ mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1);
+ div = (pll_reg.b.p + 1);
+ }
+
+ return ((CLKIN_25M * mul) / div);
+}
+
+#define SCU_CLKSEL2_HCLK_DIV_MASK GENMASK(22, 20)
+#define SCU_CLKSEL2_HCLK_DIV_SHIFT 20
+
+static u32 ast2700_soc1_get_hclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 clk_sel2 = readl(&scu->clk_sel2);
+ u32 hclk_div = (clk_sel2 & SCU_CLKSEL2_HCLK_DIV_MASK) >>
+ SCU_CLKSEL2_HCLK_DIV_SHIFT;
+
+ if (!hclk_div)
+ hclk_div = 2;
+ else
+ hclk_div++;
+
+ return (rate / hclk_div);
+}
+
+#define SCU1_CLKSEL1_PCLK_DIV_MASK GENMASK(20, 18)
+#define SCU1_CLKSEL1_PCLK_DIV_SHIFT 18
+
+static u32 ast2700_soc1_get_pclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+
+ u32 clk_sel1 = readl(&scu->clk_sel1);
+ u32 pclk_div = (clk_sel1 & SCU1_CLKSEL1_PCLK_DIV_MASK) >>
+ SCU1_CLKSEL1_PCLK_DIV_SHIFT;
+
+ return (rate / ((pclk_div + 1) * 2));
+}
+
+#define SCU_UART_CLKGEN_N_MASK GENMASK(17, 8)
+#define SCU_UART_CLKGEN_N_SHIFT 8
+#define SCU_UART_CLKGEN_R_MASK GENMASK(7, 0)
+#define SCU_UART_CLKGEN_R_SHIFT 0
+
+static u32 ast2700_soc1_get_uart_uxclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 uxclk_sel = readl(&scu->clk_sel2) & GENMASK(1, 0);
+ u32 uxclk_ctrl = readl(&scu->uxclk_ctrl);
+ u32 rate;
+
+ switch (uxclk_sel) {
+ case 0:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ break;
+ }
+
+ u32 n = (uxclk_ctrl & SCU_UART_CLKGEN_N_MASK) >>
+ SCU_UART_CLKGEN_N_SHIFT;
+ u32 r = (uxclk_ctrl & SCU_UART_CLKGEN_R_MASK) >>
+ SCU_UART_CLKGEN_R_SHIFT;
+
+ return ((rate * r) / (n * 2));
+}
+
+#define SCU_HUART_CLKGEN_N_MASK GENMASK(17, 8)
+#define SCU_HUART_CLKGEN_N_SHIFT 8
+#define SCU_HUART_CLKGEN_R_MASK GENMASK(7, 0)
+#define SCU_HUART_CLKGEN_R_SHIFT 0
+
+static u32 ast2700_soc1_get_uart_huxclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 huxclk_sel = (readl(&scu->clk_sel2) & GENMASK(4, 3)) >> 3;
+ u32 huxclk_ctrl = readl(&scu->huxclk_ctrl);
+ u32 n = (huxclk_ctrl & SCU_HUART_CLKGEN_N_MASK) >>
+ SCU_HUART_CLKGEN_N_SHIFT;
+ u32 r = (huxclk_ctrl & SCU_HUART_CLKGEN_R_MASK) >>
+ SCU_HUART_CLKGEN_R_SHIFT;
+ u32 rate;
+
+ switch (huxclk_sel) {
+ case 0:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ break;
+ }
+
+ return ((rate * r) / (n * 2));
+}
+
+#define SCU_CLKSRC1_SDIO_DIV_MASK GENMASK(16, 14)
+#define SCU_CLKSRC1_SDIO_DIV_SHIFT 14
+#define SCU_CLKSRC1_SDIO_SEL BIT(13)
+const int ast2700_sd_div_tbl[] = {
+ 2, 2, 3, 4, 5, 6, 7, 8
+};
+
+static u32 ast2700_soc1_get_sdio_clk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = 0;
+ u32 clk_sel1 = readl(&scu->clk_sel1);
+ u32 div = (clk_sel1 & SCU_CLKSRC1_SDIO_DIV_MASK) >>
+ SCU_CLKSRC1_SDIO_DIV_SHIFT;
+
+ if (clk_sel1 & SCU_CLKSRC1_SDIO_SEL)
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ else
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+
+ if (!div)
+ div = 1;
+
+ div++;
+
+ return (rate / div);
+}
+
+static void ast2700_init_sdclk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (src_clk / ast2700_sd_div_tbl[i] <= 125000000)
+ break;
+ }
+
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~(SCU_CLKSRC1_SDIO_DIV_MASK | SCU_CLKSRC1_SDIO_SEL);
+ reg_280 |= i << SCU_CLKSRC1_SDIO_DIV_SHIFT;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static u32
+ast2700_soc1_get_uart_clk_rate(struct ast2700_scu1 *scu, int uart_idx)
+{
+ u32 rate = 0;
+
+ if (readl(&scu->clk_sel1) & BIT(uart_idx))
+ rate = ast2700_soc1_get_uart_huxclk_rate(scu);
+ else
+ rate = ast2700_soc1_get_uart_uxclk_rate(scu);
+
+ return rate;
+}
+
+static ulong ast2700_soc1_clk_get_rate(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case SCU1_CLK_HPLL:
+ case SCU1_CLK_APLL:
+ case SCU1_CLK_DPLL:
+ rate = ast2700_soc1_get_pll_rate(scu, clk->id);
+ break;
+ case SCU1_CLK_AHB:
+ rate = ast2700_soc1_get_hclk_rate(scu);
+ break;
+ case SCU1_CLK_APB:
+ rate = ast2700_soc1_get_pclk_rate(scu);
+ break;
+ case SCU1_CLK_GATE_UART0CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 0);
+ break;
+ case SCU1_CLK_GATE_UART1CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 1);
+ break;
+ case SCU1_CLK_GATE_UART2CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 2);
+ break;
+ case SCU1_CLK_GATE_UART3CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 3);
+ break;
+ case SCU1_CLK_GATE_UART5CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 5);
+ break;
+ case SCU1_CLK_GATE_UART6CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 6);
+ break;
+ case SCU1_CLK_GATE_UART7CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 7);
+ break;
+ case SCU1_CLK_GATE_UART8CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 8);
+ break;
+ case SCU1_CLK_GATE_UART9CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 9);
+ break;
+ case SCU1_CLK_GATE_UART10CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 10);
+ break;
+ case SCU1_CLK_GATE_UART11CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 11);
+ break;
+ case SCU1_CLK_GATE_UART12CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 12);
+ break;
+ case SCU1_CLK_GATE_SDCLK:
+ rate = ast2700_soc1_get_sdio_clk_rate(scu);
+ break;
+ case SCU1_CLK_UXCLK:
+ rate = ast2700_soc1_get_uart_uxclk_rate(scu);
+ break;
+ case SCU1_CLK_HUXCLK:
+ rate = ast2700_soc1_get_uart_huxclk_rate(scu);
+ break;
+ default:
+ debug("%s: unknown clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static int ast2700_soc1_clk_enable(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+ u32 clkgate_bit;
+
+ if (clk->id >= 32)
+ clkgate_bit = BIT(clk->id - 32);
+ else
+ clkgate_bit = BIT(clk->id);
+
+ writel(clkgate_bit, &scu->clkgate_clr1);
+
+ return 0;
+}
+
+static const struct clk_ops ast2700_soc1_clk_ops = {
+ .get_rate = ast2700_soc1_clk_get_rate,
+ .enable = ast2700_soc1_clk_enable,
+};
+
+#define SCU_HW_REVISION_ID GENMASK(23, 16)
+#define SCU_CPUCLK_MASK GENMASK(4, 2)
+#define SCU_CPUCLK_SHIFT 2
+static u32 ast2700_soc0_get_hpll_rate(struct ast2700_scu0 *scu)
+{
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+ u32 rate;
+
+ pll_reg.w = readl(&scu->hpll);
+
+ if ((chip_id1 & SCU_HW_REVISION_ID) && (hwstrap1 & BIT(3))) {
+ switch ((hwstrap1 & GENMASK(4, 2)) >> 2) {
+ case 2:
+ rate = 1800000000;
+ break;
+ case 3:
+ rate = 1700000000;
+ break;
+ case 6:
+ rate = 1200000000;
+ break;
+ case 7:
+ rate = 800000000;
+ break;
+ default:
+ rate = 1600000000;
+ }
+ } else if (hwstrap1 & GENMASK(3, 2)) {
+ switch ((hwstrap1 & GENMASK(3, 2)) >> 2) {
+ case 1U:
+ rate = 1900000000;
+ break;
+ case 2U:
+ rate = 1800000000;
+ break;
+ case 3U:
+ rate = 1700000000;
+ break;
+ default:
+ rate = 1600000000;
+ break;
+ }
+ } else {
+ if (pll_reg.b.bypass == 0U) {
+ /* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+ div = (pll_reg.b.p + 1);
+ }
+ rate = ((CLKIN_25M * mul) / div);
+ }
+
+ return rate;
+}
+
+static u32 ast2700_soc0_get_pll_rate(struct ast2700_scu0 *scu, int pll_idx)
+{
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+ u32 rate;
+
+ switch (pll_idx) {
+ case SCU0_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ case SCU0_CLK_MPLL:
+ pll_reg.w = readl(&scu->mpll);
+ break;
+ default:
+ pr_err("%s: invalid PSP clock source (%d)\n", __func__, pll_idx);
+ return 0;
+ }
+
+ if (pll_reg.b.bypass == 0U) {
+ if (pll_idx == SCU0_CLK_MPLL) {
+ /* F = 25Mhz * [M / (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m) / ((pll_reg.b.n + 1));
+ div = (pll_reg.b.p + 1);
+ } else {
+ /* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+ div = (pll_reg.b.p + 1);
+ }
+ }
+
+ rate = ((CLKIN_25M * mul) / div);
+
+ return rate;
+}
+
+/*
+ * AST2700A1
+ * SCU010[4:2]:
+ * 000: CPUCLK=MPLL=1.6GHz (MPLL default setting with SCU310, SCU314)
+ * 001: CPUCLK=HPLL=2.0GHz (HPLL default setting with SCU300, SCU304)
+ * 010: CPUCLK=HPLL=1.8GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 011: CPUCLK=HPLL=1.7GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 100: CPUCLK=MPLL/2=800MHz (MPLL default setting with SCU310, SCU314)
+ * 101: CPUCLK=HPLL/2=1.0GHz (HPLL default setting with SCU300, SCU304)
+ * 110: CPUCLK=HPLL=1.2GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 111: CPUCLK=HPLL=800MHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ */
+
+static u32 ast2700_soc0_get_pspclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ u32 rate;
+ int cpuclk_set;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ cpuclk_set = (hwstrap1 & SCU_CPUCLK_MASK) >> SCU_CPUCLK_SHIFT;
+ switch (cpuclk_set) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 6:
+ case 7:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 4:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 2;
+ break;
+ case 5:
+ rate = ast2700_soc0_get_hpll_rate(scu) / 2;
+ break;
+ default:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ }
+ } else {
+ if (hwstrap1 & BIT(4))
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ else
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ }
+ return rate;
+}
+
+static u32 ast2700_soc0_get_axi0clk_rate(struct ast2700_scu0 *scu)
+{
+ return ast2700_soc0_get_pspclk_rate(scu) / 2;
+}
+
+#define SCU_AHB_DIV_MASK GENMASK(6, 5)
+#define SCU_AHB_DIV_SHIFT 5
+static u32 hclk_ast2700a1_div_table[] = {
+ 6, 5, 4, 7,
+};
+
+static u32 ast2700_soc0_get_hclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 src_clk;
+ int div;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ if (hwstrap1 & BIT(7))
+ src_clk = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ else
+ src_clk = ast2700_soc0_get_hpll_rate(scu);
+
+ div = (hwstrap1 & SCU_AHB_DIV_MASK) >> SCU_AHB_DIV_SHIFT;
+ div = hclk_ast2700a1_div_table[div];
+ } else {
+ if (hwstrap1 & BIT(7))
+ src_clk = ast2700_soc0_get_hpll_rate(scu);
+ else
+ src_clk = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+
+ div = (hwstrap1 & SCU_AHB_DIV_MASK) >> SCU_AHB_DIV_SHIFT;
+
+ if (!div)
+ div = 4;
+ else
+ div = (div + 1) * 2;
+ }
+ return (src_clk / div);
+}
+
+static u32 ast2700_soc0_get_axi1clk_rate(struct ast2700_scu0 *scu)
+{
+ if (readl(&scu->chip_id1) & SCU_HW_REVISION_ID)
+ return ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+ else
+ return ast2700_soc0_get_hclk_rate(scu);
+}
+
+#define SCU0_CLKSEL1_PCLK_DIV_MASK GENMASK(25, 23)
+#define SCU0_CLKSEL1_PCLK_DIV_SHIFT 23
+
+static u32 ast2700_soc0_get_pclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 rate = ast2700_soc0_get_axi0clk_rate(scu);
+ u32 clksel1 = readl(&scu->clk_sel1);
+ int div;
+
+ div = (clksel1 & SCU0_CLKSEL1_PCLK_DIV_MASK) >>
+ SCU0_CLKSEL1_PCLK_DIV_SHIFT;
+
+ return (rate / ((div + 1) * 2));
+}
+
+#define SCU_CLKSEL1_MPHYCLK_SEL_MASK GENMASK(19, 18)
+#define SCU_CLKSEL1_MPHYCLK_SEL_SHIFT 18
+#define SCU_CLKSEL1_MPHYCLK_DIV_MASK GENMASK(7, 0)
+static u32 ast2700_soc0_get_mphyclk_rate(struct ast2700_scu0 *scu)
+{
+ int div = readl(&scu->mphyclk_para) & SCU_CLKSEL1_MPHYCLK_DIV_MASK;
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 clk_sel2;
+ int clk_sel;
+ u32 rate = 0;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ clk_sel2 = readl(&scu->clk_sel2);
+ clk_sel = (clk_sel2 & SCU_CLKSEL1_MPHYCLK_SEL_MASK)
+ >> SCU_CLKSEL1_MPHYCLK_SEL_SHIFT;
+ switch (clk_sel) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 2:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_DPLL);
+ break;
+ case 3:
+ rate = 26000000;
+ break;
+ }
+ } else {
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ }
+
+ return (rate / (div + 1));
+}
+
+static void ast2700_mphy_clk_init(struct ast2700_scu0 *scu)
+{
+ u32 clksrc1, rate = 0;
+ int i;
+
+ /* set mphy clk */
+ if (readl(&scu->chip_id1) & SCU_HW_REVISION_ID) {
+ clksrc1 = (readl(&scu->clk_sel2) & SCU_CLKSEL1_MPHYCLK_SEL_MASK)
+ >> SCU_CLKSEL1_MPHYCLK_SEL_SHIFT;
+ switch (clksrc1) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 2:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_DPLL);
+ break;
+ case 3:
+ rate = 26000000;
+ break;
+ }
+ } else {
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ }
+
+ for (i = 1; i < 256; i++) {
+ if ((rate / i) <= 26000000)
+ break;
+ }
+
+ /* register defined the value plus 1 is divider*/
+ i--;
+ writel(i, &scu->mphyclk_para);
+}
+
+#define SCU_CLKSRC1_EMMC_DIV_MASK GENMASK(14, 12)
+#define SCU_CLKSRC1_EMMC_DIV_SHIFT 12
+#define SCU_CLKSRC1_EMMC_SEL BIT(11)
+static u32 ast2700_soc0_get_emmcclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 clksel1 = readl(&scu->clk_sel1);
+ u32 rate;
+ int div;
+
+ div = (clksel1 & SCU_CLKSRC1_EMMC_DIV_MASK) >> SCU_CLKSRC1_EMMC_DIV_SHIFT;
+
+ if (clksel1 & SCU_CLKSRC1_EMMC_SEL)
+ rate = ast2700_soc0_get_hpll_rate(scu) / 4;
+ else
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+
+ return (rate / ((div + 1) * 2));
+}
+
+static void ast2700_emmc_init(struct ast2700_scu0 *scu)
+{
+ u32 clksrc1, rate, div;
+ int i;
+
+ /* set clk/cmd driving */
+ writel(2, &scu->gpio18d0_ioctrl); /* clk driving */
+ writel(1, &scu->gpio18d1_ioctrl); /* cmd driving */
+ writel(1, &scu->gpio18d2_ioctrl); /* data0 driving */
+ writel(1, &scu->gpio18d3_ioctrl); /* data1 driving */
+ writel(1, &scu->gpio18d4_ioctrl); /* data2 driving */
+ writel(1, &scu->gpio18d5_ioctrl); /* data2 driving */
+
+ /* emmc clk: set clk src mpll/4:400Mhz */
+ clksrc1 = readl(&scu->clk_sel1);
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+ for (i = 0; i < 8; i++) {
+ div = (i + 1) * 2;
+ if ((rate / div) <= 200000000)
+ break;
+ }
+
+ clksrc1 &= ~(SCU_CLKSRC1_EMMC_DIV_MASK | SCU_CLKSRC1_EMMC_SEL);
+ clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT);
+ writel(clksrc1, &scu->clk_sel1);
+}
+
+static void ast2700_vga_clk_init(struct ast2700_scu0 *scu)
+{
+ if ((readl(&scu->chip_id1) & SCU_HW_REVISION_ID) == 0)
+ return;
+
+ // Use d0clk/d1clk which generated from hpll for vga0/1 after A0
+ // Use CRT1clk as soc display source
+ setbits_le32(&scu->clk_sel3, BIT(14) | BIT(13) | BIT(12));
+}
+
+static u32 ast2700_soc0_get_uartclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 clksel2 = readl(&scu->clk_sel2);
+ u32 div = 1;
+ u32 rate;
+
+ if (clksel2 & BIT(15))
+ rate = 192000000;
+ else
+ rate = 24000000;
+
+ if (clksel2 & BIT(30))
+ div = 13;
+ return (rate / div);
+}
+
+static ulong ast2700_soc0_clk_get_rate(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case SCU0_CLK_PSP:
+ rate = ast2700_soc0_get_pspclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_HPLL:
+ rate = ast2700_soc0_get_hpll_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_DPLL:
+ case SCU0_CLK_MPLL:
+ rate = ast2700_soc0_get_pll_rate((struct ast2700_scu0 *)priv->reg, clk->id);
+ break;
+ case SCU0_CLK_AXI0:
+ rate = ast2700_soc0_get_axi0clk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_AXI1:
+ rate = ast2700_soc0_get_axi1clk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_AHB:
+ rate = ast2700_soc0_get_hclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_APB:
+ rate = ast2700_soc0_get_pclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_GATE_EMMCCLK:
+ rate = ast2700_soc0_get_emmcclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_GATE_UART4CLK:
+ rate = ast2700_soc0_get_uartclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_MPHY:
+ rate = ast2700_soc0_get_mphyclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ default:
+ debug("%s: unknown clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static int ast2700_soc0_clk_enable(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu0 *scu = (struct ast2700_scu0 *)priv->reg;
+ u32 clkgate_bit = BIT(clk->id);
+
+ writel(clkgate_bit, &scu->clkgate_clr);
+
+ return 0;
+}
+
+static const struct clk_ops ast2700_soc0_clk_ops = {
+ .get_rate = ast2700_soc0_clk_get_rate,
+ .enable = ast2700_soc0_clk_enable,
+};
+
+static void ast2700_init_mac_clk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ u8 div_idx;
+
+ /* The MAC source clock selects HPLL only, and the default clock
+ * setting is 200 Mhz.
+ * Calculate the corresponding divider:
+ * 1: div 2
+ * 2: div 3
+ * ...
+ * 7: div 8
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++)
+ if (DIV_ROUND_UP(src_clk, div_idx + 1) == 200000000)
+ break;
+
+ if (div_idx == 8) {
+ pr_err("MAC clock cannot divide to 200 MHz\n");
+ return;
+ }
+
+ /* set HPLL clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(31, 29);
+ reg_280 |= div_idx << 29;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static void ast2700_init_rgmii_clk(struct ast2700_scu1 *scu)
+{
+ u32 reg_284 = readl(&scu->clk_sel2);
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, RGMII_DEFAULT_CLK_SRC);
+
+ if (RGMII_DEFAULT_CLK_SRC == SCU1_CLK_HPLL) {
+ u32 reg_280;
+ u8 div_idx;
+
+ /* Calculate the corresponding divider:
+ * 1: div 4
+ * 2: div 6
+ * ...
+ * 7: div 16
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++) {
+ u8 div = 4 + 2 * (div_idx - 1);
+
+ if (DIV_ROUND_UP(src_clk, div) == 125000000)
+ break;
+ }
+ if (div_idx == 8) {
+ pr_err("RGMII using HPLL cannot divide to 125 MHz\n");
+ return;
+ }
+
+ /* set HPLL clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(27, 25);
+ reg_280 |= div_idx << 25;
+ writel(reg_280, &scu->clk_sel1);
+
+ /* select HPLL clock source */
+ reg_284 &= ~BIT(18);
+ } else {
+ /* APLL clock divider is fixed to 8 */
+ if (DIV_ROUND_UP(src_clk, 8) != 125000000) {
+ pr_err("RGMII using APLL cannot divide to 125 MHz\n");
+ return;
+ }
+
+ /* select APLL clock source */
+ reg_284 |= BIT(18);
+ }
+
+ writel(reg_284, &scu->clk_sel2);
+}
+
+static void ast2700_init_rmii_clk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ u8 div_idx;
+
+ /* The RMII source clock selects HPLL only.
+ * Calculate the corresponding divider:
+ * 1: div 8
+ * 2: div 12
+ * ...
+ * 7: div 32
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++) {
+ u8 div = 8 + 4 * (div_idx - 1);
+
+ if (DIV_ROUND_UP(src_clk, div) == 50000000)
+ break;
+ }
+ if (div_idx == 8) {
+ pr_err("RMII using HPLL cannot divide to 50 MHz\n");
+ return;
+ }
+
+ /* set RMII clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(23, 21);
+ reg_280 |= div_idx << 21;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static void ast2700_init_spi(struct ast2700_scu1 *scu)
+{
+ writel(readl(&scu->io_driving8) | 0x0000aaaa, &scu->io_driving8); /* fwspi driving */
+ writel(readl(&scu->io_driving3) | 0x00000aaa, &scu->io_driving3); /* spi0 driving */
+ writel(readl(&scu->io_driving3) | 0x0aaa0000, &scu->io_driving3); /* spi1 driving */
+ writel(readl(&scu->io_driving4) | 0x00002aaa, &scu->io_driving4); /* spi2 driving */
+}
+
+#define SCU1_CLK_I3C_DIV_MASK GENMASK(25, 23)
+#define SCU1_CLK_I3C_DIV(n) ((n) - 1)
+static void ast2700_init_i3c_clk(struct ast2700_scu1 *scu)
+{
+ u32 reg_284;
+
+ /* I3C 250MHz = HPLL/4 */
+ reg_284 = readl(&scu->clk_sel2);
+ reg_284 &= ~SCU1_CLK_I3C_DIV_MASK;
+ reg_284 |= FIELD_PREP(SCU1_CLK_I3C_DIV_MASK, SCU1_CLK_I3C_DIV(4));
+ writel(reg_284, &scu->clk_sel2);
+}
+
+static int ast2700_clk1_init(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+
+ ast2700_init_spi(scu);
+ ast2700_init_mac_clk(scu);
+ ast2700_init_rgmii_clk(scu);
+ ast2700_init_rmii_clk(scu);
+ ast2700_init_sdclk(scu);
+ ast2700_init_i3c_clk(scu);
+
+ return 0;
+}
+
+static int ast2700_clk0_init(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+ struct ast2700_scu0 *scu = (struct ast2700_scu0 *)priv->reg;
+
+ ast2700_emmc_init(scu);
+ ast2700_mphy_clk_init(scu);
+ ast2700_vga_clk_init(scu);
+
+ return 0;
+}
+
+static int ast2700_clk_probe(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+
+ priv->init = (ast2700_clk_init_fn)dev_get_driver_data(dev);
+ priv->reg = (void __iomem *)dev_read_addr_ptr(dev);
+
+ if (priv->init)
+ return priv->init(dev);
+
+ return 0;
+}
+
+static int ast2700_clk_bind(struct udevice *dev)
+{
+ struct udevice *sysreset_dev, *rst_dev;
+ int ret;
+
+ /* The system reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &sysreset_dev);
+ if (ret)
+ debug("Warning: No sysreset driver: ret = %d\n", ret);
+
+ /* Bind the per-SCU reset controller to the same ofnode so that
+ * <&syscon0/1 RESET_X> phandle references resolve to a UCLASS_RESET
+ * device. This pairs with the airoha-style binding pattern.
+ */
+ if (CONFIG_IS_ENABLED(RESET_AST2700)) {
+ ret = device_bind_driver_to_node(dev, "ast2700_reset", "reset",
+ dev_ofnode(dev), &rst_dev);
+ if (ret)
+ debug("Warning: failed to bind reset controller: ret = %d\n", ret);
+ }
+
+ return 0;
+}
+
+static const struct udevice_id ast2700_soc1_clk_ids[] = {
+ { .compatible = "aspeed,ast2700-scu1", .data = (ulong)&ast2700_clk1_init },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2700_soc1_clk) = {
+ .name = "aspeed_ast2700_scu1",
+ .id = UCLASS_CLK,
+ .of_match = ast2700_soc1_clk_ids,
+ .priv_auto = sizeof(struct ast2700_clk_priv),
+ .ops = &ast2700_soc1_clk_ops,
+ .probe = ast2700_clk_probe,
+ .bind = ast2700_clk_bind,
+};
+
+static const struct udevice_id ast2700_soc0_clk_ids[] = {
+ { .compatible = "aspeed,ast2700-scu0", .data = (ulong)&ast2700_clk0_init },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2700_soc0_clk) = {
+ .name = "aspeed_ast2700_scu0",
+ .id = UCLASS_CLK,
+ .of_match = ast2700_soc0_clk_ids,
+ .priv_auto = sizeof(struct ast2700_clk_priv),
+ .ops = &ast2700_soc0_clk_ops,
+ .probe = ast2700_clk_probe,
+ .bind = ast2700_clk_bind,
+};
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index 2251e2846fa..0d0e39db57e 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -426,7 +426,7 @@ static const struct pmc_clk_setup sam9x60_clk_setup[] = {
static int sam9x60_clk_probe(struct udevice *dev)
{
- void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[64], *muxallocs[64];
const char *p[10];
unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c
index 9ea253e6ff8..93f899b6617 100644
--- a/drivers/clk/at91/sam9x7.c
+++ b/drivers/clk/at91/sam9x7.c
@@ -817,7 +817,7 @@ static const struct {
static int sam9x7_clk_probe(struct udevice *dev)
{
- void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[64], *muxallocs[64];
const char *p[10];
unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c
index 9f0b394543b..0c17a8cf67b 100644
--- a/drivers/clk/at91/sama7d65.c
+++ b/drivers/clk/at91/sama7d65.c
@@ -1176,7 +1176,7 @@ static const struct pmc_clk_setup sama7d65_clk_setup[] = {
static int sama7d65_clk_probe(struct udevice *dev)
{
- void __iomem *base = (void *)devfdt_get_addr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[SAMA7D65_MAX_MUX_ALLOCS];
unsigned int *muxallocs[SAMA7D65_MAX_MUX_ALLOCS];
const char *p[12];
@@ -1185,8 +1185,8 @@ static int sama7d65_clk_probe(struct udevice *dev)
bool main_osc_bypass;
int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
- if (IS_ERR(base))
- return PTR_ERR(base);
+ if (!base)
+ return -EINVAL;
memset(muxallocs, 0, ARRAY_SIZE(muxallocs));
memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index f24d251857f..c436038aed2 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -1109,7 +1109,7 @@ static const struct pmc_clk_setup sama7g5_clk_setup[] = {
static int sama7g5_clk_probe(struct udevice *dev)
{
- void __iomem *base = devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[SAMA7G5_MAX_MUX_ALLOCS];
unsigned int *muxallocs[SAMA7G5_MAX_MUX_ALLOCS];
const char *p[10];
@@ -1118,8 +1118,8 @@ static int sama7g5_clk_probe(struct udevice *dev)
bool main_osc_bypass;
int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
- if (IS_ERR(base))
- return PTR_ERR(base);
+ if (!base)
+ return -EINVAL;
memset(muxallocs, 0, sizeof(muxallocs));
memset(clkmuxallocs, 0, sizeof(clkmuxallocs));
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index dcaffd360fd..410bc088248 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -124,12 +124,15 @@ U_BOOT_DRIVER(at91_sam9x60_td_slck) = {
static int at91_sam9x60_sckc_probe(struct udevice *dev)
{
struct sam9x60_sckc *sckc = dev_get_priv(dev);
- void __iomem *base = devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
const char *slow_rc_osc, *slow_osc;
const char *parents[2];
struct clk *clk, c;
int ret;
+ if (!base)
+ return -EINVAL;
+
ret = clk_get_by_index(dev, 0, &c);
if (ret)
return ret;
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index e692b9c2167..d30786a9e6c 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -228,20 +228,30 @@ static struct clk *_register_divider(struct udevice *dev, const char *name,
return clk;
}
-struct clk *clk_register_divider(struct udevice *dev, const char *name,
+struct clk *clk_register_divider_table(struct udevice *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
- u8 clk_divider_flags)
+ u8 clk_divider_flags, const struct clk_div_table *table)
{
struct clk *clk;
clk = _register_divider(dev, name, parent_name, flags, reg, shift,
- width, clk_divider_flags, NULL);
+ width, clk_divider_flags, table);
if (IS_ERR(clk))
return ERR_CAST(clk);
return clk;
}
+struct clk *clk_register_divider(struct udevice *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 shift, u8 width,
+ u8 clk_divider_flags)
+{
+ return clk_register_divider_table(dev, name, parent_name, flags, reg,
+ shift, width, clk_divider_flags,
+ NULL);
+}
+
U_BOOT_DRIVER(ccf_clk_divider) = {
.name = UBOOT_DM_CLK_CCF_DIVIDER,
.id = UCLASS_CLK,
diff --git a/drivers/clk/clk-hsdk-cgu.c b/drivers/clk/clk-hsdk-cgu.c
index 53655059279..dbc926a4391 100644
--- a/drivers/clk/clk-hsdk-cgu.c
+++ b/drivers/clk/clk-hsdk-cgu.c
@@ -753,11 +753,11 @@ static int hsdk_cgu_clk_probe(struct udevice *dev)
else
hsdk_clk->map = hsdk_4xd_clk_map;
- hsdk_clk->cgu_regs = devfdt_get_addr_index_ptr(dev, 0);
+ hsdk_clk->cgu_regs = dev_read_addr_index_ptr(dev, 0);
if (!hsdk_clk->cgu_regs)
return -EINVAL;
- hsdk_clk->creg_regs = devfdt_get_addr_index_ptr(dev, 1);
+ hsdk_clk->creg_regs = dev_read_addr_index_ptr(dev, 1);
if (!hsdk_clk->creg_regs)
return -EINVAL;
diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c
index 117266ac778..4a6c71016da 100644
--- a/drivers/clk/clk-stub.c
+++ b/drivers/clk/clk-stub.c
@@ -49,11 +49,13 @@ static struct clk_ops stub_clk_ops = {
};
static const struct udevice_id stub_clk_ids[] = {
+ { .compatible = "qcom,qcs615-rpmh-clk" },
{ .compatible = "qcom,rpmcc" },
- { .compatible = "qcom,sdm670-rpmh-clk" },
- { .compatible = "qcom,sdm845-rpmh-clk" },
+ { .compatible = "qcom,sa8775p-rpmh-clk" },
{ .compatible = "qcom,sc7180-rpmh-clk" },
{ .compatible = "qcom,sc7280-rpmh-clk" },
+ { .compatible = "qcom,sdm670-rpmh-clk" },
+ { .compatible = "qcom,sdm845-rpmh-clk" },
{ .compatible = "qcom,sm6350-rpmh-clk" },
{ .compatible = "qcom,sm8150-rpmh-clk" },
{ .compatible = "qcom,sm8250-rpmh-clk" },
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index f57ac79f8ca..846b8011f5c 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -9,6 +9,7 @@
#include <log.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
+#include <dm/of_access.h>
#include <dt-bindings/clock/imx6qdl-clock.h>
#include "clk.h"
@@ -46,6 +47,33 @@ static struct clk_ops imx6q_clk_ops = {
.disable = ccf_clk_disable,
};
+static const char *const pll_bypass_src_sels[] = {
+ "osc",
+ "lvds1_in",
+ "lvds2_in",
+ "dummy",
+};
+
+static const char *const pll2_bypass_sels[] = {
+ "pll2",
+ "pll2_bypass_src",
+};
+
+static const char *const pll3_bypass_sels[] = {
+ "pll3",
+ "pll3_bypass_src",
+};
+
+static const char *const pll5_bypass_sels[] = {
+ "pll5",
+ "pll5_bypass_src",
+};
+
+static const char *const pll6_bypass_sels[] = {
+ "pll6",
+ "pll6_bypass_src",
+};
+
static const char *const usdhc_sels[] = {
"pll2_pfd2_396m",
"pll2_pfd0_352m",
@@ -72,6 +100,23 @@ static const char *const ecspi_sels[] = {
"pll3_60m",
"osc",
};
+
+static const struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { /* sentinel */ }
+};
+
+static const struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { /* sentinel */ }
+};
+
+#if CONFIG_IS_ENABLED(VIDEO)
static const char *const ipu_sels[] = {
"mmdc_ch0_axi",
"pll2_pfd2_396m",
@@ -113,6 +158,122 @@ static const char *ipu2_di1_sels_2[] = {
static unsigned int share_count_mipi_core_cfg;
+static void of_assigned_ldb_sels(struct udevice *dev, int *ldb_di0_sel,
+ int *ldb_di1_sel)
+{
+ struct ofnode_phandle_args clk_args, parent_args;
+ ofnode node = dev_ofnode(dev);
+ int count, err;
+
+ count = dev_count_phandle_with_args(dev, "assigned-clocks",
+ "#clock-cells", 0);
+ if (count <= 0) {
+ if (count == 0)
+ debug("%s: no assigned_clocks found\n", dev->name);
+ else
+ pr_err("%s: failed to get phandle count (%d)\n",
+ dev->name, count);
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ err = dev_read_phandle_with_args(dev, "assigned-clocks",
+ "#clock-cells", 0, i,
+ &clk_args);
+ if (err == -ENOENT)
+ /* Skip empty handles */
+ continue;
+ else if (err < 0)
+ return;
+
+ if (!ofnode_equal(clk_args.node, node) ||
+ clk_args.args[0] >= IMX6QDL_CLK_END) {
+ pr_err("%s: clock %d not in ccm\n", dev->name, i);
+ return;
+ }
+
+ err = dev_read_phandle_with_args(dev, "assigned-clock-parents",
+ "#clock-cells", 0, i,
+ &parent_args);
+ if (err < 0)
+ return;
+
+ if (!ofnode_equal(parent_args.node, node) ||
+ parent_args.args[0] >= IMX6QDL_CLK_END) {
+ pr_err("%s: parent clock %d not in ccm\n", dev->name,
+ i);
+ return;
+ }
+
+ if (clk_args.args[0] == IMX6QDL_CLK_LDB_DI0_SEL)
+ *ldb_di0_sel = parent_args.args[0];
+ else if (clk_args.args[0] == IMX6QDL_CLK_LDB_DI1_SEL)
+ *ldb_di1_sel = parent_args.args[0];
+ }
+}
+
+static void imx6q_init_ldb_clks(struct udevice *dev)
+{
+ int ldb_di_sel[] = { IMX6QDL_CLK_END, IMX6QDL_CLK_END };
+ enum ldb_di_clock ldb_di_clk[] = { MXC_MMDC_CH1_CLK, MXC_MMDC_CH1_CLK };
+
+ of_assigned_ldb_sels(dev, &ldb_di_sel[0], &ldb_di_sel[1]);
+ for (int i = 0; i < 2; i++) {
+ switch (ldb_di_sel[i]) {
+ case IMX6QDL_CLK_PLL5_VIDEO_DIV:
+ ldb_di_clk[i] = MXC_PLL5_CLK;
+ break;
+ case IMX6QDL_CLK_PLL2_PFD0_352M:
+ ldb_di_clk[i] = MXC_PLL2_PFD0_CLK;
+ break;
+ case IMX6QDL_CLK_PLL2_PFD2_396M: {
+ struct clk *clk, *parent;
+
+ int err = clk_get_by_id(IMX6QDL_CLK_PERIPH_PRE, &clk);
+
+ if (err) {
+ pr_err("%s: failed to get periph_pre clock "
+ "(%d)\n",
+ dev->name, err);
+ return;
+ }
+
+ err = clk_get_by_id(IMX6QDL_CLK_PLL2_PFD2_396M,
+ &parent);
+ if (err) {
+ pr_err("%s: failed to get pll2_pfd2_396m clock"
+ " (%d)\n",
+ dev->name, err);
+ return;
+ }
+
+ if (parent == clk) {
+ pr_err("%s: ldb_di%d_sel: couldn't disable "
+ "pll2_pfd2_396m clock\n",
+ dev->name, i);
+ return;
+ }
+
+ ldb_di_clk[i] = MXC_PLL2_PFD2_CLK;
+ break;
+ }
+ case IMX6QDL_CLK_MMDC_CH1_AXI:
+ case IMX6QDL_CLK_END:
+ /* use the default clock */
+ break;
+ case IMX6QDL_CLK_PLL3_USB_OTG:
+ ldb_di_clk[i] = MXC_PLL3_SW_CLK;
+ break;
+ default:
+ pr_err("%s: invalid LDB clock parent\n", dev->name);
+ return;
+ }
+ }
+
+ select_ldb_di_clock_source(ldb_di_clk[0], ldb_di_clk[1]);
+}
+#endif /* CONFIG_IS_ENABLED(VIDEO) */
+
static int imx6q_clk_probe(struct udevice *dev)
{
void *base;
@@ -120,26 +281,70 @@ static int imx6q_clk_probe(struct udevice *dev)
/* Anatop clocks */
base = (void *)ANATOP_BASE_ADDR;
- clk_dm(IMX6QDL_CLK_PLL2,
- imx_clk_pllv3(dev, IMX_PLLV3_GENERIC, "pll2_bus", "osc",
- base + 0x30, 0x1));
+ clk_dm(IMX6QDL_PLL2_BYPASS_SRC,
+ imx_clk_mux(dev, "pll2_bypass_src", base + 0x30, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+ clk_dm(IMX6QDL_PLL3_BYPASS_SRC,
+ imx_clk_mux(dev, "pll3_bypass_src", base + 0x10, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+ clk_dm(IMX6QDL_PLL5_BYPASS_SRC,
+ imx_clk_mux(dev, "pll5_bypass_src", base + 0xa0, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+ clk_dm(IMX6QDL_PLL6_BYPASS_SRC,
+ imx_clk_mux(dev, "pll6_bypass_src", base + 0xe0, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+
+ clk_dm(IMX6QDL_CLK_PLL2, imx_clk_pllv3(dev, IMX_PLLV3_GENERIC, "pll2",
+ "osc", base + 0x30, 0x1));
+ clk_dm(IMX6QDL_CLK_PLL3, imx_clk_pllv3(dev, IMX_PLLV3_USB, "pll3",
+ "osc", base + 0x10, 0x3));
+ clk_dm(IMX6QDL_CLK_PLL5, imx_clk_pllv3(dev, IMX_PLLV3_AV, "pll5", "osc",
+ base + 0xa0, 0x7f));
+ clk_dm(IMX6QDL_CLK_PLL6, imx_clk_pllv3(dev, IMX_PLLV3_ENET, "pll6",
+ "osc", base + 0xe0, 0x3));
+
+ clk_dm(IMX6QDL_PLL2_BYPASS,
+ imx_clk_mux_flags(dev, "pll2_bypass", base + 0x30, 16, 1,
+ pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_PLL3_BYPASS,
+ imx_clk_mux_flags(dev, "pll3_bypass", base + 0x10, 16, 1,
+ pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_PLL5_BYPASS,
+ imx_clk_mux_flags(dev, "pll5_bypass", base + 0xa0, 16, 1,
+ pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_PLL6_BYPASS,
+ imx_clk_mux_flags(dev, "pll6_bypass", base + 0xe0, 16, 1,
+ pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels),
+ CLK_SET_RATE_PARENT));
+
+ SET_CLK_PARENT(IMX6QDL_PLL2_BYPASS, IMX6QDL_CLK_PLL2);
+ SET_CLK_PARENT(IMX6QDL_PLL3_BYPASS, IMX6QDL_CLK_PLL3);
+ SET_CLK_PARENT(IMX6QDL_PLL5_BYPASS, IMX6QDL_CLK_PLL5);
+ SET_CLK_PARENT(IMX6QDL_PLL6_BYPASS, IMX6QDL_CLK_PLL6);
+
+ clk_dm(IMX6QDL_CLK_PLL2_BUS,
+ imx_clk_gate(dev, "pll2_bus", "pll2_bypass", base + 0x30, 13));
clk_dm(IMX6QDL_CLK_PLL3_USB_OTG,
- imx_clk_pllv3(dev, IMX_PLLV3_USB, "pll3_usb_otg", "osc",
- base + 0x10, 0x3));
+ imx_clk_gate(dev, "pll3_usb_otg", "pll3_bypass", base + 0x10,
+ 13));
+ clk_dm(IMX6QDL_CLK_PLL5_VIDEO,
+ imx_clk_gate(dev, "pll5_video", "pll5_bypass", base + 0xa0, 13));
+ clk_dm(IMX6QDL_CLK_PLL6_ENET,
+ imx_clk_gate(dev, "pll6_enet", "pll6_bypass", base + 0xe0, 13));
+
clk_dm(IMX6QDL_CLK_PLL3_60M,
imx_clk_fixed_factor(dev, "pll3_60m", "pll3_usb_otg", 1, 8));
clk_dm(IMX6QDL_CLK_PLL3_80M,
imx_clk_fixed_factor(dev, "pll3_80m", "pll3_usb_otg", 1, 6));
clk_dm(IMX6QDL_CLK_PLL3_120M,
imx_clk_fixed_factor(dev, "pll3_120m", "pll3_usb_otg", 1, 4));
- clk_dm(IMX6QDL_CLK_PLL5, imx_clk_pllv3(dev, IMX_PLLV3_AV, "pll5", "osc",
- base + 0xa0, 0x7f));
- clk_dm(IMX6QDL_CLK_PLL5_VIDEO,
- imx_clk_gate(dev, "pll5_video", "pll5", base + 0xa0, 13));
- clk_dm(IMX6QDL_CLK_PLL6, imx_clk_pllv3(dev, IMX_PLLV3_ENET, "pll6",
- "osc", base + 0xe0, 0x3));
- clk_dm(IMX6QDL_CLK_PLL6_ENET,
- imx_clk_gate(dev, "pll6_enet", "pll6", base + 0xe0, 13));
clk_dm(IMX6QDL_CLK_PLL2_PFD0_352M,
imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0));
@@ -151,10 +356,14 @@ static int imx6q_clk_probe(struct udevice *dev)
clk_dm(IMX6QDL_CLK_PLL2_198M,
imx_clk_fixed_factor(dev, "pll2_198m", "pll2_pfd2_396m", 1, 2));
clk_dm(IMX6QDL_CLK_PLL5_POST_DIV,
- imx_clk_fixed_factor(dev, "pll5_post_div", "pll5_video", 1, 1));
+ clk_register_divider_table(dev, "pll5_post_div", "pll5_video",
+ CLK_SET_RATE_PARENT, base + 0xa0, 19,
+ 2, 0, post_div_table));
clk_dm(IMX6QDL_CLK_PLL5_VIDEO_DIV,
- imx_clk_fixed_factor(dev, "pll5_video_div", "pll5_post_div", 1,
- 1));
+ clk_register_divider_table(dev, "pll5_video_div",
+ "pll5_post_div", CLK_SET_RATE_PARENT,
+ base + 0x170, 30, 2, 0,
+ video_div_table));
clk_dm(IMX6QDL_CLK_VIDEO_27M,
imx_clk_fixed_factor(dev, "video_27m", "pll3_pfd1_540m", 1,
20));
@@ -263,6 +472,7 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "mmdc_ch1_axi", "mmdc_ch1_axi_podf",
base + 0x74, 22));
+#if CONFIG_IS_ENABLED(VIDEO)
clk_dm(IMX6QDL_CLK_IPU1_SEL,
imx_clk_mux(dev, "ipu1_sel", base + 0x3c, 9, 2, ipu_sels,
ARRAY_SIZE(ipu_sels)));
@@ -279,9 +489,12 @@ static int imx6q_clk_probe(struct udevice *dev)
ldb_di_sels, ARRAY_SIZE(ldb_di_sels)));
} else {
/*
- * Need to set these as read-only due to a hardware bug.
- * Keeping default mux values. Fixed on the i.MX6 QuadPlus
- */
+ * Need to set these as read-only due to a hardware bug.
+ * Keeping default mux values. Fixed on the i.MX6 QuadPlus
+ * Need to set the clocks now and make them read-only due to a
+ * hardware bug. Fixed on the i.MX6 QuadPlus
+ */
+ imx6q_init_ldb_clks(dev);
clk_dm(IMX6QDL_CLK_LDB_DI0_SEL,
imx_clk_mux_flags(dev, "ldb_di0_sel", base + 0x2c, 9, 3,
ldb_di_sels, ARRAY_SIZE(ldb_di_sels),
@@ -413,6 +626,7 @@ static int imx6q_clk_probe(struct udevice *dev)
ARRAY_SIZE(ipu2_di1_sels),
CLK_SET_RATE_PARENT));
}
+#endif /* CONFIG_IS_ENABLED(VIDEO) */
clk_dm(IMX6QDL_CLK_ECSPI1,
imx_clk_gate2(dev, "ecspi1", "ecspi_root", base + 0x6c, 0));
@@ -453,6 +667,8 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "enet", "ipg", base + 0x6c, 10));
clk_dm(IMX6QDL_CLK_ENET_REF,
imx_clk_fixed_factor(dev, "enet_ref", "pll6_enet", 1, 1));
+
+#if CONFIG_IS_ENABLED(VIDEO)
clk_dm(IMX6QDL_CLK_MIPI_CORE_CFG,
imx_clk_gate2_shared(dev, "mipi_core_cfg", "video_27m",
base + 0x74, 16,
@@ -480,6 +696,7 @@ static int imx6q_clk_probe(struct udevice *dev)
SET_CLK_PARENT(IMX6QDL_CLK_IPU1_SEL,
IMX6QDL_CLK_PLL3_PFD1_540M);
}
+#endif /* CONFIG_IS_ENABLED(VIDEO) */
return 0;
}
diff --git a/drivers/clk/owl/Kconfig b/drivers/clk/owl/Kconfig
index c6afef90034..5f3b8fe8ab4 100644
--- a/drivers/clk/owl/Kconfig
+++ b/drivers/clk/owl/Kconfig
@@ -1,8 +1,8 @@
config CLK_OWL
- bool "Actions Semi OWL clock drivers"
- depends on CLK && ARCH_OWL
- help
- Enable support for clock managemet unit present in Actions Semi
+ bool "Actions Semi OWL clock drivers"
+ depends on CLK && ARCH_OWL
+ help
+ Enable support for clock managemet unit present in Actions Semi
Owl series S900/S700 SoCs.
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0a2ce55aaa2..9ad233c83ac 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -111,6 +111,14 @@ config CLK_QCOM_SM6115
on the Snapdragon SM6115 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
+config CLK_QCOM_SM6125
+ bool "Qualcomm SM6125 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon SM6125 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
config CLK_QCOM_SM6350
bool "Qualcomm SM6350 GCC"
select CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index b96d61b603e..c0d95a6300e 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLK_QCOM_QCS615) += clock-qcs615.o
obj-$(CONFIG_CLK_QCOM_SA8775P) += clock-sa8775p.o
obj-$(CONFIG_CLK_QCOM_SC7280) += clock-sc7280.o
obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o
+obj-$(CONFIG_CLK_QCOM_SM6125) += clock-sm6125.o
obj-$(CONFIG_CLK_QCOM_SM6350) += clock-sm6350.o
obj-$(CONFIG_CLK_QCOM_SM7150) += clock-sm7150.o
obj-$(CONFIG_CLK_QCOM_SM8150) += clock-sm8150.o
diff --git a/drivers/clk/qcom/clock-qcm2290.c b/drivers/clk/qcom/clock-qcm2290.c
index 5a599085b50..c38ff1a1e4a 100644
--- a/drivers/clk/qcom/clock-qcm2290.c
+++ b/drivers/clk/qcom/clock-qcm2290.c
@@ -73,7 +73,7 @@ static const struct pll_vote_clk gpll6_clk = {
.status = 0x6000,
.status_bit = BIT(31),
.ena_vote = 0x79000,
- .vote_bit = BIT(7),
+ .vote_bit = BIT(6),
};
static const struct gate_clk qcm2290_clks[] = {
diff --git a/drivers/clk/qcom/clock-qcs615.c b/drivers/clk/qcom/clock-qcs615.c
index 2087fc38f63..7b3fe49de9c 100644
--- a/drivers/clk/qcom/clock-qcs615.c
+++ b/drivers/clk/qcom/clock-qcs615.c
@@ -19,6 +19,11 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf060
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77020
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x77048
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77060
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x7707c
+
#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
@@ -33,9 +38,37 @@
#define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26)
#define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27)
+/* UFS PHY AXI clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
+ F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
+ F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+/* UFS PHY ICE CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS PHY UNIPRO CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0, 8, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ { }
+};
+
static ulong qcs615_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
@@ -52,6 +85,24 @@ static ulong qcs615_set_rate(struct clk *clk, ulong rate)
5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return 19200000;
default:
return 0;
}
@@ -81,7 +132,17 @@ static const struct gate_clk qcs615_clks[] = {
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT),
GATE_CLK(GCC_DISP_HF_AXI_CLK, 0xb038, BIT(0)),
- GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0))
+ GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0)),
+ /* UFS clocks */
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770c0, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77014, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77040, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77044, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x77078, BIT(0)),
+ GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, BIT(0)),
};
static int qcs615_enable(struct clk *clk)
diff --git a/drivers/clk/qcom/clock-sa8775p.c b/drivers/clk/qcom/clock-sa8775p.c
index 4957abf6f58..7eec4aeae48 100644
--- a/drivers/clk/qcom/clock-sa8775p.c
+++ b/drivers/clk/qcom/clock-sa8775p.c
@@ -19,6 +19,11 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0x1b028
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0x1b06c
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x8302c
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x83074
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x830a8
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x8308c
+
#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
@@ -44,9 +49,35 @@
#define GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT BIT(25)
+/* UFS AXI clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS ICE CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS UNIPRO CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
@@ -63,6 +94,24 @@ static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return 19200000;
default:
return 0;
}
@@ -106,6 +155,20 @@ static const struct gate_clk sa8775p_clks[] = {
/* QUP Wrapper 3 clocks */
GATE_CLK(GCC_QUPV3_WRAP3_S0_CLK, 0x4b000, GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT),
+
+ /* UFS PHY clocks */
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x83018, 1),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x830d4, 1),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x83020, 1),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x83064, 1),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x83024, 1),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x83028, 1),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x830c0, 1),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x830a4, 1),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x8306c, 1),
+
+ /* EDP reference clock (used by UFS PHY) */
+ GATE_CLK(GCC_EDP_REF_CLKREF_EN, 0x97448, 1),
};
static int sa8775p_enable(struct clk *clk)
diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
index 01c8587ac39..91e3fcc27cb 100644
--- a/drivers/clk/qcom/clock-sc7280.c
+++ b/drivers/clk/qcom/clock-sc7280.c
@@ -23,6 +23,10 @@
#define PCIE_1_AUX_CLK_CMD_RCGR 0x8d058
#define PCIE1_PHY_RCHNG_CMD_RCGR 0x8d03c
#define PCIE_1_PIPE_CLK_PHY_MUX 0x8d054
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77024
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x7706c
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x770a0
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77084
static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
@@ -54,6 +58,33 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = {
{ }
};
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
static ulong sc7280_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
@@ -103,6 +134,26 @@ static ulong sc7280_set_rate(struct clk *clk, ulong rate)
case GCC_PCIE1_PHY_RCHNG_CLK:
clk_rcg_set_rate(priv->base, PCIE1_PHY_RCHNG_CMD_RCGR, 5, CFG_CLK_SRC_GPLL0_EVEN);
return 100000000;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_phy_aux_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
default:
return rate;
}
@@ -148,6 +199,7 @@ static const struct gate_clk sc7280_clks[] = {
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77064, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
diff --git a/drivers/clk/qcom/clock-sm6125.c b/drivers/clk/qcom/clock-sm6125.c
new file mode 100644
index 00000000000..1fd72d55e88
--- /dev/null
+++ b/drivers/clk/qcom/clock-sm6125.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm sm6125
+ *
+ * (C) Copyright 2026 Biswapriyo Nath <[email protected]>
+ *
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/bug.h>
+#include <dt-bindings/clock/qcom,gcc-sm6125.h>
+
+#include "clock-qcom.h"
+
+#define GCC_BASE 0x01400000
+
+#define QUPV3_WRAP0_S4_CMD_RCGR 0x1f608
+#define SDCC1_APPS_CLK_CMD_RCGR 0x38028
+#define SDCC2_APPS_CLK_CMD_RCGR 0x1e00c
+
+#define GCC_GPLL0_MODE 0x0
+#define GCC_GPLL3_MODE 0x3000
+#define GCC_GPLL4_MODE 0x4000
+#define GCC_GPLL5_MODE 0x5000
+#define GCC_GPLL6_MODE 0x6000
+#define GCC_GPLL7_MODE 0x7000
+#define GCC_GPLL8_MODE 0x8000
+#define GCC_GPLL9_MODE 0x9000
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+ F(7372800, CFG_CLK_SRC_GPLL0_AUX2, 1, 384, 15625),
+ F(14745600, CFG_CLK_SRC_GPLL0_AUX2, 1, 768, 15625),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(29491200, CFG_CLK_SRC_GPLL0_AUX2, 1, 1536, 15625),
+ F(32000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 75),
+ F(48000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 25),
+ F(64000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 16, 75),
+ F(75000000, CFG_CLK_SRC_GPLL0_AUX2, 4, 0, 0),
+ F(80000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 15),
+ F(96000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 25),
+ F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
+ F(102400000, CFG_CLK_SRC_GPLL0_AUX2, 1, 128, 375),
+ F(112000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 28, 75),
+ F(117964800, CFG_CLK_SRC_GPLL0_AUX2, 1, 6144, 15625),
+ F(120000000, CFG_CLK_SRC_GPLL0_AUX2, 2.5, 0, 0),
+ F(128000000, CFG_CLK_SRC_GPLL6, 3, 0, 0),
+ {}
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+ F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(25000000, CFG_CLK_SRC_GPLL0_AUX2, 12, 0, 0),
+ F(50000000, CFG_CLK_SRC_GPLL0_AUX2, 6, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
+ {}
+};
+
+static const struct pll_vote_clk gpll0_clk = {
+ .status = 0,
+ .status_bit = BIT(31),
+ .ena_vote = 0x79000,
+ .vote_bit = BIT(0),
+};
+
+static const struct gate_clk sm6125_clks[] = {
+ GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1a084, BIT(0)),
+ GATE_CLK(GCC_QUPV3_WRAP0_CORE_2X_CLK, 0x7900c, BIT(9)),
+ GATE_CLK(GCC_QUPV3_WRAP0_CORE_CLK, 0x7900c, BIT(8)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x7900c, BIT(10)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x7900c, BIT(11)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x7900c, BIT(12)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x7900c, BIT(13)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x7900c, BIT(14)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x7900c, BIT(15)),
+ GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x7900c, BIT(6)),
+ GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x7900c, BIT(7)),
+ GATE_CLK(GCC_SDCC1_AHB_CLK, 0x38008, BIT(0)),
+ GATE_CLK(GCC_SDCC1_APPS_CLK, 0x38004, BIT(0)),
+ GATE_CLK(GCC_SDCC1_ICE_CORE_CLK, 0x3800c, BIT(0)),
+ GATE_CLK(GCC_SDCC2_AHB_CLK, 0x1e008, BIT(0)),
+ GATE_CLK(GCC_SDCC2_APPS_CLK, 0x1e004, BIT(0)),
+ GATE_CLK(GCC_SYS_NOC_CPUSS_AHB_CLK, 0x79004, BIT(0)),
+ GATE_CLK(GCC_SYS_NOC_UFS_PHY_AXI_CLK, 0x45098, BIT(0)),
+ GATE_CLK(GCC_SYS_NOC_USB3_PRIM_AXI_CLK, 0x1a080, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x45014, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x45010, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x45044, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x45078, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x4501c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x45018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x45040, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x1a010, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1a018, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x1a014, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x80278, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1a054, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x1a058, BIT(0)),
+ GATE_CLK(GCC_AHB2PHY_USB_CLK, 0x1d008, BIT(0)),
+ GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, BIT(0)),
+};
+
+static ulong sm6125_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
+
+ debug("%s: clk %s rate %lu\n", __func__, sm6125_clks[clk->id].name,
+ rate);
+
+ switch (clk->id) {
+ case GCC_QUPV3_WRAP0_S4_CLK:
+ freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, QUPV3_WRAP0_S4_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src,
+ 16);
+ return 0;
+ case GCC_SDCC2_APPS_CLK:
+ clk_enable_gpll0(priv->base, &gpll0_clk);
+ freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
+ WARN(freq->src != CFG_CLK_SRC_GPLL0,
+ "SDCC2_APPS_CLK_SRC not set to GPLL0, requested rate %lu\n",
+ rate);
+ clk_rcg_set_rate_mnd(priv->base, SDCC2_APPS_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src,
+ 8);
+ return freq->freq;
+ case GCC_SDCC1_APPS_CLK:
+ /* The firmware turns this on for us and always sets it to this rate */
+ return 384000000;
+ default:
+ return rate;
+ }
+}
+
+static int sm6125_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (priv->data->num_clks < clk->id) {
+ debug("%s: unknown clk id %lu\n", __func__, clk->id);
+ return 0;
+ }
+
+ debug("%s: clk %s\n", __func__, sm6125_clks[clk->id].name);
+
+ switch (clk->id) {
+ case GCC_USB30_PRIM_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_CLKREF_CLK);
+ break;
+ }
+
+ return qcom_gate_clk_en(priv, clk->id);
+}
+
+static const struct qcom_reset_map sm6125_gcc_resets[] = {
+ [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 },
+ [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 },
+ [GCC_UFS_PHY_BCR] = { 0x45000 },
+ [GCC_USB30_PRIM_BCR] = { 0x1a000 },
+ [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 },
+ [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 },
+ [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 },
+ [GCC_CAMSS_MICRO_BCR] = { 0x560ac },
+};
+
+static const struct qcom_power_map sm6125_gdscs[] = {
+ [USB30_PRIM_GDSC] = { 0x1a004 },
+ [UFS_PHY_GDSC] = { 0x45004 },
+ [CAMSS_VFE0_GDSC] = { 0x54004 },
+ [CAMSS_VFE1_GDSC] = { 0x5403c },
+ [CAMSS_TOP_GDSC] = { 0x5607c },
+ [CAM_CPP_GDSC] = { 0x560bc },
+ [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = { 0x7d060 },
+ [HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC] = { 0x80074 },
+ [HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = { 0x80084 },
+ [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = { 0x80094 },
+};
+
+static const phys_addr_t sm6125_gpll_addrs[] = {
+ GCC_BASE + GCC_GPLL0_MODE, GCC_BASE + GCC_GPLL3_MODE,
+ GCC_BASE + GCC_GPLL4_MODE, GCC_BASE + GCC_GPLL5_MODE,
+ GCC_BASE + GCC_GPLL6_MODE, GCC_BASE + GCC_GPLL7_MODE,
+ GCC_BASE + GCC_GPLL8_MODE, GCC_BASE + GCC_GPLL9_MODE,
+};
+
+static const phys_addr_t sm6125_rcg_addrs[] = {
+ 0x0141a01c, // GCC_USB30_PRIM_MASTER_CMD_RCGR
+ 0x0141a034, // GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR
+ 0x0141a060, // GCC_USB3_PRIM_PHY_AUX_CMD_RCGR
+ 0x01438028, // GCC_SDCC1_APPS_CMD_RCGR
+ 0x0141e00c, // GCC_SDCC2_APPS_CMD_RCGR
+ 0x0141f148, // GCC_QUPV3_WRAP0_S0_CMD_RCGR
+ 0x0141f278, // GCC_QUPV3_WRAP0_S1_CMD_RCGR
+ 0x0141f3a8, // GCC_QUPV3_WRAP0_S2_CMD_RCGR
+ 0x0141f4d8, // GCC_QUPV3_WRAP0_S3_CMD_RCGR
+ 0x0141f608, // GCC_QUPV3_WRAP0_S4_CMD_RCGR
+ 0x0141f738, // GCC_QUPV3_WRAP0_S5_CMD_RCGR
+ 0x01445020, // GCC_UFS_PHY_AXI_CMD_RCGR
+ 0x01445048, // GCC_UFS_PHY_ICE_CORE_CMD_RCGR
+ 0x01445060, // GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR
+ 0x0144507c, // GCC_UFS_PHY_PHY_AUX_CMD_RCGR
+};
+
+static const char *const sm6125_rcg_names[] = {
+ "GCC_USB30_PRIM_MASTER_CMD_RCGR",
+ "GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR",
+ "GCC_USB3_PRIM_PHY_AUX_CMD_RCGR",
+ "GCC_SDCC1_APPS_CMD_RCGR",
+ "GCC_SDCC2_APPS_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S0_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S1_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S2_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S3_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S4_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S5_CMD_RCGR",
+ "GCC_UFS_PHY_AXI_CMD_RCGR",
+ "GCC_UFS_PHY_ICE_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_PHY_AUX_CMD_RCGR",
+};
+
+static struct msm_clk_data sm6125_gcc_data = {
+ .resets = sm6125_gcc_resets,
+ .num_resets = ARRAY_SIZE(sm6125_gcc_resets),
+ .clks = sm6125_clks,
+ .num_clks = ARRAY_SIZE(sm6125_clks),
+ .power_domains = sm6125_gdscs,
+ .num_power_domains = ARRAY_SIZE(sm6125_gdscs),
+
+ .enable = sm6125_enable,
+ .set_rate = sm6125_set_rate,
+
+ .dbg_pll_addrs = sm6125_gpll_addrs,
+ .num_plls = ARRAY_SIZE(sm6125_gpll_addrs),
+ .dbg_rcg_addrs = sm6125_rcg_addrs,
+ .num_rcgs = ARRAY_SIZE(sm6125_rcg_addrs),
+ .dbg_rcg_names = sm6125_rcg_names,
+};
+
+static const struct udevice_id gcc_sm6125_of_match[] = {
+ {
+ .compatible = "qcom,gcc-sm6125",
+ .data = (ulong)&sm6125_gcc_data,
+ },
+ {}
+};
+
+U_BOOT_DRIVER(gcc_sm6125) = {
+ .name = "gcc_sm6125",
+ .id = UCLASS_NOP,
+ .of_match = gcc_sm6125_of_match,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 72f99e9fa1b..1893b6c4181 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -61,11 +61,11 @@ config CLK_RCAR_GEN3
Enable this to support the clocks on Renesas R-Car Gen3 and Gen4 SoCs.
config CLK_R8A774A1
- bool "Renesas R8A774A1 clock driver"
+ bool "Renesas R8A774A1 clock driver"
def_bool y if R8A774A1
- depends on CLK_RCAR_GEN3
- help
- Enable this to support the clocks on Renesas R8A774A1 SoC.
+ depends on CLK_RCAR_GEN3
+ help
+ Enable this to support the clocks on Renesas R8A774A1 SoC.
config CLK_R8A774B1
bool "Renesas R8A774B1 clock driver"
diff --git a/drivers/clk/sophgo/clk-cv1800b.c b/drivers/clk/sophgo/clk-cv1800b.c
index d946ea57a46..248a69321fc 100644
--- a/drivers/clk/sophgo/clk-cv1800b.c
+++ b/drivers/clk/sophgo/clk-cv1800b.c
@@ -500,9 +500,12 @@ static int cv1800b_register_clk(struct udevice *dev)
{
struct clk osc;
ulong osc_rate;
- void *base = devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
int i, ret;
+ if (!base)
+ return -EINVAL;
+
ret = clk_get_by_index(dev, 0, &osc);
if (ret) {
pr_err("Failed to get clock\n");
diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c
index 842a0541bd6..046d5d1605a 100644
--- a/drivers/clk/sunxi/clk_sunxi.c
+++ b/drivers/clk/sunxi/clk_sunxi.c
@@ -64,7 +64,7 @@ static int sunxi_clk_disable(struct clk *clk)
return sunxi_set_gate(clk, false);
}
-struct clk_ops sunxi_clk_ops = {
+static const struct clk_ops sunxi_clk_ops = {
.enable = sunxi_clk_enable,
.disable = sunxi_clk_disable,
};
diff --git a/drivers/clk/ti/clk-ctrl.c b/drivers/clk/ti/clk-ctrl.c
index c5c97dc35c4..08f7410edce 100644
--- a/drivers/clk/ti/clk-ctrl.c
+++ b/drivers/clk/ti/clk-ctrl.c
@@ -8,7 +8,11 @@
#include <dm.h>
#include <dm/device_compat.h>
#include <clk-uclass.h>
-#include <asm/arch-am33xx/clock.h>
+#include <asm/ti-common/omap_clock.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+
+#define TRANSITION_TIMEOUT_US 10000
struct clk_ti_ctrl_offs {
fdt_addr_t start;
@@ -33,10 +37,37 @@ static int clk_ti_ctrl_check_offs(struct clk *clk, fdt_addr_t offs)
return -EFAULT;
}
+#define IDLEST_DISABLED (MODULE_CLKCTRL_IDLEST_DISABLED << MODULE_CLKCTRL_IDLEST_SHIFT)
+#define IDLEST_TRANSITION (MODULE_CLKCTRL_IDLEST_TRANSITIONING << MODULE_CLKCTRL_IDLEST_SHIFT)
+static int clk_ti_ctrl_disable_clock_module(u32 addr)
+{
+ int val;
+
+ clrsetbits_le32(addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+ MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
+ MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+ return readl_relaxed_poll_timeout(addr, val,
+ (val & MODULE_CLKCTRL_IDLEST_MASK) == IDLEST_DISABLED,
+ TRANSITION_TIMEOUT_US);
+}
+
+static int clk_ti_ctrl_enable_clock_module(u32 addr)
+{
+ int val;
+
+ clrsetbits_le32(addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+ MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+ MODULE_CLKCTRL_MODULEMODE_SHIFT);
+ return readl_relaxed_poll_timeout(addr, val,
+ ((val & MODULE_CLKCTRL_IDLEST_MASK) != IDLEST_DISABLED) &&
+ ((val & MODULE_CLKCTRL_IDLEST_MASK) != IDLEST_TRANSITION),
+ TRANSITION_TIMEOUT_US);
+}
+
static int clk_ti_ctrl_disable(struct clk *clk)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
- u32 *clk_modules[2] = { };
fdt_addr_t offs;
int err;
@@ -47,16 +78,13 @@ static int clk_ti_ctrl_disable(struct clk *clk)
return err;
}
- clk_modules[0] = (u32 *)(offs);
- dev_dbg(clk->dev, "disable module @ %p\n", clk_modules[0]);
- do_disable_clocks(NULL, clk_modules, 1);
- return 0;
+ dev_dbg(clk->dev, "disable module @ %x\n", offs);
+ return clk_ti_ctrl_disable_clock_module(offs);
}
static int clk_ti_ctrl_enable(struct clk *clk)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
- u32 *clk_modules[2] = { };
fdt_addr_t offs;
int err;
@@ -67,10 +95,8 @@ static int clk_ti_ctrl_enable(struct clk *clk)
return err;
}
- clk_modules[0] = (u32 *)(offs);
- dev_dbg(clk->dev, "enable module @ %p\n", clk_modules[0]);
- do_enable_clocks(NULL, clk_modules, 1);
- return 0;
+ dev_dbg(clk->dev, "enable module @ %x\n", offs);
+ return clk_ti_ctrl_enable_clock_module(offs);
}
static ulong clk_ti_ctrl_get_rate(struct clk *clk)