aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Kconfig1
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/aspeed/Makefile1
-rw-r--r--drivers/clk/aspeed/clk_ast2600.c1173
-rw-r--r--drivers/clk/clk_stm32f.c39
-rw-r--r--drivers/clk/clk_stm32h7.c70
-rw-r--r--drivers/clk/clk_stm32mp1.c147
-rw-r--r--drivers/clk/mediatek/Makefile1
-rw-r--r--drivers/clk/mediatek/clk-mt8183.c823
-rw-r--r--drivers/clk/meson/Makefile1
-rw-r--r--drivers/clk/meson/g12a-ao.c83
-rw-r--r--drivers/clk/microchip/Kconfig5
-rw-r--r--drivers/clk/microchip/Makefile1
-rw-r--r--drivers/clk/microchip/mpfs_clk.c123
-rw-r--r--drivers/clk/microchip/mpfs_clk.h44
-rw-r--r--drivers/clk/microchip/mpfs_clk_cfg.c152
-rw-r--r--drivers/clk/microchip/mpfs_clk_periph.c187
-rw-r--r--drivers/clk/ti/clk-am3-dpll.c2
-rw-r--r--drivers/clk/ti/clk-ctrl.c2
-rw-r--r--drivers/clk/ti/clk-divider.c2
-rw-r--r--drivers/clk/ti/clk-gate.c2
-rw-r--r--drivers/clk/ti/clk-mux.c2
22 files changed, 2730 insertions, 132 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index db06f276ec..4aeaa0cd58 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -165,6 +165,7 @@ source "drivers/clk/exynos/Kconfig"
source "drivers/clk/imx/Kconfig"
source "drivers/clk/kendryte/Kconfig"
source "drivers/clk/meson/Kconfig"
+source "drivers/clk/microchip/Kconfig"
source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/owl/Kconfig"
source "drivers/clk/renesas/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f8383e523d..645709b855 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
obj-$(CONFIG_CLK_K210) += kendryte/
obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
+obj-$(CONFIG_CLK_MPFS) += microchip/
obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
obj-$(CONFIG_CLK_OWL) += owl/
obj-$(CONFIG_CLK_RENESAS) += renesas/
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
index 81764b4391..84776e5265 100644
--- a/drivers/clk/aspeed/Makefile
+++ b/drivers/clk/aspeed/Makefile
@@ -4,3 +4,4 @@
#
obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
+obj-$(CONFIG_ASPEED_AST2600) += clk_ast2600.o
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
new file mode 100644
index 0000000000..f72d384047
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -0,0 +1,1173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <linux/delay.h>
+#include <asm/arch/scu_ast2600.h>
+#include <dt-bindings/clock/ast2600-clock.h>
+#include <dt-bindings/reset/ast2600-reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CLKIN_25M 25000000UL
+
+/* MAC Clock Delay settings */
+#define MAC12_DEF_DELAY_1G 0x0041b75d
+#define MAC12_DEF_DELAY_100M 0x00417410
+#define MAC12_DEF_DELAY_10M 0x00417410
+#define MAC34_DEF_DELAY_1G 0x0010438a
+#define MAC34_DEF_DELAY_100M 0x00104208
+#define MAC34_DEF_DELAY_10M 0x00104208
+
+/*
+ * 3-bit encode of CPU freqeucy
+ * Some code is duplicated
+ */
+enum ast2600_cpu_freq {
+ CPU_FREQ_1200M_1,
+ CPU_FREQ_1600M_1,
+ CPU_FREQ_1200M_2,
+ CPU_FREQ_1600M_2,
+ CPU_FREQ_800M_1,
+ CPU_FREQ_800M_2,
+ CPU_FREQ_800M_3,
+ CPU_FREQ_800M_4,
+};
+
+struct ast2600_clk_priv {
+ struct ast2600_scu *scu;
+};
+
+/*
+ * Clock divider/multiplier configuration struct.
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ *
+ * D-PLL and D2-PLL have extra divider (OD + 1), which is not
+ * yet needed and ignored by clock configurations.
+ */
+union ast2600_pll_reg {
+ uint32_t w;
+ struct {
+ unsigned int m : 13;
+ unsigned int n : 6;
+ unsigned int p : 4;
+ unsigned int off : 1;
+ unsigned int bypass : 1;
+ unsigned int reset : 1;
+ unsigned int reserved : 6;
+ } b;
+};
+
+struct ast2600_pll_cfg {
+ union ast2600_pll_reg reg;
+ unsigned int ext_reg;
+};
+
+struct ast2600_pll_desc {
+ uint32_t in;
+ uint32_t out;
+ struct ast2600_pll_cfg cfg;
+};
+
+static const struct ast2600_pll_desc ast2600_pll_lookup[] = {
+ {
+ .in = CLKIN_25M,
+ .out = 400000000,
+ .cfg.reg.b.m = 95,
+ .cfg.reg.b.n = 2,
+ .cfg.reg.b.p = 1,
+ .cfg.ext_reg = 0x31,
+ },
+ {
+ .in = CLKIN_25M,
+ .out = 200000000,
+ .cfg.reg.b.m = 127,
+ .cfg.reg.b.n = 0,
+ .cfg.reg.b.p = 15,
+ .cfg.ext_reg = 0x3f,
+ },
+ {
+ .in = CLKIN_25M,
+ .out = 334000000,
+ .cfg.reg.b.m = 667,
+ .cfg.reg.b.n = 4,
+ .cfg.reg.b.p = 9,
+ .cfg.ext_reg = 0x14d,
+ },
+ {
+ .in = CLKIN_25M,
+ .out = 1000000000,
+ .cfg.reg.b.m = 119,
+ .cfg.reg.b.n = 2,
+ .cfg.reg.b.p = 0,
+ .cfg.ext_reg = 0x3d,
+ },
+ {
+ .in = CLKIN_25M,
+ .out = 50000000,
+ .cfg.reg.b.m = 95,
+ .cfg.reg.b.n = 2,
+ .cfg.reg.b.p = 15,
+ .cfg.ext_reg = 0x31,
+ },
+};
+
+/* divisor tables */
+static uint32_t axi_ahb_div0_table[] = {
+ 3, 2, 3, 4,
+};
+
+static uint32_t axi_ahb_div1_table[] = {
+ 3, 4, 6, 8,
+};
+
+static uint32_t axi_ahb_default_table[] = {
+ 3, 4, 3, 4, 2, 2, 2, 2,
+};
+
+extern uint32_t ast2600_get_pll_rate(struct ast2600_scu *scu, int pll_idx)
+{
+ union ast2600_pll_reg pll_reg;
+ uint32_t hwstrap1;
+ uint32_t cpu_freq;
+ uint32_t mul = 1, div = 1;
+
+ switch (pll_idx) {
+ case ASPEED_CLK_APLL:
+ pll_reg.w = readl(&scu->apll);
+ break;
+ case ASPEED_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ case ASPEED_CLK_EPLL:
+ pll_reg.w = readl(&scu->epll);
+ break;
+ case ASPEED_CLK_HPLL:
+ pll_reg.w = readl(&scu->hpll);
+ break;
+ case ASPEED_CLK_MPLL:
+ pll_reg.w = readl(&scu->mpll);
+ break;
+ }
+
+ if (!pll_reg.b.bypass) {
+ /* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1)
+ * HPLL Numerator (M) = fix 0x5F when SCU500[10]=1
+ * Fixed 0xBF when SCU500[10]=0 and SCU500[8]=1
+ * SCU200[12:0] (default 0x8F) when SCU510[10]=0 and SCU510[8]=0
+ * HPLL Denumerator (N) = SCU200[18:13] (default 0x2)
+ * HPLL Divider (P) = SCU200[22:19] (default 0x0)
+ * HPLL Bandwidth Adj (NB) = fix 0x2F when SCU500[10]=1
+ * Fixed 0x5F when SCU500[10]=0 and SCU500[8]=1
+ * SCU204[11:0] (default 0x31) when SCU500[10]=0 and SCU500[8]=0
+ */
+ if (pll_idx == ASPEED_CLK_HPLL) {
+ hwstrap1 = readl(&scu->hwstrap1);
+ cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >>
+ SCU_HWSTRAP1_CPU_FREQ_SHIFT;
+
+ switch (cpu_freq) {
+ case CPU_FREQ_800M_1:
+ case CPU_FREQ_800M_2:
+ case CPU_FREQ_800M_3:
+ case CPU_FREQ_800M_4:
+ pll_reg.b.m = 0x5f;
+ break;
+ case CPU_FREQ_1600M_1:
+ case CPU_FREQ_1600M_2:
+ pll_reg.b.m = 0xbf;
+ break;
+ default:
+ pll_reg.b.m = 0x8f;
+ break;
+ }
+ }
+
+ mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1);
+ div = (pll_reg.b.p + 1);
+ }
+
+ return ((CLKIN_25M * mul) / div);
+}
+
+static uint32_t ast2600_get_hclk_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
+ uint32_t axi_div, ahb_div;
+ uint32_t hwstrap1 = readl(&scu->hwstrap1);
+ uint32_t cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >>
+ SCU_HWSTRAP1_CPU_FREQ_SHIFT;
+ uint32_t axi_ahb_ratio = (hwstrap1 & SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK) >>
+ SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT;
+
+ if (hwstrap1 & SCU_HWSTRAP1_CPU_AXI_CLK_RATIO) {
+ axi_ahb_div1_table[0] = axi_ahb_default_table[cpu_freq] * 2;
+ axi_div = 1;
+ ahb_div = axi_ahb_div1_table[axi_ahb_ratio];
+ } else {
+ axi_ahb_div0_table[0] = axi_ahb_default_table[cpu_freq];
+ axi_div = 2;
+ ahb_div = axi_ahb_div0_table[axi_ahb_ratio];
+ }
+
+ return (rate / axi_div / ahb_div);
+}
+
+static uint32_t ast2600_get_bclk_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
+ uint32_t clksrc1 = readl(&scu->clksrc1);
+ uint32_t bclk_div = (clksrc1 & SCU_CLKSRC1_BCLK_DIV_MASK) >>
+ SCU_CLKSRC1_BCLK_DIV_SHIFT;
+
+ return (rate / ((bclk_div + 1) * 4));
+}
+
+static uint32_t ast2600_get_pclk1_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
+ uint32_t clksrc1 = readl(&scu->clksrc1);
+ uint32_t pclk_div = (clksrc1 & SCU_CLKSRC1_PCLK_DIV_MASK) >>
+ SCU_CLKSRC1_PCLK_DIV_SHIFT;
+
+ return (rate / ((pclk_div + 1) * 4));
+}
+
+static uint32_t ast2600_get_pclk2_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_hclk_rate(scu);
+ uint32_t clksrc4 = readl(&scu->clksrc4);
+ uint32_t pclk_div = (clksrc4 & SCU_CLKSRC4_PCLK_DIV_MASK) >>
+ SCU_CLKSRC4_PCLK_DIV_SHIFT;
+
+ return (rate / ((pclk_div + 1) * 2));
+}
+
+static uint32_t ast2600_get_uxclk_in_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = 0;
+ uint32_t clksrc5 = readl(&scu->clksrc5);
+ uint32_t uxclk = (clksrc5 & SCU_CLKSRC5_UXCLK_MASK) >>
+ SCU_CLKSRC5_UXCLK_SHIFT;
+
+ switch (uxclk) {
+ case 0:
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2600_get_hclk_rate(scu);
+ break;
+ }
+
+ return rate;
+}
+
+static uint32_t ast2600_get_huxclk_in_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = 0;
+ uint32_t clksrc5 = readl(&scu->clksrc5);
+ uint32_t huxclk = (clksrc5 & SCU_CLKSRC5_HUXCLK_MASK) >>
+ SCU_CLKSRC5_HUXCLK_SHIFT;
+
+ switch (huxclk) {
+ case 0:
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2600_get_hclk_rate(scu);
+ break;
+ }
+
+ return rate;
+}
+
+static uint32_t ast2600_get_uart_uxclk_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_uxclk_in_rate(scu);
+ uint32_t uart_clkgen = readl(&scu->uart_clkgen);
+ uint32_t n = (uart_clkgen & SCU_UART_CLKGEN_N_MASK) >>
+ SCU_UART_CLKGEN_N_SHIFT;
+ uint32_t r = (uart_clkgen & SCU_UART_CLKGEN_R_MASK) >>
+ SCU_UART_CLKGEN_R_SHIFT;
+
+ return ((rate * r) / (n * 2));
+}
+
+static uint32_t ast2600_get_uart_huxclk_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_huxclk_in_rate(scu);
+ uint32_t huart_clkgen = readl(&scu->huart_clkgen);
+ uint32_t n = (huart_clkgen & SCU_HUART_CLKGEN_N_MASK) >>
+ SCU_HUART_CLKGEN_N_SHIFT;
+ uint32_t r = (huart_clkgen & SCU_HUART_CLKGEN_R_MASK) >>
+ SCU_HUART_CLKGEN_R_SHIFT;
+
+ return ((rate * r) / (n * 2));
+}
+
+static uint32_t ast2600_get_sdio_clk_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = 0;
+ uint32_t clksrc4 = readl(&scu->clksrc4);
+ uint32_t sdio_div = (clksrc4 & SCU_CLKSRC4_SDIO_DIV_MASK) >>
+ SCU_CLKSRC4_SDIO_DIV_SHIFT;
+
+ if (clksrc4 & SCU_CLKSRC4_SDIO)
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
+ else
+ rate = ast2600_get_hclk_rate(scu);
+
+ return (rate / ((sdio_div + 1) * 2));
+}
+
+static uint32_t ast2600_get_emmc_clk_rate(struct ast2600_scu *scu)
+{
+ uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
+ uint32_t clksrc1 = readl(&scu->clksrc1);
+ uint32_t emmc_div = (clksrc1 & SCU_CLKSRC1_EMMC_DIV_MASK) >>
+ SCU_CLKSRC1_EMMC_DIV_SHIFT;
+
+ return (rate / ((emmc_div + 1) * 4));
+}
+
+static uint32_t ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx)
+{
+ uint32_t rate = 0;
+ uint32_t uart5_clk = 0;
+ uint32_t clksrc2 = readl(&scu->clksrc2);
+ uint32_t clksrc4 = readl(&scu->clksrc4);
+ uint32_t clksrc5 = readl(&scu->clksrc5);
+ uint32_t misc_ctrl1 = readl(&scu->misc_ctrl1);
+
+ switch (uart_idx) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ if (clksrc4 & BIT(uart_idx - 1))
+ rate = ast2600_get_uart_huxclk_rate(scu);
+ else
+ rate = ast2600_get_uart_uxclk_rate(scu);
+ break;
+ case 5:
+ /*
+ * SCU0C[12] and SCU304[14] together decide
+ * the UART5 clock generation
+ */
+ if (misc_ctrl1 & SCU_MISC_CTRL1_UART5_DIV)
+ uart5_clk = 0x1 << 1;
+
+ if (clksrc2 & SCU_CLKSRC2_UART5)
+ uart5_clk |= 0x1;
+
+ switch (uart5_clk) {
+ case 0:
+ rate = 24000000;
+ break;
+ case 1:
+ rate = 192000000;
+ break;
+ case 2:
+ rate = 24000000 / 13;
+ break;
+ case 3:
+ rate = 192000000 / 13;
+ break;
+ }
+
+ break;
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ if (clksrc5 & BIT(uart_idx - 1))
+ rate = ast2600_get_uart_huxclk_rate(scu);
+ else
+ rate = ast2600_get_uart_uxclk_rate(scu);
+ break;
+ }
+
+ return rate;
+}
+
+static ulong ast2600_clk_get_rate(struct clk *clk)
+{
+ struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case ASPEED_CLK_HPLL:
+ case ASPEED_CLK_EPLL:
+ case ASPEED_CLK_DPLL:
+ case ASPEED_CLK_MPLL:
+ case ASPEED_CLK_APLL:
+ rate = ast2600_get_pll_rate(priv->scu, clk->id);
+ break;
+ case ASPEED_CLK_AHB:
+ rate = ast2600_get_hclk_rate(priv->scu);
+ break;
+ case ASPEED_CLK_APB1:
+ rate = ast2600_get_pclk1_rate(priv->scu);
+ break;
+ case ASPEED_CLK_APB2:
+ rate = ast2600_get_pclk2_rate(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_UART1CLK:
+ rate = ast2600_get_uart_clk_rate(priv->scu, 1);
+ break;
+ case ASPEED_CLK_GATE_UART2CLK:
+ rate = ast2600_get_uart_clk_rate(priv->scu, 2);
+ break;
+ case ASPEED_CLK_GATE_UART3CLK:
+ rate = ast2600_get_uart_clk_rate(priv->scu, 3);
+ break;
+ case ASPEED_CLK_GATE_UART4CLK:
+ rate = ast2600_get_uart_clk_rate(priv->scu, 4);
+ break;
+ case ASPEED_CLK_GATE_UART5CLK:
+ rate = ast2600_get_uart_clk_rate(priv->scu, 5);
+ break;
+ case ASPEED_CLK_BCLK:
+ rate = ast2600_get_bclk_rate(priv->scu);
+ break;
+ case ASPEED_CLK_SDIO:
+ rate = ast2600_get_sdio_clk_rate(priv->scu);
+ break;
+ case ASPEED_CLK_EMMC:
+ rate = ast2600_get_emmc_clk_rate(priv->scu);
+ break;
+ case ASPEED_CLK_UARTX:
+ rate = ast2600_get_uart_uxclk_rate(priv->scu);
+ break;
+ case ASPEED_CLK_HUARTX:
+ rate = ast2600_get_uart_huxclk_rate(priv->scu);
+ break;
+ default:
+ debug("can't get clk rate\n");
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+/**
+ * @brief lookup PLL divider config by input/output rate
+ * @param[in] *pll - PLL descriptor
+ * @return true - if PLL divider config is found, false - else
+ * The function caller shall fill "pll->in" and "pll->out",
+ * then this function will search the lookup table
+ * to find a valid PLL divider configuration.
+ */
+static bool ast2600_search_clock_config(struct ast2600_pll_desc *pll)
+{
+ uint32_t i;
+ const struct ast2600_pll_desc *def_desc;
+ bool is_found = false;
+
+ for (i = 0; i < ARRAY_SIZE(ast2600_pll_lookup); i++) {
+ def_desc = &ast2600_pll_lookup[i];
+
+ if (def_desc->in == pll->in && def_desc->out == pll->out) {
+ is_found = true;
+ pll->cfg.reg.w = def_desc->cfg.reg.w;
+ pll->cfg.ext_reg = def_desc->cfg.ext_reg;
+ break;
+ }
+ }
+ return is_found;
+}
+
+static uint32_t ast2600_configure_pll(struct ast2600_scu *scu,
+ struct ast2600_pll_cfg *p_cfg, int pll_idx)
+{
+ uint32_t addr, addr_ext;
+ uint32_t reg;
+
+ switch (pll_idx) {
+ case ASPEED_CLK_HPLL:
+ addr = (uint32_t)(&scu->hpll);
+ addr_ext = (uint32_t)(&scu->hpll_ext);
+ break;
+ case ASPEED_CLK_MPLL:
+ addr = (uint32_t)(&scu->mpll);
+ addr_ext = (uint32_t)(&scu->mpll_ext);
+ break;
+ case ASPEED_CLK_DPLL:
+ addr = (uint32_t)(&scu->dpll);
+ addr_ext = (uint32_t)(&scu->dpll_ext);
+ break;
+ case ASPEED_CLK_EPLL:
+ addr = (uint32_t)(&scu->epll);
+ addr_ext = (uint32_t)(&scu->epll_ext);
+ break;
+ case ASPEED_CLK_APLL:
+ addr = (uint32_t)(&scu->apll);
+ addr_ext = (uint32_t)(&scu->apll_ext);
+ break;
+ default:
+ debug("unknown PLL index\n");
+ return 1;
+ }
+
+ p_cfg->reg.b.bypass = 0;
+ p_cfg->reg.b.off = 1;
+ p_cfg->reg.b.reset = 1;
+
+ reg = readl(addr);
+ reg &= ~GENMASK(25, 0);
+ reg |= p_cfg->reg.w;
+ writel(reg, addr);
+
+ /* write extend parameter */
+ writel(p_cfg->ext_reg, addr_ext);
+ udelay(100);
+ p_cfg->reg.b.off = 0;
+ p_cfg->reg.b.reset = 0;
+ reg &= ~GENMASK(25, 0);
+ reg |= p_cfg->reg.w;
+ writel(reg, addr);
+ while (!(readl(addr_ext) & BIT(31)))
+ ;
+
+ return 0;
+}
+
+static uint32_t ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate)
+{
+ struct ast2600_pll_desc mpll;
+
+ mpll.in = CLKIN_25M;
+ mpll.out = rate;
+ if (ast2600_search_clock_config(&mpll) == false) {
+ printf("error!! unable to find valid DDR clock setting\n");
+ return 0;
+ }
+ ast2600_configure_pll(scu, &mpll.cfg, ASPEED_CLK_MPLL);
+
+ return ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL);
+}
+
+static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate;
+
+ switch (clk->id) {
+ case ASPEED_CLK_MPLL:
+ new_rate = ast2600_configure_ddr(priv->scu, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static uint32_t ast2600_configure_mac12_clk(struct ast2600_scu *scu)
+{
+ /* scu340[25:0]: 1G default delay */
+ clrsetbits_le32(&scu->mac12_clk_delay, GENMASK(25, 0),
+ MAC12_DEF_DELAY_1G);
+
+ /* set 100M/10M default delay */
+ writel(MAC12_DEF_DELAY_100M, &scu->mac12_clk_delay_100M);
+ writel(MAC12_DEF_DELAY_10M, &scu->mac12_clk_delay_10M);
+
+ /* MAC AHB = HPLL / 6 */
+ clrsetbits_le32(&scu->clksrc1, SCU_CLKSRC1_MAC_DIV_MASK,
+ (0x2 << SCU_CLKSRC1_MAC_DIV_SHIFT));
+
+ return 0;
+}
+
+static uint32_t ast2600_configure_mac34_clk(struct ast2600_scu *scu)
+{
+ /*
+ * scu350[31] RGMII 125M source: 0 = from IO pin
+ * scu350[25:0] MAC 1G delay
+ */
+ clrsetbits_le32(&scu->mac34_clk_delay, (BIT(31) | GENMASK(25, 0)),
+ MAC34_DEF_DELAY_1G);
+ writel(MAC34_DEF_DELAY_100M, &scu->mac34_clk_delay_100M);
+ writel(MAC34_DEF_DELAY_10M, &scu->mac34_clk_delay_10M);
+
+ /*
+ * clock source seletion and divider
+ * scu310[26:24] : MAC AHB bus clock = HCLK / 2
+ * scu310[18:16] : RMII 50M = HCLK_200M / 4
+ */
+ clrsetbits_le32(&scu->clksrc4,
+ (SCU_CLKSRC4_MAC_DIV_MASK | SCU_CLKSRC4_RMII34_DIV_MASK),
+ ((0x0 << SCU_CLKSRC4_MAC_DIV_SHIFT)
+ | (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT)));
+
+ /*
+ * set driving strength
+ * scu458[3:2] : MAC4 driving strength
+ * scu458[1:0] : MAC3 driving strength
+ */
+ clrsetbits_le32(&scu->pinmux16,
+ SCU_PINCTRL16_MAC4_DRIVING_MASK | SCU_PINCTRL16_MAC3_DRIVING_MASK,
+ (0x3 << SCU_PINCTRL16_MAC4_DRIVING_SHIFT)
+ | (0x3 << SCU_PINCTRL16_MAC3_DRIVING_SHIFT));
+
+ return 0;
+}
+
+/**
+ * ast2600 RGMII clock source tree
+ * 125M from external PAD -------->|\
+ * HPLL -->|\ | |---->RGMII 125M for MAC#1 & MAC#2
+ * | |---->| divider |---->|/ +
+ * EPLL -->|/ |
+ * |
+ * +---------<-----------|RGMIICK PAD output enable|<-------------+
+ * |
+ * +--------------------------->|\
+ * | |----> RGMII 125M for MAC#3 & MAC#4
+ * HCLK 200M ---->|divider|---->|/
+ * To simplify the control flow:
+ * 1. RGMII 1/2 always use EPLL as the internal clock source
+ * 2. RGMII 3/4 always use RGMIICK pad as the RGMII 125M source
+ * 125M from external PAD -------->|\
+ * | |---->RGMII 125M for MAC#1 & MAC#2
+ * EPLL---->| divider |--->|/ +
+ * |
+ * +<--------------------|RGMIICK PAD output enable|<-------------+
+ * |
+ * +--------------------------->RGMII 125M for MAC#3 & MAC#4
+ */
+#define RGMIICK_SRC_PAD 0
+#define RGMIICK_SRC_EPLL 1 /* recommended */
+#define RGMIICK_SRC_HPLL 2
+
+#define RGMIICK_DIV2 1
+#define RGMIICK_DIV3 2
+#define RGMIICK_DIV4 3
+#define RGMIICK_DIV5 4
+#define RGMIICK_DIV6 5
+#define RGMIICK_DIV7 6
+#define RGMIICK_DIV8 7 /* recommended */
+
+#define RMIICK_DIV4 0
+#define RMIICK_DIV8 1
+#define RMIICK_DIV12 2
+#define RMIICK_DIV16 3
+#define RMIICK_DIV20 4 /* recommended */
+#define RMIICK_DIV24 5
+#define RMIICK_DIV28 6
+#define RMIICK_DIV32 7
+
+struct ast2600_mac_clk_div {
+ uint32_t src; /* 0=external PAD, 1=internal PLL */
+ uint32_t fin; /* divider input speed */
+ uint32_t n; /* 0=div2, 1=div2, 2=div3, 3=div4,...,7=div8 */
+ uint32_t fout; /* fout = fin / n */
+};
+
+struct ast2600_mac_clk_div rgmii_clk_defconfig = {
+ .src = ASPEED_CLK_EPLL,
+ .fin = 1000000000,
+ .n = RGMIICK_DIV8,
+ .fout = 125000000,
+};
+
+struct ast2600_mac_clk_div rmii_clk_defconfig = {
+ .src = ASPEED_CLK_EPLL,
+ .fin = 1000000000,
+ .n = RMIICK_DIV20,
+ .fout = 50000000,
+};
+
+static void ast2600_init_mac_pll(struct ast2600_scu *p_scu,
+ struct ast2600_mac_clk_div *p_cfg)
+{
+ struct ast2600_pll_desc pll;
+
+ pll.in = CLKIN_25M;
+ pll.out = p_cfg->fin;
+ if (ast2600_search_clock_config(&pll) == false) {
+ pr_err("unable to find valid ETHNET MAC clock setting\n");
+ return;
+ }
+ ast2600_configure_pll(p_scu, &pll.cfg, p_cfg->src);
+}
+
+static void ast2600_init_rgmii_clk(struct ast2600_scu *p_scu,
+ struct ast2600_mac_clk_div *p_cfg)
+{
+ uint32_t reg_304 = readl(&p_scu->clksrc2);
+ uint32_t reg_340 = readl(&p_scu->mac12_clk_delay);
+ uint32_t reg_350 = readl(&p_scu->mac34_clk_delay);
+
+ reg_340 &= ~GENMASK(31, 29);
+ /* scu340[28]: RGMIICK PAD output enable (to MAC 3/4) */
+ reg_340 |= BIT(28);
+ if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) {
+ /*
+ * re-init PLL if the current PLL output frequency doesn't match
+ * the divider setting
+ */
+ if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src))
+ ast2600_init_mac_pll(p_scu, p_cfg);
+ /* scu340[31]: select RGMII 125M from internal source */
+ reg_340 |= BIT(31);
+ }
+
+ reg_304 &= ~GENMASK(23, 20);
+
+ /* set clock divider */
+ reg_304 |= (p_cfg->n & 0x7) << 20;
+
+ /* select internal clock source */
+ if (p_cfg->src == ASPEED_CLK_HPLL)
+ reg_304 |= BIT(23);
+
+ /* RGMII 3/4 clock source select */
+ reg_350 &= ~BIT(31);
+
+ writel(reg_304, &p_scu->clksrc2);
+ writel(reg_340, &p_scu->mac12_clk_delay);
+ writel(reg_350, &p_scu->mac34_clk_delay);
+}
+
+/**
+ * ast2600 RMII/NCSI clock source tree
+ * HPLL -->|\
+ * | |---->| divider |----> RMII 50M for MAC#1 & MAC#2
+ * EPLL -->|/
+ * HCLK(SCLICLK)---->| divider |----> RMII 50M for MAC#3 & MAC#4
+ */
+static void ast2600_init_rmii_clk(struct ast2600_scu *p_scu,
+ struct ast2600_mac_clk_div *p_cfg)
+{
+ uint32_t clksrc2 = readl(&p_scu->clksrc2);
+ uint32_t clksrc4 = readl(&p_scu->clksrc4);
+
+ if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) {
+ /*
+ * re-init PLL if the current PLL output frequency doesn't match
+ * the divider setting
+ */
+ if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src))
+ ast2600_init_mac_pll(p_scu, p_cfg);
+ }
+
+ clksrc2 &= ~(SCU_CLKSRC2_RMII12 | SCU_CLKSRC2_RMII12_DIV_MASK);
+
+ /* set RMII 1/2 clock divider */
+ clksrc2 |= (p_cfg->n & 0x7) << 16;
+
+ /* RMII clock source selection */
+ if (p_cfg->src == ASPEED_CLK_HPLL)
+ clksrc2 |= SCU_CLKSRC2_RMII12;
+
+ /* set RMII 3/4 clock divider */
+ clksrc4 &= ~SCU_CLKSRC4_RMII34_DIV_MASK;
+ clksrc4 |= (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT);
+
+ writel(clksrc2, &p_scu->clksrc2);
+ writel(clksrc4, &p_scu->clksrc4);
+}
+
+static uint32_t ast2600_configure_mac(struct ast2600_scu *scu, int index)
+{
+ uint32_t reset_bit;
+ uint32_t clkgate_bit;
+
+ switch (index) {
+ case 1:
+ reset_bit = BIT(ASPEED_RESET_MAC1);
+ clkgate_bit = SCU_CLKGATE1_MAC1;
+ writel(reset_bit, &scu->modrst_ctrl1);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr1);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr1);
+ break;
+ case 2:
+ reset_bit = BIT(ASPEED_RESET_MAC2);
+ clkgate_bit = SCU_CLKGATE1_MAC2;
+ writel(reset_bit, &scu->modrst_ctrl1);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr1);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr1);
+ break;
+ case 3:
+ reset_bit = BIT(ASPEED_RESET_MAC3 - 32);
+ clkgate_bit = SCU_CLKGATE2_MAC3;
+ writel(reset_bit, &scu->modrst_ctrl2);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr2);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr2);
+ break;
+ case 4:
+ reset_bit = BIT(ASPEED_RESET_MAC4 - 32);
+ clkgate_bit = SCU_CLKGATE2_MAC4;
+ writel(reset_bit, &scu->modrst_ctrl2);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr2);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr2);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void ast2600_configure_rsa_ecc_clk(struct ast2600_scu *scu)
+{
+ uint32_t clksrc1 = readl(&scu->clksrc1);
+
+ /* Configure RSA clock = HPLL/3 */
+ clksrc1 |= SCU_CLKSRC1_ECC_RSA;
+ clksrc1 &= ~SCU_CLKSRC1_ECC_RSA_DIV_MASK;
+ clksrc1 |= (2 << SCU_CLKSRC1_ECC_RSA_DIV_SHIFT);
+
+ writel(clksrc1, &scu->clksrc1);
+}
+
+static ulong ast2600_enable_sdclk(struct ast2600_scu *scu)
+{
+ uint32_t reset_bit;
+ uint32_t clkgate_bit;
+
+ reset_bit = BIT(ASPEED_RESET_SD - 32);
+ clkgate_bit = SCU_CLKGATE2_SDIO;
+
+ writel(reset_bit, &scu->modrst_ctrl2);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr2);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr2);
+
+ return 0;
+}
+
+static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu)
+{
+ int i = 0;
+ uint32_t div = 0;
+ uint32_t rate = 0;
+ uint32_t clksrc4 = readl(&scu->clksrc4);
+
+ /*
+ * ast2600 SD controller max clk is 200Mhz
+ * use apll for clock source 800/4 = 200
+ * controller max is 200mhz
+ */
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
+ for (i = 0; i < 8; i++) {
+ div = (i + 1) * 2;
+ if ((rate / div) <= 200000000)
+ break;
+ }
+ clksrc4 &= ~SCU_CLKSRC4_SDIO_DIV_MASK;
+ clksrc4 |= (i << SCU_CLKSRC4_SDIO_DIV_SHIFT);
+ clksrc4 |= SCU_CLKSRC4_SDIO;
+ writel(clksrc4, &scu->clksrc4);
+
+ setbits_le32(&scu->clksrc4, SCU_CLKSRC4_SDIO_EN);
+
+ return 0;
+}
+
+static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu)
+{
+ uint32_t reset_bit;
+ uint32_t clkgate_bit;
+
+ reset_bit = BIT(ASPEED_RESET_EMMC);
+ clkgate_bit = SCU_CLKGATE1_EMMC;
+
+ writel(reset_bit, &scu->modrst_ctrl1);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr1);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr1);
+
+ return 0;
+}
+
+static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu)
+{
+ int i = 0;
+ uint32_t div = 0;
+ uint32_t rate = 0;
+ uint32_t clksrc1 = readl(&scu->clksrc1);
+
+ /*
+ * ast2600 eMMC controller max clk is 200Mhz
+ * HPll->1/2->|\
+ * |->SCU300[11]->SCU300[14:12][1/N] +
+ * MPLL------>|/ |
+ * +----------------------------------------------+
+ * |
+ * +---------> EMMC12C[15:8][1/N]-> eMMC clk
+ */
+ rate = ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL);
+ for (i = 0; i < 8; i++) {
+ div = (i + 1) * 2;
+ if ((rate / div) <= 200000000)
+ break;
+ }
+
+ clksrc1 &= ~SCU_CLKSRC1_EMMC_DIV_MASK;
+ clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT);
+ clksrc1 |= SCU_CLKSRC1_EMMC;
+ writel(clksrc1, &scu->clksrc1);
+
+ setbits_le32(&scu->clksrc1, SCU_CLKSRC1_EMMC_EN);
+
+ return 0;
+}
+
+static ulong ast2600_enable_fsiclk(struct ast2600_scu *scu)
+{
+ uint32_t reset_bit;
+ uint32_t clkgate_bit;
+
+ reset_bit = BIT(ASPEED_RESET_FSI % 32);
+ clkgate_bit = SCU_CLKGATE2_FSI;
+
+ /* The FSI clock is shared between masters. If it's already on
+ * don't touch it, as that will reset the existing master.
+ */
+ if (!(readl(&scu->clkgate_ctrl2) & clkgate_bit)) {
+ debug("%s: already running, not touching it\n", __func__);
+ return 0;
+ }
+
+ writel(reset_bit, &scu->modrst_ctrl2);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr2);
+ mdelay(10);
+ writel(reset_bit, &scu->modrst_clr2);
+
+ return 0;
+}
+
+static ulong ast2600_enable_usbahclk(struct ast2600_scu *scu)
+{
+ uint32_t reset_bit;
+ uint32_t clkgate_bit;
+
+ reset_bit = BIT(ASPEED_RESET_EHCI_P1);
+ clkgate_bit = SCU_CLKGATE1_USB_HUB;
+
+ writel(reset_bit, &scu->modrst_ctrl1);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_ctrl1);
+ mdelay(20);
+ writel(reset_bit, &scu->modrst_clr1);
+
+ return 0;
+}
+
+static ulong ast2600_enable_usbbhclk(struct ast2600_scu *scu)
+{
+ uint32_t reset_bit;
+ uint32_t clkgate_bit;
+
+ reset_bit = BIT(ASPEED_RESET_EHCI_P2);
+ clkgate_bit = SCU_CLKGATE1_USB_HOST2;
+
+ writel(reset_bit, &scu->modrst_ctrl1);
+ udelay(100);
+ writel(clkgate_bit, &scu->clkgate_clr1);
+ mdelay(20);
+ writel(reset_bit, &scu->modrst_clr1);
+
+ return 0;
+}
+
+static int ast2600_clk_enable(struct clk *clk)
+{
+ struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case ASPEED_CLK_GATE_MAC1CLK:
+ ast2600_configure_mac(priv->scu, 1);
+ break;
+ case ASPEED_CLK_GATE_MAC2CLK:
+ ast2600_configure_mac(priv->scu, 2);
+ break;
+ case ASPEED_CLK_GATE_MAC3CLK:
+ ast2600_configure_mac(priv->scu, 3);
+ break;
+ case ASPEED_CLK_GATE_MAC4CLK:
+ ast2600_configure_mac(priv->scu, 4);
+ break;
+ case ASPEED_CLK_GATE_SDCLK:
+ ast2600_enable_sdclk(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_SDEXTCLK:
+ ast2600_enable_extsdclk(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_EMMCCLK:
+ ast2600_enable_emmcclk(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_EMMCEXTCLK:
+ ast2600_enable_extemmcclk(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_FSICLK:
+ ast2600_enable_fsiclk(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_USBPORT1CLK:
+ ast2600_enable_usbahclk(priv->scu);
+ break;
+ case ASPEED_CLK_GATE_USBPORT2CLK:
+ ast2600_enable_usbbhclk(priv->scu);
+ break;
+ default:
+ pr_err("can't enable clk\n");
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+struct clk_ops ast2600_clk_ops = {
+ .get_rate = ast2600_clk_get_rate,
+ .set_rate = ast2600_clk_set_rate,
+ .enable = ast2600_clk_enable,
+};
+
+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);
+
+ ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
+ ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
+ ast2600_configure_mac12_clk(priv->scu);
+ ast2600_configure_mac34_clk(priv->scu);
+ ast2600_configure_rsa_ecc_clk(priv->scu);
+
+ return 0;
+}
+
+static int ast2600_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
+ if (ret)
+ debug("Warning: No reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+struct aspeed_clks {
+ ulong id;
+ const char *name;
+};
+
+static struct aspeed_clks aspeed_clk_names[] = {
+ { ASPEED_CLK_HPLL, "hpll" },
+ { ASPEED_CLK_MPLL, "mpll" },
+ { ASPEED_CLK_APLL, "apll" },
+ { ASPEED_CLK_EPLL, "epll" },
+ { ASPEED_CLK_DPLL, "dpll" },
+ { ASPEED_CLK_AHB, "hclk" },
+ { ASPEED_CLK_APB1, "pclk1" },
+ { ASPEED_CLK_APB2, "pclk2" },
+ { ASPEED_CLK_BCLK, "bclk" },
+ { ASPEED_CLK_UARTX, "uxclk" },
+ { ASPEED_CLK_HUARTX, "huxclk" },
+};
+
+int soc_clk_dump(void)
+{
+ struct udevice *dev;
+ struct clk clk;
+ unsigned long rate;
+ int i, ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu),
+ &dev);
+ if (ret)
+ return ret;
+
+ printf("Clk\t\tHz\n");
+
+ for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) {
+ clk.id = aspeed_clk_names[i].id;
+ ret = clk_request(dev, &clk);
+ if (ret < 0) {
+ debug("%s clk_request() failed: %d\n", __func__, ret);
+ continue;
+ }
+
+ ret = clk_get_rate(&clk);
+ rate = ret;
+
+ clk_free(&clk);
+
+ if (ret == -ENOTSUPP) {
+ printf("clk ID %lu not supported yet\n",
+ aspeed_clk_names[i].id);
+ continue;
+ }
+ if (ret < 0) {
+ printf("%s %lu: get_rate err: %d\n", __func__,
+ aspeed_clk_names[i].id, ret);
+ continue;
+ }
+
+ printf("%s(%3lu):\t%lu\n", aspeed_clk_names[i].name,
+ aspeed_clk_names[i].id, rate);
+ }
+
+ return 0;
+}
+
+static const struct udevice_id ast2600_clk_ids[] = {
+ { .compatible = "aspeed,ast2600-scu", },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2600_scu) = {
+ .name = "aspeed_ast2600_scu",
+ .id = UCLASS_CLK,
+ .of_match = ast2600_clk_ids,
+ .priv_auto = sizeof(struct ast2600_clk_priv),
+ .ops = &ast2600_clk_ops,
+ .bind = ast2600_clk_bind,
+ .probe = ast2600_clk_probe,
+};
diff --git a/drivers/clk/clk_stm32f.c b/drivers/clk/clk_stm32f.c
index 7e67895ab7..e7c26db51c 100644
--- a/drivers/clk/clk_stm32f.c
+++ b/drivers/clk/clk_stm32f.c
@@ -4,18 +4,19 @@
* Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
*/
+#define LOG_CATEGORY UCLASS_CLK
+
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <log.h>
#include <stm32_rcc.h>
-#include <linux/bitops.h>
-
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/stm32_pwr.h>
-
+#include <dm/device_compat.h>
#include <dt-bindings/mfd/stm32f7-rcc.h>
+#include <linux/bitops.h>
#define RCC_CR_HSION BIT(0)
#define RCC_CR_HSEON BIT(16)
@@ -309,7 +310,7 @@ static unsigned long stm32_clk_get_pllsai_rate(struct stm32_clk *priv,
>> RCC_PLLSAICFGR_PLLSAIR_SHIFT;
break;
default:
- pr_err("incorrect PLLSAI output %d\n", output);
+ log_err("incorrect PLLSAI output %d\n", output);
return -EINVAL;
}
@@ -490,7 +491,7 @@ static ulong stm32_clk_get_rate(struct clk *clk)
return (sysclk >> stm32_get_apb_shift(regs, APB2));
default:
- pr_err("clock index %ld out of range\n", clk->id);
+ dev_err(clk->dev, "clock index %ld out of range\n", clk->id);
return -EINVAL;
}
}
@@ -509,8 +510,9 @@ static ulong stm32_set_rate(struct clk *clk, ulong rate)
/* Only set_rate for LTDC clock is implemented */
if (clk->id != STM32F7_APB2_CLOCK(LTDC)) {
- pr_err("set_rate not implemented for clock index %ld\n",
- clk->id);
+ dev_err(clk->dev,
+ "set_rate not implemented for clock index %ld\n",
+ clk->id);
return 0;
}
@@ -604,8 +606,8 @@ static int stm32_clk_enable(struct clk *clk)
u32 offset = clk->id / 32;
u32 bit_index = clk->id % 32;
- debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
- __func__, clk->id, offset, bit_index);
+ dev_dbg(clk->dev, "clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
+ clk->id, offset, bit_index);
setbits_le32(&regs->ahb1enr + offset, BIT(bit_index));
return 0;
@@ -618,7 +620,7 @@ static int stm32_clk_probe(struct udevice *dev)
struct clk clk;
int err;
- debug("%s\n", __func__);
+ dev_dbg(dev, "%s\n", __func__);
struct stm32_clk *priv = dev_get_priv(dev);
fdt_addr_t addr;
@@ -652,14 +654,14 @@ static int stm32_clk_probe(struct udevice *dev)
&fixed_clock_dev);
if (err) {
- pr_err("Can't find fixed clock (%d)", err);
+ dev_err(dev, "Can't find fixed clock (%d)", err);
return err;
}
err = clk_request(fixed_clock_dev, &clk);
if (err) {
- pr_err("Can't request %s clk (%d)", fixed_clock_dev->name,
- err);
+ dev_err(dev, "Can't request %s clk (%d)",
+ fixed_clock_dev->name, err);
return err;
}
@@ -673,8 +675,8 @@ static int stm32_clk_probe(struct udevice *dev)
priv->hse_rate = clk_get_rate(&clk);
if (priv->hse_rate < 1000000) {
- pr_err("%s: unexpected HSE clock rate = %ld \"n", __func__,
- priv->hse_rate);
+ dev_err(dev, "unexpected HSE clock rate = %ld \"n",
+ priv->hse_rate);
return -EINVAL;
}
@@ -684,8 +686,7 @@ static int stm32_clk_probe(struct udevice *dev)
err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
&args);
if (err) {
- debug("%s: can't find syscon device (%d)\n", __func__,
- err);
+ dev_err(dev, "can't find syscon device (%d)\n", err);
return err;
}
@@ -699,10 +700,10 @@ static int stm32_clk_probe(struct udevice *dev)
static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
{
- debug("%s(clk=%p)\n", __func__, clk);
+ dev_dbg(clk->dev, "clk=%p\n", clk);
if (args->args_count != 2) {
- debug("Invaild args_count: %d\n", args->args_count);
+ dev_dbg(clk->dev, "Invaild args_count: %d\n", args->args_count);
return -EINVAL;
}
diff --git a/drivers/clk/clk_stm32h7.c b/drivers/clk/clk_stm32h7.c
index 0171fe8c11..20b3647099 100644
--- a/drivers/clk/clk_stm32h7.c
+++ b/drivers/clk/clk_stm32h7.c
@@ -4,6 +4,8 @@
* Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
*/
+#define LOG_CATEGORY UCLASS_CLK
+
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
@@ -11,6 +13,7 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
+#include <dm/device_compat.h>
#include <dm/root.h>
#include <linux/bitops.h>
@@ -465,18 +468,18 @@ static ulong stm32_get_rate(struct stm32_rcc_regs *regs, enum pllsrc pllsrc)
int ret;
const char *name = pllsrc_name[pllsrc];
- debug("%s name %s\n", __func__, name);
+ log_debug("pllsrc name %s\n", name);
clk.id = 0;
ret = uclass_get_device_by_name(UCLASS_CLK, name, &fixed_clock_dev);
if (ret) {
- pr_err("Can't find clk %s (%d)", name, ret);
+ log_err("Can't find clk %s (%d)", name, ret);
return 0;
}
ret = clk_request(fixed_clock_dev, &clk);
if (ret) {
- pr_err("Can't request %s clk (%d)", name, ret);
+ log_err("Can't request %s clk (%d)", name, ret);
return 0;
}
@@ -484,8 +487,7 @@ static ulong stm32_get_rate(struct stm32_rcc_regs *regs, enum pllsrc pllsrc)
if (pllsrc == HSI)
divider = stm32_get_HSI_divider(regs);
- debug("%s divider %d rate %ld\n", __func__,
- divider, clk_get_rate(&clk));
+ log_debug("divider %d rate %ld\n", divider, clk_get_rate(&clk));
return clk_get_rate(&clk) >> divider;
};
@@ -516,7 +518,7 @@ static u32 stm32_get_PLL1_rate(struct stm32_rcc_regs *regs,
break;
case RCC_PLLCKSELR_PLLSRC_NO_CLK:
/* shouldn't happen */
- pr_err("wrong value for RCC_PLLCKSELR register\n");
+ log_err("wrong value for RCC_PLLCKSELR register\n");
pllsrc = 0;
break;
}
@@ -546,10 +548,10 @@ static u32 stm32_get_PLL1_rate(struct stm32_rcc_regs *regs,
vco = (pllsrc / divm1) * divn1;
rate = (pllsrc * fracn1) / (divm1 * 8192);
- debug("%s divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\n",
- __func__, divm1, divn1, divp1, divq1, divr1);
- debug("%s fracn1 = %d vco = %ld rate = %ld\n",
- __func__, fracn1, vco, rate);
+ log_debug("divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\n",
+ divm1, divn1, divp1, divq1, divr1);
+ log_debug("fracn1 = %d vco = %ld rate = %ld\n",
+ fracn1, vco, rate);
switch (output) {
case PLL1_P_CK:
@@ -610,7 +612,7 @@ u32 psc = stm32_get_apb_psc(regs, apb);
case 16:
return sysclk / 4;
default:
- pr_err("unexpected prescaler value (%d)\n", psc);
+ log_err("unexpected prescaler value (%d)\n", psc);
return 0;
}
else
@@ -623,7 +625,7 @@ u32 psc = stm32_get_apb_psc(regs, apb);
case 16:
return sysclk / psc;
default:
- pr_err("unexpected prescaler value (%d)\n", psc);
+ log_err("unexpected prescaler value (%d)\n", psc);
return 0;
}
};
@@ -665,8 +667,8 @@ static ulong stm32_clk_get_rate(struct clk *clk)
if (!sysclk)
return sysclk;
- debug("%s system clock: source = %d freq = %ld\n",
- __func__, source, sysclk);
+ dev_dbg(clk->dev, "system clock: source = %d freq = %ld\n",
+ source, sysclk);
d1cfgr = readl(&regs->d1cfgr);
@@ -685,8 +687,8 @@ static ulong stm32_clk_get_rate(struct clk *clk)
gate_offset = clk_map[clk->id].gate_offset;
- debug("%s clk->id=%ld gate_offset=0x%x sysclk=%ld\n",
- __func__, clk->id, gate_offset, sysclk);
+ dev_dbg(clk->dev, "clk->id=%ld gate_offset=0x%x sysclk=%ld\n",
+ clk->id, gate_offset, sysclk);
switch (gate_offset) {
case RCC_AHB3ENR:
@@ -704,8 +706,8 @@ static ulong stm32_clk_get_rate(struct clk *clk)
sysclk = sysclk / prescaler_table[idx];
}
- debug("%s system clock: freq after APB3 prescaler = %ld\n",
- __func__, sysclk);
+ dev_dbg(clk->dev, "system clock: freq after APB3 prescaler = %ld\n",
+ sysclk);
return sysclk;
break;
@@ -719,8 +721,9 @@ static ulong stm32_clk_get_rate(struct clk *clk)
sysclk = sysclk / prescaler_table[idx];
}
- debug("%s system clock: freq after APB4 prescaler = %ld\n",
- __func__, sysclk);
+ dev_dbg(clk->dev,
+ "system clock: freq after APB4 prescaler = %ld\n",
+ sysclk);
return sysclk;
break;
@@ -741,8 +744,9 @@ static ulong stm32_clk_get_rate(struct clk *clk)
return stm32_get_timer_rate(priv, sysclk, APB1);
}
- debug("%s system clock: freq after APB1 prescaler = %ld\n",
- __func__, sysclk);
+ dev_dbg(clk->dev,
+ "system clock: freq after APB1 prescaler = %ld\n",
+ sysclk);
return (sysclk / stm32_get_apb_psc(regs, APB1));
break;
@@ -758,15 +762,17 @@ static ulong stm32_clk_get_rate(struct clk *clk)
return stm32_get_timer_rate(priv, sysclk, APB2);
}
- debug("%s system clock: freq after APB2 prescaler = %ld\n",
- __func__, sysclk);
+ dev_dbg(clk->dev,
+ "system clock: freq after APB2 prescaler = %ld\n",
+ sysclk);
return (sysclk / stm32_get_apb_psc(regs, APB2));
break;
default:
- pr_err("unexpected gate_offset value (0x%x)\n", gate_offset);
+ dev_err(clk->dev, "unexpected gate_offset value (0x%x)\n",
+ gate_offset);
return -EINVAL;
break;
}
@@ -783,9 +789,9 @@ static int stm32_clk_enable(struct clk *clk)
gate_offset = clk_map[clk_id].gate_offset;
gate_bit_index = clk_map[clk_id].gate_bit_idx;
- debug("%s: clkid=%ld gate offset=0x%x bit_index=%d name=%s\n",
- __func__, clk->id, gate_offset, gate_bit_index,
- clk_map[clk_id].name);
+ dev_dbg(clk->dev, "clkid=%ld gate offset=0x%x bit_index=%d name=%s\n",
+ clk->id, gate_offset, gate_bit_index,
+ clk_map[clk_id].name);
setbits_le32(&regs->cr + (gate_offset / 4), BIT(gate_bit_index));
@@ -810,13 +816,13 @@ static int stm32_clk_probe(struct udevice *dev)
"st,syscfg", &syscon);
if (err) {
- pr_err("unable to find syscon device\n");
+ dev_err(dev, "unable to find syscon device\n");
return err;
}
priv->pwr_regmap = syscon_get_regmap(syscon);
if (!priv->pwr_regmap) {
- pr_err("unable to find regmap\n");
+ dev_err(dev, "unable to find regmap\n");
return -ENODEV;
}
@@ -829,7 +835,7 @@ static int stm32_clk_of_xlate(struct clk *clk,
struct ofnode_phandle_args *args)
{
if (args->args_count != 1) {
- debug("Invaild args_count: %d\n", args->args_count);
+ dev_dbg(clk->dev, "Invaild args_count: %d\n", args->args_count);
return -EINVAL;
}
@@ -852,7 +858,7 @@ static int stm32_clk_of_xlate(struct clk *clk,
clk->id = 0;
}
- debug("%s clk->id %ld\n", __func__, clk->id);
+ dev_dbg(clk->dev, "clk->id %ld\n", clk->id);
return 0;
}
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 5bea2b60b9..d4f1048591 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -3,6 +3,8 @@
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/
+#define LOG_CATEGORY UCLASS_CLK
+
#include <common.h>
#include <clk-uclass.h>
#include <div64.h>
@@ -14,12 +16,13 @@
#include <syscon.h>
#include <time.h>
#include <vsprintf.h>
-#include <linux/bitops.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
#include <asm/arch/sys_proto.h>
+#include <dm/device_compat.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -781,7 +784,7 @@ static const struct stm32mp1_clk_data stm32mp1_data = {
static ulong stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv, int idx)
{
if (idx >= NB_OSC) {
- debug("%s: clk id %d not found\n", __func__, idx);
+ log_debug("clk id %d not found\n", idx);
return 0;
}
@@ -799,7 +802,7 @@ static int stm32mp1_clk_get_id(struct stm32mp1_clk_priv *priv, unsigned long id)
}
if (i == nb_clks) {
- printf("%s: clk id %d not found\n", __func__, (u32)id);
+ log_err("clk id %d not found\n", (u32)id);
return -EINVAL;
}
@@ -812,8 +815,7 @@ static int stm32mp1_clk_get_sel(struct stm32mp1_clk_priv *priv,
const struct stm32mp1_clk_gate *gate = priv->data->gate;
if (gate[i].sel > _PARENT_SEL_NB) {
- printf("%s: parents for clk id %d not found\n",
- __func__, i);
+ log_err("parents for clk id %d not found\n", i);
return -EINVAL;
}
@@ -858,17 +860,14 @@ static int stm32mp1_clk_get_parent(struct stm32mp1_clk_priv *priv,
p = (readl(priv->base + sel[s].offset) >> sel[s].src) & sel[s].msk;
if (p < sel[s].nb_parent) {
-#ifdef DEBUG
- debug("%s: %s clock is the parent %s of clk id %d\n", __func__,
- stm32mp1_clk_parent_name[sel[s].parent[p]],
- stm32mp1_clk_parent_sel_name[s],
- (u32)id);
-#endif
+ log_content("%s clock is the parent %s of clk id %d\n",
+ stm32mp1_clk_parent_name[sel[s].parent[p]],
+ stm32mp1_clk_parent_sel_name[s],
+ (u32)id);
return sel[s].parent[p];
}
- pr_err("%s: no parents defined for clk id %d\n",
- __func__, (u32)id);
+ log_err("no parents defined for clk id %d\n", (u32)id);
return -EINVAL;
}
@@ -1124,7 +1123,7 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p)
if (!uclass_get_device_by_name(UCLASS_CLK, "ck_dsi_phy",
&dev)) {
if (clk_request(dev, &clk)) {
- pr_err("ck_dsi_phy request");
+ log_err("ck_dsi_phy request");
} else {
clk.id = 0;
clock = clk_get_rate(&clk);
@@ -1136,8 +1135,7 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p)
break;
}
- debug("%s(%d) clock = %lx : %ld kHz\n",
- __func__, p, clock, clock / 1000);
+ log_debug("id=%d clock = %lx : %ld kHz\n", p, clock, clock / 1000);
return clock;
}
@@ -1156,7 +1154,7 @@ static int stm32mp1_clk_enable(struct clk *clk)
else
setbits_le32(priv->base + gate[i].offset, BIT(gate[i].bit));
- debug("%s: id clock %d has been enabled\n", __func__, (u32)clk->id);
+ dev_dbg(clk->dev, "%s: id clock %d has been enabled\n", __func__, (u32)clk->id);
return 0;
}
@@ -1177,7 +1175,7 @@ static int stm32mp1_clk_disable(struct clk *clk)
else
clrbits_le32(priv->base + gate[i].offset, BIT(gate[i].bit));
- debug("%s: id clock %d has been disabled\n", __func__, (u32)clk->id);
+ dev_dbg(clk->dev, "%s: id clock %d has been disabled\n", __func__, (u32)clk->id);
return 0;
}
@@ -1193,10 +1191,9 @@ static ulong stm32mp1_clk_get_rate(struct clk *clk)
rate = stm32mp1_clk_get(priv, p);
-#ifdef DEBUG
- debug("%s: computed rate for id clock %d is %d (parent is %s)\n",
- __func__, (u32)clk->id, (u32)rate, stm32mp1_clk_parent_name[p]);
-#endif
+ dev_vdbg(clk->dev, "computed rate for id clock %d is %d (parent is %s)\n",
+ (u32)clk->id, (u32)rate, stm32mp1_clk_parent_name[p]);
+
return rate;
}
@@ -1335,7 +1332,7 @@ static int stm32mp1_pll1_opp(struct stm32mp1_clk_priv *priv, int clksrc,
ret = stm32mp1_get_max_opp_freq(priv, &output_freq);
if (ret) {
- debug("PLL1 OPP configuration not found (%d).\n", ret);
+ log_debug("PLL1 OPP configuration not found (%d).\n", ret);
return ret;
}
@@ -1440,8 +1437,8 @@ static int stm32mp1_osc_wait(int enable, fdt_addr_t rcc, u32 offset,
TIMEOUT_1S);
if (ret)
- pr_err("OSC %x @ %x timeout for enable=%d : 0x%x\n",
- mask_rdy, address, enable, readl(address));
+ log_err("OSC %x @ %x timeout for enable=%d : 0x%x\n",
+ mask_rdy, address, enable, readl(address));
return ret;
}
@@ -1529,8 +1526,8 @@ static int stm32mp1_set_hsidiv(fdt_addr_t rcc, u8 hsidiv)
val & RCC_OCRDYR_HSIDIVRDY,
TIMEOUT_200MS);
if (ret)
- pr_err("HSIDIV failed @ 0x%x: 0x%x\n",
- address, readl(address));
+ log_err("HSIDIV failed @ 0x%x: 0x%x\n",
+ address, readl(address));
return ret;
}
@@ -1546,7 +1543,7 @@ static int stm32mp1_hsidiv(fdt_addr_t rcc, ulong hsifreq)
break;
if (hsidiv == 4) {
- pr_err("clk-hsi frequency invalid");
+ log_err("clk-hsi frequency invalid");
return -1;
}
@@ -1577,8 +1574,8 @@ static int pll_output(struct stm32mp1_clk_priv *priv, int pll_id, int output)
TIMEOUT_200MS);
if (ret) {
- pr_err("PLL%d start failed @ 0x%x: 0x%x\n",
- pll_id, pllxcr, readl(pllxcr));
+ log_err("PLL%d start failed @ 0x%x: 0x%x\n",
+ pll_id, pllxcr, readl(pllxcr));
return ret;
}
@@ -1640,7 +1637,7 @@ static int pll_config(struct stm32mp1_clk_priv *priv, int pll_id,
if (refclk < (stm32mp1_pll[type].refclk_min * 1000000) ||
refclk > (stm32mp1_pll[type].refclk_max * 1000000)) {
- debug("invalid refclk = %x\n", (u32)refclk);
+ log_err("invalid refclk = %x\n", (u32)refclk);
return -EINVAL;
}
if (type == PLL_800 && refclk >= 8000000)
@@ -1736,7 +1733,7 @@ static __maybe_unused int pll_set_rate(struct udevice *dev,
divn = (value >> 13) - 1;
if (divn < DIVN_MIN ||
divn > stm32mp1_pll[type].divn_max) {
- pr_err("divn invalid = %d", divn);
+ dev_err(dev, "divn invalid = %d", divn);
return -EINVAL;
}
fracv = value - ((divn + 1) << 13);
@@ -1761,8 +1758,8 @@ static int set_clksrc(struct stm32mp1_clk_priv *priv, unsigned int clksrc)
ret = readl_poll_timeout(address, val, val & RCC_SELR_SRCRDY,
TIMEOUT_200MS);
if (ret)
- pr_err("CLKSRC %x start failed @ 0x%x: 0x%x\n",
- clksrc, address, readl(address));
+ log_err("CLKSRC %x start failed @ 0x%x: 0x%x\n",
+ clksrc, address, readl(address));
return ret;
}
@@ -1781,7 +1778,7 @@ static void stgen_config(struct stm32mp1_clk_priv *priv)
if (cntfid0 != rate) {
u64 counter;
- pr_debug("System Generic Counter (STGEN) update\n");
+ log_debug("System Generic Counter (STGEN) update\n");
clrbits_le32(stgenc + STGENC_CNTCR, STGENC_CNTCR_EN);
counter = (u64)readl(stgenc + STGENC_CNTCVL);
counter |= ((u64)(readl(stgenc + STGENC_CNTCVU))) << 32;
@@ -1807,8 +1804,8 @@ static int set_clkdiv(unsigned int clkdiv, u32 address)
ret = readl_poll_timeout(address, val, val & RCC_DIVR_DIVRDY,
TIMEOUT_200MS);
if (ret)
- pr_err("CLKDIV %x start failed @ 0x%x: 0x%x\n",
- clkdiv, address, readl(address));
+ log_err("CLKDIV %x start failed @ 0x%x: 0x%x\n",
+ clkdiv, address, readl(address));
return ret;
}
@@ -1891,13 +1888,13 @@ static int stm32mp1_clktree(struct udevice *dev)
/* check mandatory field */
ret = dev_read_u32_array(dev, "st,clksrc", clksrc, CLKSRC_NB);
if (ret < 0) {
- debug("field st,clksrc invalid: error %d\n", ret);
+ dev_dbg(dev, "field st,clksrc invalid: error %d\n", ret);
return -FDT_ERR_NOTFOUND;
}
ret = dev_read_u32_array(dev, "st,clkdiv", clkdiv, CLKDIV_NB);
if (ret < 0) {
- debug("field st,clkdiv invalid: error %d\n", ret);
+ dev_dbg(dev, "field st,clkdiv invalid: error %d\n", ret);
return -FDT_ERR_NOTFOUND;
}
@@ -1911,11 +1908,11 @@ static int stm32mp1_clktree(struct udevice *dev)
pllcfg_valid[i] = ofnode_valid(node);
pllcsg_set[i] = false;
if (pllcfg_valid[i]) {
- debug("DT for PLL %d @ %s\n", i, name);
+ dev_dbg(dev, "DT for PLL %d @ %s\n", i, name);
ret = ofnode_read_u32_array(node, "cfg",
pllcfg[i], PLLCFG_NB);
if (ret < 0) {
- debug("field cfg invalid: error %d\n", ret);
+ dev_dbg(dev, "field cfg invalid: error %d\n", ret);
return -FDT_ERR_NOTFOUND;
}
pllfracv[i] = ofnode_read_u32_default(node, "frac", 0);
@@ -1925,30 +1922,30 @@ static int stm32mp1_clktree(struct udevice *dev)
if (!ret) {
pllcsg_set[i] = true;
} else if (ret != -FDT_ERR_NOTFOUND) {
- debug("invalid csg node for pll@%d res=%d\n",
- i, ret);
+ dev_dbg(dev, "invalid csg node for pll@%d res=%d\n",
+ i, ret);
return ret;
}
} else if (i == _PLL1) {
/* use OPP for PLL1 for A7 CPU */
- debug("DT for PLL %d with OPP\n", i);
+ dev_dbg(dev, "DT for PLL %d with OPP\n", i);
ret = stm32mp1_pll1_opp(priv,
clksrc[CLKSRC_PLL12],
pllcfg[i],
&pllfracv[i]);
if (ret) {
- debug("PLL %d with OPP error = %d\n", i, ret);
+ dev_dbg(dev, "PLL %d with OPP error = %d\n", i, ret);
return ret;
}
pllcfg_valid[i] = true;
}
}
- debug("configuration MCO\n");
+ dev_dbg(dev, "configuration MCO\n");
stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]);
stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]);
- debug("switch ON osillator\n");
+ dev_dbg(dev, "switch ON osillator\n");
/*
* switch ON oscillator found in device-tree,
* HSI already ON after bootrom
@@ -1986,24 +1983,24 @@ static int stm32mp1_clktree(struct udevice *dev)
stm32mp1_csi_set(rcc, 1);
/* come back to HSI */
- debug("come back to HSI\n");
+ dev_dbg(dev, "come back to HSI\n");
set_clksrc(priv, CLK_MPU_HSI);
set_clksrc(priv, CLK_AXI_HSI);
set_clksrc(priv, CLK_MCU_HSI);
- debug("pll stop\n");
+ dev_dbg(dev, "pll stop\n");
for (i = 0; i < _PLL_NB; i++)
pll_stop(priv, i);
/* configure HSIDIV */
- debug("configure HSIDIV\n");
+ dev_dbg(dev, "configure HSIDIV\n");
if (priv->osc[_HSI]) {
stm32mp1_hsidiv(rcc, priv->osc[_HSI]);
stgen_config(priv);
}
/* select DIV */
- debug("select DIV\n");
+ dev_dbg(dev, "select DIV\n");
/* no ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */
writel(clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK, rcc + RCC_MPCKDIVR);
set_clkdiv(clkdiv[CLKDIV_AXI], rcc + RCC_AXIDIVR);
@@ -2018,17 +2015,17 @@ static int stm32mp1_clktree(struct udevice *dev)
writel(clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK, rcc + RCC_RTCDIVR);
/* configure PLLs source */
- debug("configure PLLs source\n");
+ dev_dbg(dev, "configure PLLs source\n");
set_clksrc(priv, clksrc[CLKSRC_PLL12]);
set_clksrc(priv, clksrc[CLKSRC_PLL3]);
set_clksrc(priv, clksrc[CLKSRC_PLL4]);
/* configure and start PLLs */
- debug("configure PLLs\n");
+ dev_dbg(dev, "configure PLLs\n");
for (i = 0; i < _PLL_NB; i++) {
if (!pllcfg_valid[i])
continue;
- debug("configure PLL %d\n", i);
+ dev_dbg(dev, "configure PLL %d\n", i);
pll_config(priv, i, pllcfg[i], pllfracv[i]);
if (pllcsg_set[i])
pll_csg(priv, i, pllcsg[i]);
@@ -2039,7 +2036,7 @@ static int stm32mp1_clktree(struct udevice *dev)
for (i = 0; i < _PLL_NB; i++) {
if (!pllcfg_valid[i])
continue;
- debug("output PLL %d\n", i);
+ dev_dbg(dev, "output PLL %d\n", i);
pll_output(priv, i, pllcfg[i][PLLCFG_O]);
}
@@ -2048,14 +2045,14 @@ static int stm32mp1_clktree(struct udevice *dev)
stm32mp1_lse_wait(rcc);
/* configure with expected clock source */
- debug("CLKSRC\n");
+ dev_dbg(dev, "CLKSRC\n");
set_clksrc(priv, clksrc[CLKSRC_MPU]);
set_clksrc(priv, clksrc[CLKSRC_AXI]);
set_clksrc(priv, clksrc[CLKSRC_MCU]);
set_rtcsrc(priv, clksrc[CLKSRC_RTC], lse_css);
/* configure PKCK */
- debug("PKCK\n");
+ dev_dbg(dev, "PKCK\n");
pkcs_cell = dev_read_prop(dev, "st,pkcs", &len);
if (pkcs_cell) {
bool ckper_disabled = false;
@@ -2081,7 +2078,7 @@ static int stm32mp1_clktree(struct udevice *dev)
/* STGEN clock source can change with CLK_STGEN_XXX */
stgen_config(priv);
- debug("oscillator off\n");
+ dev_dbg(dev, "oscillator off\n");
/* switch OFF HSI if not found in device-tree */
if (!priv->osc[_HSI])
stm32mp1_hsi_set(rcc, 0);
@@ -2147,14 +2144,12 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate)
case DSI_PX:
break;
default:
- pr_err("not supported");
+ dev_err(clk->dev, "Set of clk %ld not supported", clk->id);
return -EINVAL;
}
p = stm32mp1_clk_get_parent(priv, clk->id);
-#ifdef DEBUG
- debug("%s: parent = %d:%s\n", __func__, p, stm32mp1_clk_parent_name[p]);
-#endif
+ dev_vdbg(clk->dev, "parent = %d:%s\n", p, stm32mp1_clk_parent_name[p]);
if (p < 0)
return -EINVAL;
@@ -2192,7 +2187,7 @@ static void stm32mp1_osc_clk_init(const char *name,
clk.id = 0;
if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) {
if (clk_request(dev, &clk))
- pr_err("%s request", name);
+ log_err("%s request", name);
else
priv->osc[index] = clk_get_rate(&clk);
}
@@ -2214,7 +2209,7 @@ static void stm32mp1_osc_init(struct udevice *dev)
for (i = 0; i < NB_OSC; i++) {
stm32mp1_osc_clk_init(name[i], priv, i);
- debug("%d: %s => %x\n", i, name[i], (u32)priv->osc[i]);
+ dev_dbg(dev, "%d: %s => %x\n", i, name[i], (u32)priv->osc[i]);
}
}
@@ -2288,11 +2283,11 @@ static int stm32mp1_clk_probe(struct udevice *dev)
if (!(gd->flags & GD_FLG_RELOC))
result = stm32mp1_clktree(dev);
if (result)
- printf("clock tree initialization failed (%d)\n", result);
+ dev_err(dev, "clock tree initialization failed (%d)\n", result);
#endif
#ifndef CONFIG_SPL_BUILD
-#if defined(DEBUG)
+#if defined(VERBOSE_DEBUG)
/* display debug information for probe after relocation */
if (gd->flags & GD_FLG_RELOC)
stm32mp1_clk_dump(priv);
@@ -2306,14 +2301,14 @@ static int stm32mp1_clk_probe(struct udevice *dev)
if (gd->flags & GD_FLG_RELOC) {
char buf[32];
- printf("Clocks:\n");
- printf("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk));
- printf("- MCU : %s MHz\n",
- strmhz(buf, stm32mp1_clk_get(priv, _CK_MCU)));
- printf("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk));
- printf("- PER : %s MHz\n",
- strmhz(buf, stm32mp1_clk_get(priv, _CK_PER)));
- printf("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk));
+ log_info("Clocks:\n");
+ log_info("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk));
+ log_info("- MCU : %s MHz\n",
+ strmhz(buf, stm32mp1_clk_get(priv, _CK_MCU)));
+ log_info("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk));
+ log_info("- PER : %s MHz\n",
+ strmhz(buf, stm32mp1_clk_get(priv, _CK_PER)));
+ log_info("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk));
}
#endif /* CONFIG_DISPLAY_CPUINFO */
#endif
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 237fd17f16..522e724221 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_MT8512) += clk-mt8512.o
obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o
obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
+obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o
obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o
obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
new file mode 100644
index 0000000000..17e653a1f0
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -0,0 +1,823 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT8183 SoC
+ *
+ * Copyright (C) 2020 BayLibre, SAS
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Fabien Parent <fparent@baylibre.com>
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt8183-clk.h>
+
+#include "clk-mtk.h"
+
+#define MT8183_PLL_FMAX (3800UL * MHZ)
+#define MT8183_PLL_FMIN (1500UL * MHZ)
+
+/* apmixedsys */
+#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, _pcwbits, \
+ _pcwibits, _pd_reg, _pd_shift, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .rst_bar_mask = _rst_bar_mask, \
+ .fmax = MT8183_PLL_FMAX, \
+ .fmin = MT8183_PLL_FMIN, \
+ .flags = _flags, \
+ .pcwbits = _pcwbits, \
+ .pcwibits = _pcwibits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static const struct mtk_pll_data apmixed_plls[] = {
+ PLL(CLK_APMIXED_ARMPLL_LL, 0x0200, 0x020C, 0x00000001,
+ HAVE_RST_BAR, BIT(24), 22, 8, 0x0204, 24,
+ 0x0204, 0),
+ PLL(CLK_APMIXED_ARMPLL_L, 0x0210, 0x021C, 0x00000001,
+ HAVE_RST_BAR, BIT(24), 22, 8, 0x0214, 24,
+ 0x0214, 0),
+ PLL(CLK_APMIXED_CCIPLL, 0x0290, 0x029C, 0x00000001,
+ HAVE_RST_BAR, BIT(24), 22, 8, 0x0294, 24,
+ 0x0294, 0),
+ PLL(CLK_APMIXED_MAINPLL, 0x0220, 0x022C, 0x00000001,
+ HAVE_RST_BAR, BIT(24), 22, 8, 0x0224, 24,
+ 0x0224, 0),
+ PLL(CLK_APMIXED_UNIV2PLL, 0x0230, 0x023C, 0x00000001,
+ HAVE_RST_BAR, BIT(24), 22, 8, 0x0234, 24,
+ 0x0234, 0),
+ PLL(CLK_APMIXED_MSDCPLL, 0x0250, 0x025C, 0x00000001,
+ 0, 0, 22, 8, 0x0254, 24, 0x0254, 0),
+ PLL(CLK_APMIXED_MMPLL, 0x0270, 0x027C, 0x00000001,
+ HAVE_RST_BAR, BIT(23), 22, 8, 0x0274, 24,
+ 0x0274, 0),
+ PLL(CLK_APMIXED_MFGPLL, 0x0240, 0x024C, 0x00000001,
+ 0, 0, 22, 8, 0x0244, 24, 0x0244, 0),
+ PLL(CLK_APMIXED_TVDPLL, 0x0260, 0x026C, 0x00000001,
+ 0, 0, 22, 8, 0x0264, 24, 0x0264, 0),
+ PLL(CLK_APMIXED_APLL1, 0x02A0, 0x02B0, 0x00000001,
+ 0, 0, 32, 8, 0x02A0, 1, 0x02A4, 0),
+ PLL(CLK_APMIXED_APLL2, 0x02b4, 0x02c4, 0x00000001,
+ 0, 0, 32, 8, 0x02B4, 1, 0x02B8, 0),
+};
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+ FIXED_CLK(CLK_TOP_CLK26M, CLK_XTAL, 26000000),
+ FIXED_CLK(CLK_TOP_ULPOSC, CLK_XTAL, 250000),
+ FIXED_CLK(CLK_TOP_UNIVP_192M, CLK_TOP_UNIVPLL, 192000000),
+};
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+ FACTOR(CLK_TOP_CLK13M, CLK_TOP_CLK26M, 1, 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_F26M_CK_D2, CLK_TOP_CLK26M, 1, 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_CK, CLK_APMIXED_MAINPLL, 1,
+ 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_SYSPLL_D2, CLK_TOP_SYSPLL_CK, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D3, CLK_APMIXED_MAINPLL, 1,
+ 3, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1,
+ 5, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1,
+ 7, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_SYSPLL_D2_D2, CLK_TOP_SYSPLL_D2, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D2_D4, CLK_TOP_SYSPLL_D2, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D2_D8, CLK_TOP_SYSPLL_D2, 1,
+ 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D2_D16, CLK_TOP_SYSPLL_D2, 1,
+ 16, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D3_D2, CLK_TOP_SYSPLL_D3, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D3_D4, CLK_TOP_SYSPLL_D3, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D3_D8, CLK_TOP_SYSPLL_D3, 1,
+ 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D5_D2, CLK_TOP_SYSPLL_D5, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D5_D4, CLK_TOP_SYSPLL_D5, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D7_D2, CLK_TOP_SYSPLL_D7, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_SYSPLL_D7_D4, CLK_TOP_SYSPLL_D7, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_CK, CLK_TOP_UNIVPLL, 1, 1, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D2, CLK_TOP_UNIVPLL_CK, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D3, CLK_TOP_UNIVPLL, 1, 3, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D5, CLK_TOP_UNIVPLL, 1, 5, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D7, CLK_TOP_UNIVPLL, 1, 7, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D2_D2, CLK_TOP_UNIVPLL_D2, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D2_D4, CLK_TOP_UNIVPLL_D2, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D2_D8, CLK_TOP_UNIVPLL_D2, 1,
+ 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D3_D2, CLK_TOP_UNIVPLL_D3, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D3_D4, CLK_TOP_UNIVPLL_D3, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D3_D8, CLK_TOP_UNIVPLL_D3, 1,
+ 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D5_D2, CLK_TOP_UNIVPLL_D5, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D5_D4, CLK_TOP_UNIVPLL_D5, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL_D5_D8, CLK_TOP_UNIVPLL_D5, 1,
+ 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVP_192M_CK, CLK_TOP_UNIVP_192M, 1, 1,
+ CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVP_192M_D2, CLK_TOP_UNIVP_192M_CK, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVP_192M_D4, CLK_TOP_UNIVP_192M_CK, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVP_192M_D8, CLK_TOP_UNIVP_192M_CK, 1,
+ 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVP_192M_D16, CLK_TOP_UNIVP_192M_CK, 1,
+ 16, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVP_192M_D32, CLK_TOP_UNIVP_192M_CK, 1,
+ 32, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_APLL1_CK, CLK_APMIXED_APLL1, 1, 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL1_D2, CLK_APMIXED_APLL1, 1, 2, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL1_D4, CLK_APMIXED_APLL1, 1, 4, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL1_D8, CLK_APMIXED_APLL1, 1, 8, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL2_CK, CLK_APMIXED_APLL2, 1, 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL2_D2, CLK_APMIXED_APLL2, 1, 2, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL2_D4, CLK_APMIXED_APLL2, 1, 4, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_APLL2_D8, CLK_APMIXED_APLL2, 1, 8, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_TVDPLL_CK, CLK_APMIXED_TVDPLL, 1, 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_TVDPLL_D2, CLK_TOP_TVDPLL_CK, 1, 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_TVDPLL_D4, CLK_APMIXED_TVDPLL, 1, 4, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_TVDPLL_D8, CLK_APMIXED_TVDPLL, 1, 8, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_TVDPLL_D16, CLK_APMIXED_TVDPLL, 1,
+ 16, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MMPLL_CK, CLK_APMIXED_MMPLL, 1, 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MMPLL_D4, CLK_APMIXED_MMPLL, 1, 4, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MMPLL_D4_D2, CLK_TOP_MMPLL_D4, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_MMPLL_D4_D4, CLK_TOP_MMPLL_D4, 1, 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_MMPLL_D5, CLK_APMIXED_MMPLL, 1, 5, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MMPLL_D5_D2, CLK_TOP_MMPLL_D5, 1,
+ 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_MMPLL_D5_D4, CLK_TOP_MMPLL_D5, 1,
+ 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_MMPLL_D6, CLK_APMIXED_MMPLL, 1, 6, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MMPLL_D7, CLK_APMIXED_MMPLL, 1, 7, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MFGPLL_CK, CLK_APMIXED_MFGPLL, 1, 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MSDCPLL_CK, CLK_APMIXED_MSDCPLL, 1,
+ 1, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MSDCPLL_D2, CLK_APMIXED_MSDCPLL, 1,
+ 2, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MSDCPLL_D4, CLK_APMIXED_MSDCPLL, 1,
+ 4, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MSDCPLL_D8, CLK_APMIXED_MSDCPLL, 1,
+ 8, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_MSDCPLL_D16, CLK_APMIXED_MSDCPLL, 1,
+ 16, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_AD_OSC_CK, CLK_TOP_ULPOSC, 1, 1, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_OSC_D2, CLK_TOP_ULPOSC, 1, 2, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_OSC_D4, CLK_TOP_ULPOSC, 1, 4, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_OSC_D8, CLK_TOP_ULPOSC, 1, 8, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_OSC_D16, CLK_TOP_ULPOSC, 1, 16, CLK_PARENT_TOPCKGEN),
+ FACTOR(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIV2PLL, 1, 2, CLK_PARENT_APMIXED),
+ FACTOR(CLK_TOP_UNIVPLL_D3_D16, CLK_TOP_UNIVPLL_D3, 1,
+ 16, CLK_PARENT_TOPCKGEN),
+};
+
+static const int axi_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D4,
+ CLK_TOP_SYSPLL_D7,
+ CLK_TOP_OSC_D4
+};
+
+static const int mm_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MMPLL_D7,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int img_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MMPLL_D6,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int cam_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2,
+ CLK_TOP_MMPLL_D6,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_MMPLL_D7,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_SYSPLL_D3_D2,
+ CLK_TOP_UNIVPLL_D3_D2
+};
+
+static const int dsp_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MMPLL_D6,
+ CLK_TOP_MMPLL_D7,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int dsp1_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MMPLL_D6,
+ CLK_TOP_MMPLL_D7,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int dsp2_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MMPLL_D6,
+ CLK_TOP_MMPLL_D7,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int ipu_if_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MMPLL_D6,
+ CLK_TOP_MMPLL_D7,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int mfg_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MFGPLL_CK,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_SYSPLL_D3
+};
+
+static const int f52m_mfg_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_UNIVPLL_D3_D4,
+ CLK_TOP_UNIVPLL_D3_D8
+};
+
+static const int camtg_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVP_192M_D8,
+ CLK_TOP_UNIVPLL_D3_D8,
+ CLK_TOP_UNIVP_192M_D4,
+ CLK_TOP_UNIVPLL_D3_D16,
+ CLK_TOP_F26M_CK_D2,
+ CLK_TOP_UNIVP_192M_D16,
+ CLK_TOP_UNIVP_192M_D32
+};
+
+static const int camtg2_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVP_192M_D8,
+ CLK_TOP_UNIVPLL_D3_D8,
+ CLK_TOP_UNIVP_192M_D4,
+ CLK_TOP_UNIVPLL_D3_D16,
+ CLK_TOP_F26M_CK_D2,
+ CLK_TOP_UNIVP_192M_D16,
+ CLK_TOP_UNIVP_192M_D32
+};
+
+static const int camtg3_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVP_192M_D8,
+ CLK_TOP_UNIVPLL_D3_D8,
+ CLK_TOP_UNIVP_192M_D4,
+ CLK_TOP_UNIVPLL_D3_D16,
+ CLK_TOP_F26M_CK_D2,
+ CLK_TOP_UNIVP_192M_D16,
+ CLK_TOP_UNIVP_192M_D32
+};
+
+static const int camtg4_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVP_192M_D8,
+ CLK_TOP_UNIVPLL_D3_D8,
+ CLK_TOP_UNIVP_192M_D4,
+ CLK_TOP_UNIVPLL_D3_D16,
+ CLK_TOP_F26M_CK_D2,
+ CLK_TOP_UNIVP_192M_D16,
+ CLK_TOP_UNIVP_192M_D32
+};
+
+static const int uart_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D3_D8
+};
+
+static const int spi_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D5_D2,
+ CLK_TOP_SYSPLL_D3_D4,
+ CLK_TOP_MSDCPLL_D4
+};
+
+static const int msdc50_hclk_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_SYSPLL_D3_D2
+};
+
+static const int msdc50_0_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_MSDCPLL_CK,
+ CLK_TOP_MSDCPLL_D2,
+ CLK_TOP_UNIVPLL_D2_D4,
+ CLK_TOP_SYSPLL_D3_D2,
+ CLK_TOP_UNIVPLL_D2_D2
+};
+
+static const int msdc30_1_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2,
+ CLK_TOP_SYSPLL_D7,
+ CLK_TOP_MSDCPLL_D2
+};
+
+static const int msdc30_2_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_SYSPLL_D3_D2,
+ CLK_TOP_SYSPLL_D7,
+ CLK_TOP_MSDCPLL_D2
+};
+
+static const int audio_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D5_D4,
+ CLK_TOP_SYSPLL_D7_D4,
+ CLK_TOP_SYSPLL_D2_D16
+};
+
+static const int aud_intbus_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D4,
+ CLK_TOP_SYSPLL_D7_D2
+};
+
+static const int pmicspi_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D8,
+ CLK_TOP_OSC_D8
+};
+
+static const int fpwrap_ulposc_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_OSC_D16,
+ CLK_TOP_OSC_D4,
+ CLK_TOP_OSC_D8
+};
+
+static const int atb_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_SYSPLL_D5
+};
+
+static const int sspm_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D2_D4,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D3
+};
+
+static const int dpi0_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_TVDPLL_D2,
+ CLK_TOP_TVDPLL_D4,
+ CLK_TOP_TVDPLL_D8,
+ CLK_TOP_TVDPLL_D16,
+ CLK_TOP_UNIVPLL_D5_D2,
+ CLK_TOP_UNIVPLL_D3_D4,
+ CLK_TOP_SYSPLL_D3_D4,
+ CLK_TOP_UNIVPLL_D3_D8
+};
+
+static const int scam_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D5_D2
+};
+
+static const int disppwm_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D3_D4,
+ CLK_TOP_OSC_D2,
+ CLK_TOP_OSC_D4,
+ CLK_TOP_OSC_D16
+};
+
+static const int usb_top_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D5_D4,
+ CLK_TOP_UNIVPLL_D3_D4,
+ CLK_TOP_UNIVPLL_D5_D2
+};
+
+static const int ssusb_top_xhci_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D5_D4,
+ CLK_TOP_UNIVPLL_D3_D4,
+ CLK_TOP_UNIVPLL_D5_D2
+};
+
+static const int spm_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D8
+};
+
+static const int i2c_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D8,
+ CLK_TOP_UNIVPLL_D5_D2
+};
+
+static const int scp_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D2_D8,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D3
+};
+
+static const int seninf_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_UNIVPLL_D2_D2,
+ CLK_TOP_UNIVPLL_D3_D2,
+ CLK_TOP_UNIVPLL_D2_D4
+};
+
+static const int dxcc_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_SYSPLL_D2_D4,
+ CLK_TOP_SYSPLL_D2_D8
+};
+
+static const int aud_engen1_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_APLL1_D2,
+ CLK_TOP_APLL1_D4,
+ CLK_TOP_APLL1_D8
+};
+
+static const int aud_engen2_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_APLL2_D2,
+ CLK_TOP_APLL2_D4,
+ CLK_TOP_APLL2_D8
+};
+
+static const int faes_ufsfde_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2,
+ CLK_TOP_SYSPLL_D2_D2,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_SYSPLL_D2_D4,
+ CLK_TOP_UNIVPLL_D3
+};
+
+static const int fufs_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_SYSPLL_D2_D4,
+ CLK_TOP_SYSPLL_D2_D8,
+ CLK_TOP_SYSPLL_D2_D16
+};
+
+static const int aud_1_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_APLL1_CK
+};
+
+static const int aud_2_parents[] = {
+ CLK_TOP_CLK26M,
+ CLK_TOP_APLL2_CK
+};
+
+static const struct mtk_composite top_muxes[] = {
+ /* CLK_CFG_0 */
+ MUX(CLK_TOP_MUX_AXI, axi_parents, 0x40, 0, 2),
+ MUX(CLK_TOP_MUX_MM, mm_parents, 0x40, 8, 3),
+ MUX(CLK_TOP_MUX_IMG, img_parents, 0x40, 16, 3),
+ MUX(CLK_TOP_MUX_CAM, cam_parents, 0x40, 24, 4),
+ /* CLK_CFG_1 */
+ MUX(CLK_TOP_MUX_DSP, dsp_parents, 0x50, 0, 4),
+ MUX(CLK_TOP_MUX_DSP1, dsp1_parents, 0x50, 8, 4),
+ MUX(CLK_TOP_MUX_DSP2, dsp2_parents, 0x50, 16, 4),
+ MUX(CLK_TOP_MUX_IPU_IF, ipu_if_parents, 0x50, 24, 4),
+ /* CLK_CFG_2 */
+ MUX(CLK_TOP_MUX_MFG, mfg_parents, 0x60, 0, 2),
+ MUX(CLK_TOP_MUX_F52M_MFG, f52m_mfg_parents, 0x60, 8, 2),
+ MUX(CLK_TOP_MUX_CAMTG, camtg_parents, 0x60, 16, 3),
+ MUX(CLK_TOP_MUX_CAMTG2, camtg2_parents, 0x60, 24, 3),
+ /* CLK_CFG_3 */
+ MUX(CLK_TOP_MUX_CAMTG3, camtg3_parents, 0x70, 0, 3),
+ MUX(CLK_TOP_MUX_CAMTG4, camtg4_parents, 0x70, 8, 3),
+ MUX(CLK_TOP_MUX_UART, uart_parents, 0x70, 16, 1),
+ MUX(CLK_TOP_MUX_SPI, spi_parents, 0x70, 24, 2),
+ /* CLK_CFG_4 */
+ MUX(CLK_TOP_MUX_MSDC50_0_HCLK, msdc50_hclk_parents, 0x80, 0, 2),
+ MUX(CLK_TOP_MUX_MSDC50_0, msdc50_0_parents, 0x80, 8, 3),
+ MUX(CLK_TOP_MUX_MSDC30_1, msdc30_1_parents, 0x80, 16, 3),
+ MUX(CLK_TOP_MUX_MSDC30_2, msdc30_2_parents, 0x80, 24, 3),
+ /* CLK_CFG_5 */
+ MUX(CLK_TOP_MUX_AUDIO, audio_parents, 0x90, 0, 2),
+ MUX(CLK_TOP_MUX_AUD_INTBUS, aud_intbus_parents, 0x90, 8, 2),
+ MUX(CLK_TOP_MUX_PMICSPI, pmicspi_parents, 0x90, 16, 2),
+ MUX(CLK_TOP_MUX_FPWRAP_ULPOSC, fpwrap_ulposc_parents, 0x90, 24, 2),
+ /* CLK_CFG_6 */
+ MUX(CLK_TOP_MUX_ATB, atb_parents, 0xa0, 0, 2),
+ MUX(CLK_TOP_MUX_SSPM, sspm_parents, 0xa0, 8, 3),
+ MUX(CLK_TOP_MUX_DPI0, dpi0_parents, 0xa0, 16, 4),
+ MUX(CLK_TOP_MUX_SCAM, scam_parents, 0xa0, 24, 1),
+ /* CLK_CFG_7 */
+ MUX(CLK_TOP_MUX_DISP_PWM, disppwm_parents, 0xb0, 0, 3),
+ MUX(CLK_TOP_MUX_USB_TOP, usb_top_parents, 0xb0, 8, 2),
+ MUX(CLK_TOP_MUX_SSUSB_TOP_XHCI, ssusb_top_xhci_parents, 0xb0, 16, 2),
+ MUX(CLK_TOP_MUX_SPM, spm_parents, 0xb0, 24, 1),
+ /* CLK_CFG_8 */
+ MUX(CLK_TOP_MUX_I2C, i2c_parents, 0xc0, 0, 2),
+ MUX(CLK_TOP_MUX_SCP, scp_parents, 0xc0, 8, 3),
+ MUX(CLK_TOP_MUX_SENINF, seninf_parents, 0xc0, 16, 2),
+ MUX(CLK_TOP_MUX_DXCC, dxcc_parents, 0xc0, 24, 2),
+ /* CLK_CFG_9 */
+ MUX(CLK_TOP_MUX_AUD_ENG1, aud_engen1_parents, 0xd0, 0, 2),
+ MUX(CLK_TOP_MUX_AUD_ENG2, aud_engen2_parents, 0xd0, 8, 2),
+ MUX(CLK_TOP_MUX_FAES_UFSFDE, faes_ufsfde_parents, 0xd0, 16, 3),
+ MUX(CLK_TOP_MUX_FUFS, fufs_parents, 0xd0, 24, 2),
+ /* CLK_CFG_10 */
+ MUX(CLK_TOP_MUX_AUD_1, aud_1_parents, 0xe0, 0, 1),
+ MUX(CLK_TOP_MUX_AUD_2, aud_2_parents, 0xe0, 8, 1),
+};
+
+static const struct mtk_clk_tree mt8183_clk_tree = {
+ .xtal_rate = 26 * MHZ,
+ .xtal2_rate = 26 * MHZ,
+ .fdivs_offs = CLK_TOP_CLK13M,
+ .muxes_offs = CLK_TOP_MUX_AXI,
+ .plls = apmixed_plls,
+ .fclks = top_fixed_clks,
+ .fdivs = top_fixed_divs,
+ .muxes = top_muxes,
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+ .set_ofs = 0x80,
+ .clr_ofs = 0x84,
+ .sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+ .set_ofs = 0x88,
+ .clr_ofs = 0x8c,
+ .sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+ .set_ofs = 0xa4,
+ .clr_ofs = 0xa8,
+ .sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs infra3_cg_regs = {
+ .set_ofs = 0xc0,
+ .clr_ofs = 0xc4,
+ .sta_ofs = 0xc8,
+};
+
+#define GATE_INFRA0(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &infra0_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+#define GATE_INFRA1(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &infra1_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+#define GATE_INFRA2(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &infra2_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+#define GATE_INFRA3(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &infra3_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate infra_clks[] = {
+ /* INFRA0 */
+ GATE_INFRA0(CLK_INFRA_PMIC_TMR, CLK_TOP_MUX_AXI, 0),
+ GATE_INFRA0(CLK_INFRA_PMIC_AP, CLK_TOP_MUX_AXI, 1),
+ GATE_INFRA0(CLK_INFRA_PMIC_MD, CLK_TOP_MUX_AXI, 2),
+ GATE_INFRA0(CLK_INFRA_PMIC_CONN, CLK_TOP_MUX_AXI, 3),
+ GATE_INFRA0(CLK_INFRA_SCPSYS, CLK_TOP_MUX_SCP, 4),
+ GATE_INFRA0(CLK_INFRA_SEJ, CLK_TOP_CLK26M, 5),
+ GATE_INFRA0(CLK_INFRA_APXGPT, CLK_TOP_MUX_AXI, 6),
+ GATE_INFRA0(CLK_INFRA_ICUSB, CLK_TOP_MUX_AXI, 8),
+ GATE_INFRA0(CLK_INFRA_GCE, CLK_TOP_MUX_AXI, 9),
+ GATE_INFRA0(CLK_INFRA_THERM, CLK_TOP_MUX_AXI, 10),
+ GATE_INFRA0(CLK_INFRA_I2C0, CLK_TOP_MUX_I2C, 11),
+ GATE_INFRA0(CLK_INFRA_I2C1, CLK_TOP_MUX_I2C, 12),
+ GATE_INFRA0(CLK_INFRA_I2C2, CLK_TOP_MUX_I2C, 13),
+ GATE_INFRA0(CLK_INFRA_I2C3, CLK_TOP_MUX_I2C, 14),
+ GATE_INFRA0(CLK_INFRA_PWM_HCLK, CLK_TOP_MUX_AXI, 15),
+ GATE_INFRA0(CLK_INFRA_PWM1, CLK_TOP_MUX_I2C, 16),
+ GATE_INFRA0(CLK_INFRA_PWM2, CLK_TOP_MUX_I2C, 17),
+ GATE_INFRA0(CLK_INFRA_PWM3, CLK_TOP_MUX_I2C, 18),
+ GATE_INFRA0(CLK_INFRA_PWM4, CLK_TOP_MUX_I2C, 19),
+ GATE_INFRA0(CLK_INFRA_PWM, CLK_TOP_MUX_I2C, 21),
+ GATE_INFRA0(CLK_INFRA_UART0, CLK_TOP_MUX_UART, 22),
+ GATE_INFRA0(CLK_INFRA_UART1, CLK_TOP_MUX_UART, 23),
+ GATE_INFRA0(CLK_INFRA_UART2, CLK_TOP_MUX_UART, 24),
+ GATE_INFRA0(CLK_INFRA_UART3, CLK_TOP_MUX_UART, 25),
+ GATE_INFRA0(CLK_INFRA_GCE_26M, CLK_TOP_MUX_AXI, 27),
+ GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, CLK_TOP_MUX_AXI, 28),
+ GATE_INFRA0(CLK_INFRA_BTIF, CLK_TOP_MUX_AXI, 31),
+ /* INFRA1 */
+ GATE_INFRA1(CLK_INFRA_SPI0, CLK_TOP_MUX_SPI, 1),
+ GATE_INFRA1(CLK_INFRA_MSDC0, CLK_TOP_MUX_MSDC50_0_HCLK, 2),
+ GATE_INFRA1(CLK_INFRA_MSDC1, CLK_TOP_MUX_AXI, 4),
+ GATE_INFRA1(CLK_INFRA_MSDC2, CLK_TOP_MUX_AXI, 5),
+ GATE_INFRA1(CLK_INFRA_MSDC0_SCK, CLK_TOP_MUX_MSDC50_0, 6),
+ GATE_INFRA1(CLK_INFRA_DVFSRC, CLK_TOP_CLK26M, 7),
+ GATE_INFRA1(CLK_INFRA_GCPU, CLK_TOP_MUX_AXI, 8),
+ GATE_INFRA1(CLK_INFRA_TRNG, CLK_TOP_MUX_AXI, 9),
+ GATE_INFRA1(CLK_INFRA_AUXADC, CLK_TOP_CLK26M, 10),
+ GATE_INFRA1(CLK_INFRA_CPUM, CLK_TOP_MUX_AXI, 11),
+ GATE_INFRA1(CLK_INFRA_CCIF1_AP, CLK_TOP_MUX_AXI, 12),
+ GATE_INFRA1(CLK_INFRA_CCIF1_MD, CLK_TOP_MUX_AXI, 13),
+ GATE_INFRA1(CLK_INFRA_AUXADC_MD, CLK_TOP_CLK26M, 14),
+ GATE_INFRA1(CLK_INFRA_MSDC1_SCK, CLK_TOP_MUX_MSDC30_1, 16),
+ GATE_INFRA1(CLK_INFRA_MSDC2_SCK, CLK_TOP_MUX_MSDC30_2, 17),
+ GATE_INFRA1(CLK_INFRA_AP_DMA, CLK_TOP_MUX_AXI, 18),
+ GATE_INFRA1(CLK_INFRA_XIU, CLK_TOP_MUX_AXI, 19),
+ GATE_INFRA1(CLK_INFRA_DEVICE_APC, CLK_TOP_MUX_AXI, 20),
+ GATE_INFRA1(CLK_INFRA_CCIF_AP, CLK_TOP_MUX_AXI, 23),
+ GATE_INFRA1(CLK_INFRA_DEBUGSYS, CLK_TOP_MUX_AXI, 24),
+ GATE_INFRA1(CLK_INFRA_AUDIO, CLK_TOP_MUX_AXI, 25),
+ GATE_INFRA1(CLK_INFRA_CCIF_MD, CLK_TOP_MUX_AXI, 26),
+ GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, CLK_TOP_MUX_DXCC, 27),
+ GATE_INFRA1(CLK_INFRA_DXCC_AO, CLK_TOP_MUX_DXCC, 28),
+ GATE_INFRA1(CLK_INFRA_DEVMPU_BCLK, CLK_TOP_MUX_AXI, 30),
+ GATE_INFRA1(CLK_INFRA_DRAMC_F26M, CLK_TOP_CLK26M, 31),
+ /* INFRA2 */
+ GATE_INFRA2(CLK_INFRA_IRTX, CLK_TOP_CLK26M, 0),
+ GATE_INFRA2(CLK_INFRA_USB, CLK_TOP_MUX_USB_TOP, 1),
+ GATE_INFRA2(CLK_INFRA_DISP_PWM, CLK_TOP_MUX_AXI, 2),
+ GATE_INFRA2(CLK_INFRA_CLDMA_BCLK, CLK_TOP_MUX_AXI, 3),
+ GATE_INFRA2(CLK_INFRA_AUDIO_26M_BCLK, CLK_TOP_CLK26M, 4),
+ GATE_INFRA2(CLK_INFRA_SPI1, CLK_TOP_MUX_SPI, 6),
+ GATE_INFRA2(CLK_INFRA_I2C4, CLK_TOP_MUX_I2C, 7),
+ GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, CLK_TOP_CLK26M, 8),
+ GATE_INFRA2(CLK_INFRA_SPI2, CLK_TOP_MUX_SPI, 9),
+ GATE_INFRA2(CLK_INFRA_SPI3, CLK_TOP_MUX_SPI, 10),
+ GATE_INFRA2(CLK_INFRA_UNIPRO_SCK, CLK_TOP_MUX_SSUSB_TOP_XHCI, 11),
+ GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, CLK_TOP_MUX_FUFS, 12),
+ GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_BCLK, CLK_TOP_MUX_FUFS, 13),
+ GATE_INFRA2(CLK_INFRA_MD32_BCLK, CLK_TOP_MUX_AXI, 14),
+ GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, CLK_TOP_MUX_AXI, 16),
+ GATE_INFRA2(CLK_INFRA_I2C5, CLK_TOP_MUX_I2C, 18),
+ GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, CLK_TOP_MUX_I2C, 19),
+ GATE_INFRA2(CLK_INFRA_I2C5_IMM, CLK_TOP_MUX_I2C, 20),
+ GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, CLK_TOP_MUX_I2C, 21),
+ GATE_INFRA2(CLK_INFRA_I2C1_IMM, CLK_TOP_MUX_I2C, 22),
+ GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, CLK_TOP_MUX_I2C, 23),
+ GATE_INFRA2(CLK_INFRA_I2C2_IMM, CLK_TOP_MUX_I2C, 24),
+ GATE_INFRA2(CLK_INFRA_SPI4, CLK_TOP_MUX_SPI, 25),
+ GATE_INFRA2(CLK_INFRA_SPI5, CLK_TOP_MUX_SPI, 26),
+ GATE_INFRA2(CLK_INFRA_CQ_DMA, CLK_TOP_MUX_AXI, 27),
+ GATE_INFRA2(CLK_INFRA_UFS, CLK_TOP_MUX_FUFS, 28),
+ GATE_INFRA2(CLK_INFRA_AES_UFSFDE, CLK_TOP_MUX_FAES_UFSFDE, 29),
+ GATE_INFRA2(CLK_INFRA_UFS_TICK, CLK_TOP_MUX_FUFS, 30),
+ /* INFRA3 */
+ GATE_INFRA3(CLK_INFRA_MSDC0_SELF, CLK_TOP_MUX_MSDC50_0, 0),
+ GATE_INFRA3(CLK_INFRA_MSDC1_SELF, CLK_TOP_MUX_MSDC50_0, 1),
+ GATE_INFRA3(CLK_INFRA_MSDC2_SELF, CLK_TOP_MUX_MSDC50_0, 2),
+ GATE_INFRA3(CLK_INFRA_UFS_AXI, CLK_TOP_MUX_AXI, 5),
+ GATE_INFRA3(CLK_INFRA_I2C6, CLK_TOP_MUX_I2C, 6),
+ GATE_INFRA3(CLK_INFRA_AP_MSDC0, CLK_TOP_MUX_MSDC50_0_HCLK, 7),
+ GATE_INFRA3(CLK_INFRA_MD_MSDC0, CLK_TOP_MUX_MSDC50_0_HCLK, 8),
+ GATE_INFRA3(CLK_INFRA_CCIF2_AP, CLK_TOP_MUX_AXI, 16),
+ GATE_INFRA3(CLK_INFRA_CCIF2_MD, CLK_TOP_MUX_AXI, 17),
+ GATE_INFRA3(CLK_INFRA_CCIF3_AP, CLK_TOP_MUX_AXI, 18),
+ GATE_INFRA3(CLK_INFRA_CCIF3_MD, CLK_TOP_MUX_AXI, 19),
+ GATE_INFRA3(CLK_INFRA_SEJ_F13M, CLK_TOP_CLK26M, 20),
+ GATE_INFRA3(CLK_INFRA_AES_BCLK, CLK_TOP_MUX_AXI, 21),
+ GATE_INFRA3(CLK_INFRA_I2C7, CLK_TOP_MUX_I2C, 22),
+ GATE_INFRA3(CLK_INFRA_I2C8, CLK_TOP_MUX_I2C, 23),
+ GATE_INFRA3(CLK_INFRA_FBIST2FPC, CLK_TOP_MUX_MSDC50_0, 24),
+};
+
+static int mt8183_apmixedsys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt8183_clk_tree);
+}
+
+static int mt8183_topckgen_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt8183_clk_tree);
+}
+
+static int mt8183_infracfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt8183_clk_tree, infra_clks);
+}
+
+static const struct udevice_id mt8183_apmixed_compat[] = {
+ { .compatible = "mediatek,mt8183-apmixedsys", },
+ { }
+};
+
+static const struct udevice_id mt8183_topckgen_compat[] = {
+ { .compatible = "mediatek,mt8183-topckgen", },
+ { }
+};
+
+static const struct udevice_id mt8183_infracfg_compat[] = {
+ { .compatible = "mediatek,mt8183-infracfg", },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+ .name = "mt8183-apmixedsys",
+ .id = UCLASS_CLK,
+ .of_match = mt8183_apmixed_compat,
+ .probe = mt8183_apmixedsys_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_apmixedsys_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+ .name = "mt8183-topckgen",
+ .id = UCLASS_CLK,
+ .of_match = mt8183_topckgen_compat,
+ .probe = mt8183_topckgen_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+ .name = "mt8183-infracfg",
+ .id = UCLASS_CLK,
+ .of_match = mt8183_infracfg_compat,
+ .probe = mt8183_infracfg_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c873d6976f..7204383e17 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -6,4 +6,5 @@
obj-$(CONFIG_CLK_MESON_GX) += gxbb.o
obj-$(CONFIG_CLK_MESON_AXG) += axg.o
obj-$(CONFIG_CLK_MESON_G12A) += g12a.o
+obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o
diff --git a/drivers/clk/meson/g12a-ao.c b/drivers/clk/meson/g12a-ao.c
new file mode 100644
index 0000000000..0148529e04
--- /dev/null
+++ b/drivers/clk/meson/g12a-ao.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <common.h>
+#include <log.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <dt-bindings/clock/g12a-aoclkc.h>
+
+#include "clk_meson.h"
+
+struct meson_clk {
+ struct regmap *map;
+};
+
+#define AO_CLK_GATE0 0x4c
+#define AO_SAR_CLK 0x90
+
+static struct meson_gate gates[] = {
+ MESON_GATE(CLKID_AO_SAR_ADC, AO_CLK_GATE0, 8),
+ MESON_GATE(CLKID_AO_SAR_ADC_CLK, AO_SAR_CLK, 8),
+};
+
+static int meson_set_gate(struct clk *clk, bool on)
+{
+ struct meson_clk *priv = dev_get_priv(clk->dev);
+ struct meson_gate *gate;
+
+ if (clk->id >= ARRAY_SIZE(gates))
+ return -ENOENT;
+
+ gate = &gates[clk->id];
+
+ if (gate->reg == 0)
+ return 0;
+
+ regmap_update_bits(priv->map, gate->reg,
+ BIT(gate->bit), on ? BIT(gate->bit) : 0);
+
+ return 0;
+}
+
+static int meson_clk_enable(struct clk *clk)
+{
+ return meson_set_gate(clk, true);
+}
+
+static int meson_clk_disable(struct clk *clk)
+{
+ return meson_set_gate(clk, false);
+}
+
+static int meson_clk_probe(struct udevice *dev)
+{
+ struct meson_clk *priv = dev_get_priv(dev);
+
+ priv->map = syscon_node_to_regmap(dev_ofnode(dev_get_parent(dev)));
+ if (IS_ERR(priv->map))
+ return PTR_ERR(priv->map);
+
+ return 0;
+}
+
+static struct clk_ops meson_clk_ops = {
+ .disable = meson_clk_disable,
+ .enable = meson_clk_enable,
+};
+
+static const struct udevice_id meson_clk_ids[] = {
+ { .compatible = "amlogic,meson-g12a-aoclkc" },
+ { }
+};
+
+U_BOOT_DRIVER(meson_clk_axg) = {
+ .name = "meson_clk_g12a_ao",
+ .id = UCLASS_CLK,
+ .of_match = meson_clk_ids,
+ .priv_auto = sizeof(struct meson_clk),
+ .ops = &meson_clk_ops,
+ .probe = meson_clk_probe,
+};
diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig
new file mode 100644
index 0000000000..b70241559d
--- /dev/null
+++ b/drivers/clk/microchip/Kconfig
@@ -0,0 +1,5 @@
+config CLK_MPFS
+ bool "Clock support for Microchip PolarFire SoC"
+ depends on CLK && CLK_CCF
+ help
+ This enables support clock driver for Microchip PolarFire SoC platform.
diff --git a/drivers/clk/microchip/Makefile b/drivers/clk/microchip/Makefile
new file mode 100644
index 0000000000..904b345d75
--- /dev/null
+++ b/drivers/clk/microchip/Makefile
@@ -0,0 +1 @@
+obj-y += mpfs_clk.o mpfs_clk_cfg.o mpfs_clk_periph.o
diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c
new file mode 100644
index 0000000000..722c79b7c0
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <log.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+/* All methods are delegated to CCF clocks */
+
+static ulong mpfs_clk_get_rate(struct clk *clk)
+{
+ struct clk *c;
+ int err = clk_get_by_id(clk->id, &c);
+
+ if (err)
+ return err;
+ return clk_get_rate(c);
+}
+
+static ulong mpfs_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *c;
+ int err = clk_get_by_id(clk->id, &c);
+
+ if (err)
+ return err;
+ return clk_set_rate(c, rate);
+}
+
+static int mpfs_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk *c, *p;
+ int err = clk_get_by_id(clk->id, &c);
+
+ if (err)
+ return err;
+
+ err = clk_get_by_id(parent->id, &p);
+ if (err)
+ return err;
+
+ return clk_set_parent(c, p);
+}
+
+static int mpfs_clk_endisable(struct clk *clk, bool enable)
+{
+ struct clk *c;
+ int err = clk_get_by_id(clk->id, &c);
+
+ if (err)
+ return err;
+ return enable ? clk_enable(c) : clk_disable(c);
+}
+
+static int mpfs_clk_enable(struct clk *clk)
+{
+ return mpfs_clk_endisable(clk, true);
+}
+
+static int mpfs_clk_disable(struct clk *clk)
+{
+ return mpfs_clk_endisable(clk, false);
+}
+
+static int mpfs_clk_probe(struct udevice *dev)
+{
+ int ret;
+ void __iomem *base;
+ u32 clk_rate;
+ const char *parent_clk_name;
+ struct clk *clk = dev_get_priv(dev);
+
+ base = dev_read_addr_ptr(dev);
+ if (!base)
+ return -EINVAL;
+
+ ret = clk_get_by_index(dev, 0, clk);
+ if (ret)
+ return ret;
+
+ dev_read_u32(clk->dev, "clock-frequency", &clk_rate);
+ parent_clk_name = clk->dev->name;
+
+ ret = mpfs_clk_register_cfgs(base, clk_rate, parent_clk_name);
+ if (ret)
+ return ret;
+
+ ret = mpfs_clk_register_periphs(base, clk_rate, "clk_ahb");
+
+ return ret;
+}
+
+static const struct clk_ops mpfs_clk_ops = {
+ .set_rate = mpfs_clk_set_rate,
+ .get_rate = mpfs_clk_get_rate,
+ .set_parent = mpfs_clk_set_parent,
+ .enable = mpfs_clk_enable,
+ .disable = mpfs_clk_disable,
+};
+
+static const struct udevice_id mpfs_of_match[] = {
+ { .compatible = "microchip,mpfs-clkcfg" },
+ { }
+};
+
+U_BOOT_DRIVER(mpfs_clk) = {
+ .name = "mpfs_clk",
+ .id = UCLASS_CLK,
+ .of_match = mpfs_of_match,
+ .ops = &mpfs_clk_ops,
+ .probe = mpfs_clk_probe,
+ .priv_auto = sizeof(struct clk),
+};
diff --git a/drivers/clk/microchip/mpfs_clk.h b/drivers/clk/microchip/mpfs_clk.h
new file mode 100644
index 0000000000..8e3fc55ae3
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#ifndef __MICROCHIP_MPFS_CLK_H
+#define __MICROCHIP_MPFS_CLK_H
+
+#include <linux/clk-provider.h>
+/**
+ * mpfs_clk_register_cfgs() - register configuration clocks
+ *
+ * @base: base address of the mpfs system register.
+ * @clk_rate: the mpfs pll clock rate.
+ * @parent_name: a pointer to parent clock name.
+ * @return zero on success, or a negative error code.
+ */
+int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
+ const char *parent_name);
+/**
+ * mpfs_clk_register_periphs() - register peripheral clocks
+ *
+ * @base: base address of the mpfs system register.
+ * @clk_rate: the mpfs pll clock rate.
+ * @parent_name: a pointer to parent clock name.
+ * @return zero on success, or a negative error code.
+ */
+int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
+ const char *parent_name);
+/**
+ * divider_get_val() - get the clock divider value
+ *
+ * @rate: requested clock rate.
+ * @parent_rate: parent clock rate.
+ * @table: a pointer to clock divider table.
+ * @width: width of the divider bit field.
+ * @flags: common clock framework flags.
+ * @return divider value on success, or a negative error code.
+ */
+int divider_get_val(unsigned long rate, unsigned long parent_rate,
+ const struct clk_div_table *table,
+ u8 width, unsigned long flags);
+
+#endif /* __MICROCHIP_MPFS_CLK_H */
diff --git a/drivers/clk/microchip/mpfs_clk_cfg.c b/drivers/clk/microchip/mpfs_clk_cfg.c
new file mode 100644
index 0000000000..fefddd1413
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk_cfg.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/microchip-mpfs-clock.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+#define MPFS_CFG_CLOCK "mpfs_cfg_clock"
+
+#define REG_CLOCK_CONFIG_CR 0x08
+
+/* CPU and AXI clock divisors */
+static const struct clk_div_table mpfs_div_cpu_axi_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+ { 0, 0 }
+};
+
+/* AHB clock divisors */
+static const struct clk_div_table mpfs_div_ahb_table[] = {
+ { 1, 2 }, { 2, 4}, { 3, 8 },
+ { 0, 0 }
+};
+
+/**
+ * struct mpfs_cfg_clock - per instance of configuration clock
+ * @id: index of a configuration clock
+ * @name: name of a configuration clock
+ * @shift: shift to the divider bit field of a configuration clock
+ * @width: width of the divider bit field of a configation clock
+ * @table: clock divider table instance
+ * @flags: common clock framework flags
+ */
+struct mpfs_cfg_clock {
+ unsigned int id;
+ const char *name;
+ u8 shift;
+ u8 width;
+ const struct clk_div_table *table;
+ unsigned long flags;
+};
+
+/**
+ * struct mpfs_cfg_hw_clock - hardware configuration clock (cpu, axi, ahb)
+ * @cfg: configuration clock instance
+ * @sys_base: base address of the mpfs system register
+ * @prate: the pll clock rate
+ * @hw: clock instance
+ */
+struct mpfs_cfg_hw_clock {
+ struct mpfs_cfg_clock cfg;
+ void __iomem *sys_base;
+ u32 prate;
+ struct clk hw;
+};
+
+#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
+
+static ulong mpfs_cfg_clk_recalc_rate(struct clk *hw)
+{
+ struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+ struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+ void __iomem *base_addr = cfg_hw->sys_base;
+ unsigned long rate;
+ u32 val;
+
+ val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> cfg->shift;
+ val &= clk_div_mask(cfg->width);
+ rate = cfg_hw->prate / (1u << val);
+ hw->rate = rate;
+
+ return rate;
+}
+
+static ulong mpfs_cfg_clk_set_rate(struct clk *hw, ulong rate)
+{
+ struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+ struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+ void __iomem *base_addr = cfg_hw->sys_base;
+ u32 val;
+ int divider_setting;
+
+ divider_setting = divider_get_val(rate, cfg_hw->prate, cfg->table, cfg->width, cfg->flags);
+
+ if (divider_setting < 0)
+ return divider_setting;
+
+ val = readl(base_addr + REG_CLOCK_CONFIG_CR);
+ val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
+ val |= divider_setting << cfg->shift;
+ writel(val, base_addr + REG_CLOCK_CONFIG_CR);
+
+ return clk_get_rate(hw);
+}
+
+#define CLK_CFG(_id, _name, _shift, _width, _table, _flags) { \
+ .cfg.id = _id, \
+ .cfg.name = _name, \
+ .cfg.shift = _shift, \
+ .cfg.width = _width, \
+ .cfg.table = _table, \
+ .cfg.flags = _flags, \
+ }
+
+static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
+ CLK_CFG(CLK_CPU, "clk_cpu", 0, 2, mpfs_div_cpu_axi_table, 0),
+ CLK_CFG(CLK_AXI, "clk_axi", 2, 2, mpfs_div_cpu_axi_table, 0),
+ CLK_CFG(CLK_AHB, "clk_ahb", 4, 2, mpfs_div_ahb_table, 0),
+};
+
+int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
+ const char *parent_name)
+{
+ int ret;
+ int i, id, num_clks;
+ const char *name;
+ struct clk *hw;
+
+ num_clks = ARRAY_SIZE(mpfs_cfg_clks);
+ for (i = 0; i < num_clks; i++) {
+ hw = &mpfs_cfg_clks[i].hw;
+ mpfs_cfg_clks[i].sys_base = base;
+ mpfs_cfg_clks[i].prate = clk_rate;
+ name = mpfs_cfg_clks[i].cfg.name;
+ ret = clk_register(hw, MPFS_CFG_CLOCK, name, parent_name);
+ if (ret)
+ ERR_PTR(ret);
+ id = mpfs_cfg_clks[i].cfg.id;
+ clk_dm(id, hw);
+ }
+ return 0;
+}
+
+const struct clk_ops mpfs_cfg_clk_ops = {
+ .set_rate = mpfs_cfg_clk_set_rate,
+ .get_rate = mpfs_cfg_clk_recalc_rate,
+};
+
+U_BOOT_DRIVER(mpfs_cfg_clock) = {
+ .name = MPFS_CFG_CLOCK,
+ .id = UCLASS_CLK,
+ .ops = &mpfs_cfg_clk_ops,
+};
diff --git a/drivers/clk/microchip/mpfs_clk_periph.c b/drivers/clk/microchip/mpfs_clk_periph.c
new file mode 100644
index 0000000000..61d90eb4a8
--- /dev/null
+++ b/drivers/clk/microchip/mpfs_clk_periph.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/microchip-mpfs-clock.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+#define MPFS_PERIPH_CLOCK "mpfs_periph_clock"
+
+#define REG_CLOCK_CONFIG_CR 0x08
+#define REG_SUBBLK_CLOCK_CR 0x84
+#define REG_SUBBLK_RESET_CR 0x88
+
+#define CFG_CPU_SHIFT 0x0
+#define CFG_AXI_SHIFT 0x2
+#define CFG_AHB_SHIFT 0x4
+#define CFG_WIDTH 0x2
+
+/**
+ * struct mpfs_periph_clock - per instance of peripheral clock
+ * @id: index of a peripheral clock
+ * @name: name of a peripheral clock
+ * @shift: shift to a peripheral clock bit field
+ * @flags: common clock framework flags
+ */
+struct mpfs_periph_clock {
+ unsigned int id;
+ const char *name;
+ u8 shift;
+ unsigned long flags;
+};
+
+/**
+ * struct mpfs_periph_hw_clock - hardware peripheral clock
+ * @periph: peripheral clock instance
+ * @sys_base: base address of the mpfs system register
+ * @prate: the pll clock rate
+ * @hw: clock instance
+ */
+struct mpfs_periph_hw_clock {
+ struct mpfs_periph_clock periph;
+ void __iomem *sys_base;
+ u32 prate;
+ struct clk hw;
+};
+
+#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
+
+static int mpfs_periph_clk_enable(struct clk *hw)
+{
+ struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+ struct mpfs_periph_clock *periph = &periph_hw->periph;
+ void __iomem *base_addr = periph_hw->sys_base;
+ u32 reg, val;
+
+ if (periph->flags != CLK_IS_CRITICAL) {
+ reg = readl(base_addr + REG_SUBBLK_RESET_CR);
+ val = reg & ~(1u << periph->shift);
+ writel(val, base_addr + REG_SUBBLK_RESET_CR);
+
+ reg = readl(base_addr + REG_SUBBLK_CLOCK_CR);
+ val = reg | (1u << periph->shift);
+ writel(val, base_addr + REG_SUBBLK_CLOCK_CR);
+ }
+
+ return 0;
+}
+
+static int mpfs_periph_clk_disable(struct clk *hw)
+{
+ struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+ struct mpfs_periph_clock *periph = &periph_hw->periph;
+ void __iomem *base_addr = periph_hw->sys_base;
+ u32 reg, val;
+
+ if (periph->flags != CLK_IS_CRITICAL) {
+ reg = readl(base_addr + REG_SUBBLK_RESET_CR);
+ val = reg | (1u << periph->shift);
+ writel(val, base_addr + REG_SUBBLK_RESET_CR);
+
+ reg = readl(base_addr + REG_SUBBLK_CLOCK_CR);
+ val = reg & ~(1u << periph->shift);
+ writel(val, base_addr + REG_SUBBLK_CLOCK_CR);
+ }
+
+ return 0;
+}
+
+static ulong mpfs_periph_clk_recalc_rate(struct clk *hw)
+{
+ struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+ void __iomem *base_addr = periph_hw->sys_base;
+ unsigned long rate;
+ u32 val;
+
+ val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> CFG_AHB_SHIFT;
+ val &= clk_div_mask(CFG_WIDTH);
+ rate = periph_hw->prate / (1u << val);
+ hw->rate = rate;
+
+ return rate;
+}
+
+#define CLK_PERIPH(_id, _name, _shift, _flags) { \
+ .periph.id = _id, \
+ .periph.name = _name, \
+ .periph.shift = _shift, \
+ .periph.flags = _flags, \
+ }
+
+static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
+ CLK_PERIPH(CLK_ENVM, "clk_periph_envm", 0, CLK_IS_CRITICAL),
+ CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", 1, 0),
+ CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", 2, 0),
+ CLK_PERIPH(CLK_MMC, "clk_periph_mmc", 3, 0),
+ CLK_PERIPH(CLK_TIMER, "clk_periph_timer", 4, 0),
+ CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", 5, 0),
+ CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", 6, 0),
+ CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", 7, 0),
+ CLK_PERIPH(CLK_MMUART3, "clk_periph_mmuart3", 8, 0),
+ CLK_PERIPH(CLK_MMUART4, "clk_periph_mmuart4", 9, 0),
+ CLK_PERIPH(CLK_SPI0, "clk_periph_spi0", 10, 0),
+ CLK_PERIPH(CLK_SPI1, "clk_periph_spi1", 11, 0),
+ CLK_PERIPH(CLK_I2C0, "clk_periph_i2c0", 12, 0),
+ CLK_PERIPH(CLK_I2C1, "clk_periph_i2c1", 13, 0),
+ CLK_PERIPH(CLK_CAN0, "clk_periph_can0", 14, 0),
+ CLK_PERIPH(CLK_CAN1, "clk_periph_can1", 15, 0),
+ CLK_PERIPH(CLK_USB, "clk_periph_usb", 16, 0),
+ CLK_PERIPH(CLK_RTC, "clk_periph_rtc", 18, 0),
+ CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", 19, 0),
+ CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", 20, 0),
+ CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", 21, 0),
+ CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", 22, 0),
+ CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", 23, CLK_IS_CRITICAL),
+ CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", 24, 0),
+ CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", 25, 0),
+ CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", 26, 0),
+ CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", 27, 0),
+ CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", 28, 0),
+ CLK_PERIPH(CLK_CFM, "clk_periph_cfm", 29, 0),
+};
+
+int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
+ const char *parent_name)
+{
+ int ret;
+ int i, id, num_clks;
+ const char *name;
+ struct clk *hw;
+
+ num_clks = ARRAY_SIZE(mpfs_periph_clks);
+ for (i = 0; i < num_clks; i++) {
+ hw = &mpfs_periph_clks[i].hw;
+ mpfs_periph_clks[i].sys_base = base;
+ mpfs_periph_clks[i].prate = clk_rate;
+ name = mpfs_periph_clks[i].periph.name;
+ ret = clk_register(hw, MPFS_PERIPH_CLOCK, name, parent_name);
+ if (ret)
+ ERR_PTR(ret);
+ id = mpfs_periph_clks[i].periph.id;
+ clk_dm(id, hw);
+ }
+
+ return 0;
+}
+
+const struct clk_ops mpfs_periph_clk_ops = {
+ .enable = mpfs_periph_clk_enable,
+ .disable = mpfs_periph_clk_disable,
+ .get_rate = mpfs_periph_clk_recalc_rate,
+};
+
+U_BOOT_DRIVER(mpfs_periph_clock) = {
+ .name = MPFS_PERIPH_CLOCK,
+ .id = UCLASS_CLK,
+ .ops = &mpfs_periph_clk_ops,
+};
diff --git a/drivers/clk/ti/clk-am3-dpll.c b/drivers/clk/ti/clk-am3-dpll.c
index 7916a24538..90b4cc69ef 100644
--- a/drivers/clk/ti/clk-am3-dpll.c
+++ b/drivers/clk/ti/clk-am3-dpll.c
@@ -260,7 +260,7 @@ U_BOOT_DRIVER(clk_ti_am3_dpll) = {
.name = "ti_am3_dpll_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_am3_dpll_of_match,
- .ofdata_to_platdata = clk_ti_am3_dpll_of_to_plat,
+ .of_to_plat = clk_ti_am3_dpll_of_to_plat,
.probe = clk_ti_am3_dpll_probe,
.remove = clk_ti_am3_dpll_remove,
.priv_auto = sizeof(struct clk_ti_am3_dpll_priv),
diff --git a/drivers/clk/ti/clk-ctrl.c b/drivers/clk/ti/clk-ctrl.c
index 940e8d6caf..3c6195b208 100644
--- a/drivers/clk/ti/clk-ctrl.c
+++ b/drivers/clk/ti/clk-ctrl.c
@@ -148,7 +148,7 @@ U_BOOT_DRIVER(clk_ti_ctrl) = {
.name = "ti_ctrl_clk",
.id = UCLASS_CLK,
.of_match = clk_ti_ctrl_ids,
- .ofdata_to_platdata = clk_ti_ctrl_of_to_plat,
+ .of_to_plat = clk_ti_ctrl_of_to_plat,
.ops = &clk_ti_ctrl_ops,
.priv_auto = sizeof(struct clk_ti_ctrl_priv),
};
diff --git a/drivers/clk/ti/clk-divider.c b/drivers/clk/ti/clk-divider.c
index a862637785..270f2fbdf0 100644
--- a/drivers/clk/ti/clk-divider.c
+++ b/drivers/clk/ti/clk-divider.c
@@ -373,7 +373,7 @@ U_BOOT_DRIVER(clk_ti_divider) = {
.name = "ti_divider_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_divider_of_match,
- .ofdata_to_platdata = clk_ti_divider_of_to_plat,
+ .of_to_plat = clk_ti_divider_of_to_plat,
.probe = clk_ti_divider_probe,
.remove = clk_ti_divider_remove,
.priv_auto = sizeof(struct clk_ti_divider_priv),
diff --git a/drivers/clk/ti/clk-gate.c b/drivers/clk/ti/clk-gate.c
index 236eaed6df..0ca453c8de 100644
--- a/drivers/clk/ti/clk-gate.c
+++ b/drivers/clk/ti/clk-gate.c
@@ -87,7 +87,7 @@ U_BOOT_DRIVER(clk_ti_gate) = {
.name = "ti_gate_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_gate_of_match,
- .ofdata_to_platdata = clk_ti_gate_of_to_plat,
+ .of_to_plat = clk_ti_gate_of_to_plat,
.priv_auto = sizeof(struct clk_ti_gate_priv),
.ops = &clk_ti_gate_ops,
};
diff --git a/drivers/clk/ti/clk-mux.c b/drivers/clk/ti/clk-mux.c
index 419502c389..bb5e49e114 100644
--- a/drivers/clk/ti/clk-mux.c
+++ b/drivers/clk/ti/clk-mux.c
@@ -245,7 +245,7 @@ U_BOOT_DRIVER(clk_ti_mux) = {
.name = "ti_mux_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_mux_of_match,
- .ofdata_to_platdata = clk_ti_mux_of_to_plat,
+ .of_to_plat = clk_ti_mux_of_to_plat,
.probe = clk_ti_mux_probe,
.remove = clk_ti_mux_remove,
.priv_auto = sizeof(struct clk_ti_mux_priv),