summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Kconfig12
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/clk-renesas-pcie.c327
-rw-r--r--drivers/clk/mediatek/clk-mt7622.c239
-rw-r--r--drivers/clk/mediatek/clk-mt7623.c127
-rw-r--r--drivers/clk/mediatek/clk-mt7629.c195
-rw-r--r--drivers/clk/mediatek/clk-mt7981.c126
-rw-r--r--drivers/clk/mediatek/clk-mt7986.c69
-rw-r--r--drivers/clk/mediatek/clk-mt7987.c70
-rw-r--r--drivers/clk/mediatek/clk-mt7988.c144
-rw-r--r--drivers/clk/mediatek/clk-mt8183.c63
-rw-r--r--drivers/clk/mediatek/clk-mt8188.c551
-rw-r--r--drivers/clk/mediatek/clk-mt8189.c112
-rw-r--r--drivers/clk/mediatek/clk-mt8195.c52
-rw-r--r--drivers/clk/mediatek/clk-mt8365.c51
-rw-r--r--drivers/clk/mediatek/clk-mt8512.c101
-rw-r--r--drivers/clk/mediatek/clk-mt8516.c65
-rw-r--r--drivers/clk/mediatek/clk-mt8518.c65
-rw-r--r--drivers/clk/mediatek/clk-mtk.c306
-rw-r--r--drivers/clk/mediatek/clk-mtk.h31
-rw-r--r--drivers/clk/renesas/r8a78000-cpg.c4
-rw-r--r--drivers/clk/spacemit/Kconfig23
-rw-r--r--drivers/clk/spacemit/Makefile7
-rw-r--r--drivers/clk/spacemit/clk-k1.c1878
-rw-r--r--drivers/clk/spacemit/clk_common.h79
-rw-r--r--drivers/clk/spacemit/clk_ddn.c93
-rw-r--r--drivers/clk/spacemit/clk_ddn.h53
-rw-r--r--drivers/clk/spacemit/clk_mix.c403
-rw-r--r--drivers/clk/spacemit/clk_mix.h224
-rw-r--r--drivers/clk/spacemit/clk_pll.c157
-rw-r--r--drivers/clk/spacemit/clk_pll.h81
-rw-r--r--drivers/clk/sunxi/clk_a523.c1
32 files changed, 4609 insertions, 1102 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e69b0543817..47da49c8314 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -215,6 +215,13 @@ config CLK_HSDK
Enable this to support the cgu clocks on Synopsys ARC HSDK and
Synopsys ARC HSDK-4xD boards
+config CLK_RS9_PCIE
+ tristate "Clock driver for Renesas 9-series PCIe clock generators"
+ depends on CLK
+ help
+ This driver supports the Renesas 9-series PCIe clock generator
+ models 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ.
+
config CLK_VERSACLOCK
bool "Enable VersaClock 5/6 devices"
depends on CLK
@@ -277,11 +284,12 @@ source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/owl/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/renesas/Kconfig"
-source "drivers/clk/sophgo/Kconfig"
-source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sifive/Kconfig"
+source "drivers/clk/sophgo/Kconfig"
+source "drivers/clk/spacemit/Kconfig"
source "drivers/clk/starfive/Kconfig"
source "drivers/clk/stm32/Kconfig"
+source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/thead/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c37ef75d420..4b241a9240a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -45,9 +45,11 @@ obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
obj-$(CONFIG_CLK_OWL) += owl/
obj-$(CONFIG_CLK_QCOM) += qcom/
obj-$(CONFIG_CLK_RENESAS) += renesas/
+obj-$(CONFIG_$(PHASE_)CLK_RS9_PCIE) += clk-renesas-pcie.o
obj-$(CONFIG_$(PHASE_)CLK_SCMI) += clk_scmi.o
obj-$(CONFIG_CLK_SIFIVE) += sifive/
obj-$(CONFIG_CLK_SOPHGO) += sophgo/
+obj-$(CONFIG_CLK_SPACEMIT) += spacemit/
obj-$(CONFIG_CLK_SUNXI) += sunxi/
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o
diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
new file mode 100644
index 00000000000..ad57cd4fd28
--- /dev/null
+++ b/drivers/clk/clk-renesas-pcie.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for Renesas 9-series PCIe clock generator driver
+ *
+ * The following series can be supported:
+ * - 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ
+ * Currently supported:
+ * - 9FGV0241
+ * - 9FGV0441
+ * - 9FGV0841
+ *
+ * Copyright (C) 2022-2026 Marek Vasut
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <errno.h>
+#include <i2c.h>
+#include <linux/bitops.h>
+
+#define RS9_REG_OE 0x0
+#define RS9_REG_SS 0x1
+#define RS9_REG_SS_AMP_0V6 0x0
+#define RS9_REG_SS_AMP_0V7 0x1
+#define RS9_REG_SS_AMP_0V8 0x2
+#define RS9_REG_SS_AMP_0V9 0x3
+#define RS9_REG_SS_AMP_DEFAULT RS9_REG_SS_AMP_0V8
+#define RS9_REG_SS_AMP_MASK 0x3
+#define RS9_REG_SS_SSC_100 0
+#define RS9_REG_SS_SSC_M025 (1 << 3)
+#define RS9_REG_SS_SSC_M050 (3 << 3)
+#define RS9_REG_SS_SSC_DEFAULT RS9_REG_SS_SSC_100
+#define RS9_REG_SS_SSC_MASK (3 << 3)
+#define RS9_REG_SS_SSC_LOCK BIT(5)
+#define RS9_REG_SR 0x2
+#define RS9_REG_REF 0x3
+#define RS9_REG_REF_OE BIT(4)
+#define RS9_REG_REF_OD BIT(5)
+#define RS9_REG_REF_SR_SLOWEST 0
+#define RS9_REG_REF_SR_SLOW (1 << 6)
+#define RS9_REG_REF_SR_FAST (2 << 6)
+#define RS9_REG_REF_SR_FASTER (3 << 6)
+#define RS9_REG_VID 0x5
+#define RS9_REG_DID 0x6
+#define RS9_REG_BCP 0x7
+
+#define RS9_REG_VID_MASK GENMASK(3, 0)
+#define RS9_REG_VID_IDT 0x01
+
+#define RS9_REG_DID_TYPE_FGV (0x0 << RS9_REG_DID_TYPE_SHIFT)
+#define RS9_REG_DID_TYPE_DBV (0x1 << RS9_REG_DID_TYPE_SHIFT)
+#define RS9_REG_DID_TYPE_DMV (0x2 << RS9_REG_DID_TYPE_SHIFT)
+#define RS9_REG_DID_TYPE_SHIFT 0x6
+
+/* Structure to describe features of a particular 9-series model */
+struct rs9_chip_info {
+ unsigned int num_clks;
+ u8 outshift;
+ u8 did;
+};
+
+struct rs9_driver_data {
+ struct udevice *i2c;
+ struct rs9_chip_info *chip_info;
+ unsigned long rate;
+ u8 pll_amplitude;
+ u8 pll_ssc;
+ u8 clk_dif_sr;
+};
+
+static int clk_rs9_request(struct clk *clk)
+{
+ struct rs9_driver_data *rs9 = dev_get_priv(clk->dev);
+
+ if (clk->id > rs9->chip_info->num_clks)
+ return -EINVAL;
+
+ return 0;
+}
+
+static ulong clk_rs9_get_rate(struct clk *clk)
+{
+ struct rs9_driver_data *rs9 = dev_get_priv(clk->dev);
+
+ return rs9->rate * 4;
+}
+
+static const struct clk_ops clk_rs9_ops = {
+ .request = clk_rs9_request,
+ .get_rate = clk_rs9_get_rate,
+};
+
+static int rs9_write(struct udevice *dev, u8 reg, u8 val)
+{
+ u8 data[2] = { 1, val };
+
+ return dm_i2c_write(dev, reg, data, 2);
+}
+
+static int rs9_read(struct udevice *dev, u8 reg, u8 *val)
+{
+ struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
+ struct i2c_msg xfer[2];
+ u8 txdata = reg;
+ u8 rxdata[2];
+ int ret;
+
+ xfer[0].addr = chip->chip_addr;
+ xfer[0].flags = 0;
+ xfer[0].len = 1;
+ xfer[0].buf = (void *)&txdata;
+
+ xfer[1].addr = chip->chip_addr;
+ xfer[1].flags = I2C_M_RD;
+ xfer[1].len = 2;
+ xfer[1].buf = (void *)rxdata;
+
+ ret = dm_i2c_xfer(dev, xfer, 2);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Byte 0 is transfer length, which is always 1 due
+ * to BCP register programming to 1 in rs9_probe(),
+ * ignore it and use data from Byte 1.
+ */
+ *val = rxdata[1];
+ return 0;
+}
+
+static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
+{
+ /*
+ * On 9FGV0241, the DIF OE0 is BIT(1) and DIF OE(1) is BIT(2),
+ * on 9FGV0441 and 9FGV0841 the DIF OE0 is BIT(0) and so on.
+ * Increment the index in the 9FGV0241 special case here.
+ */
+ return BIT(idx + rs9->chip_info->outshift);
+}
+
+static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
+{
+ struct udevice *dev = rs9->i2c;
+ u8 dif = rs9_calc_dif(rs9, idx);
+ unsigned char name[5] = "DIF0";
+ ofnode np;
+ u32 sr;
+
+ /* Set defaults */
+ rs9->clk_dif_sr |= dif;
+
+ snprintf(name, 5, "DIF%d", idx);
+ np = dev_read_subnode(dev, name);
+ if (!ofnode_valid(np))
+ return 0;
+
+ /* Output clock slew rate */
+ sr = ofnode_read_u32_default(np, "renesas,slew-rate", 3000000);
+ if (sr == 2000000) { /* 2V/ns */
+ rs9->clk_dif_sr &= ~dif;
+ } else if (sr == 3000000) { /* 3V/ns (default) */
+ rs9->clk_dif_sr |= dif;
+ } else {
+ dev_err(dev, "Invalid renesas,slew-rate value\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rs9_get_common_config(struct rs9_driver_data *rs9)
+{
+ struct udevice *dev = rs9->i2c;
+ unsigned int amp, ssc;
+
+ /* Set defaults */
+ rs9->pll_amplitude = RS9_REG_SS_AMP_DEFAULT;
+ rs9->pll_ssc = RS9_REG_SS_SSC_DEFAULT;
+
+ /* Output clock amplitude */
+ amp = dev_read_u32_default(dev, "renesas,out-amplitude-microvolt", 700000);
+ if (amp == 600000) { /* 0.6V */
+ rs9->pll_amplitude = RS9_REG_SS_AMP_0V6;
+ } else if (amp == 700000) { /* 0.7V (default) */
+ rs9->pll_amplitude = RS9_REG_SS_AMP_0V7;
+ } else if (amp == 800000) { /* 0.8V */
+ rs9->pll_amplitude = RS9_REG_SS_AMP_0V8;
+ } else if (amp == 900000) { /* 0.9V */
+ rs9->pll_amplitude = RS9_REG_SS_AMP_0V9;
+ } else {
+ dev_err(dev, "Invalid renesas,out-amplitude-microvolt value\n");
+ return -EINVAL;
+ }
+
+ /* Output clock spread spectrum */
+ ssc = dev_read_u32_default(dev, "renesas,out-spread-spectrum", 100000);
+ if (ssc == 100000) { /* 100% ... no spread (default) */
+ rs9->pll_ssc = RS9_REG_SS_SSC_100;
+ } else if (ssc == 99750) { /* -0.25% ... down spread */
+ rs9->pll_ssc = RS9_REG_SS_SSC_M025;
+ } else if (ssc == 99500) { /* -0.50% ... down spread */
+ rs9->pll_ssc = RS9_REG_SS_SSC_M050;
+ } else {
+ dev_err(dev, "Invalid renesas,out-spread-spectrum value\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void rs9_update_config(struct rs9_driver_data *rs9)
+{
+ struct udevice *dev = rs9->i2c;
+ int i;
+
+ /* If amplitude is non-default, update it. */
+ if (rs9->pll_amplitude != RS9_REG_SS_AMP_DEFAULT) {
+ dm_i2c_reg_clrset(dev, RS9_REG_SS, RS9_REG_SS_AMP_MASK,
+ rs9->pll_amplitude);
+ }
+
+ /* If SSC is non-default, update it. */
+ if (rs9->pll_ssc != RS9_REG_SS_SSC_DEFAULT) {
+ dm_i2c_reg_clrset(dev, RS9_REG_SS, RS9_REG_SS_SSC_MASK,
+ rs9->pll_ssc);
+ }
+
+ for (i = 0; i < rs9->chip_info->num_clks; i++) {
+ u8 dif = rs9_calc_dif(rs9, i);
+
+ if (rs9->clk_dif_sr & dif)
+ continue;
+
+ dm_i2c_reg_clrset(dev, RS9_REG_SR, dif,
+ rs9->clk_dif_sr & dif);
+ }
+}
+
+static int clk_rs9_probe(struct udevice *dev)
+{
+ struct rs9_driver_data *rs9 = dev_get_priv(dev);
+ struct clk *clk;
+ u8 vid, did;
+ int i, ret;
+
+ rs9->i2c = dev;
+ rs9->chip_info = (struct rs9_chip_info *)dev_get_driver_data(dev);
+ if (!rs9->chip_info)
+ return -EINVAL;
+
+ clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ rs9->rate = clk_get_rate(clk);
+
+ /* Fetch common configuration from DT (if specified) */
+ ret = rs9_get_common_config(rs9);
+ if (ret)
+ return ret;
+
+ /* Fetch DIFx output configuration from DT (if specified) */
+ for (i = 0; i < rs9->chip_info->num_clks; i++) {
+ ret = rs9_get_output_config(rs9, i);
+ if (ret)
+ return ret;
+ }
+
+ /* Always read back 1 Byte via I2C */
+ ret = rs9_write(dev, RS9_REG_BCP, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = rs9_read(dev, RS9_REG_VID, &vid);
+ if (ret < 0)
+ return ret;
+
+ ret = rs9_read(dev, RS9_REG_DID, &did);
+ if (ret < 0)
+ return ret;
+
+ vid &= RS9_REG_VID_MASK;
+ if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did) {
+ dev_err(dev, "Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n",
+ vid, did, RS9_REG_VID_IDT, rs9->chip_info->did);
+ return -ENODEV;
+ }
+
+ rs9_update_config(rs9);
+
+ return 0;
+}
+
+static const struct rs9_chip_info renesas_9fgv0241_info = {
+ .num_clks = 2,
+ .outshift = 1,
+ .did = RS9_REG_DID_TYPE_FGV | 0x02,
+};
+
+static const struct rs9_chip_info renesas_9fgv0441_info = {
+ .num_clks = 4,
+ .outshift = 0,
+ .did = RS9_REG_DID_TYPE_FGV | 0x04,
+};
+
+static const struct rs9_chip_info renesas_9fgv0841_info = {
+ .num_clks = 8,
+ .outshift = 0,
+ .did = RS9_REG_DID_TYPE_FGV | 0x08,
+};
+
+static const struct udevice_id clk_rs9_of_match[] = {
+ { .compatible = "renesas,9fgv0241", .data = (ulong)&renesas_9fgv0241_info },
+ { .compatible = "renesas,9fgv0441", .data = (ulong)&renesas_9fgv0441_info },
+ { .compatible = "renesas,9fgv0841", .data = (ulong)&renesas_9fgv0841_info },
+ { /* sentinel */ },
+};
+
+U_BOOT_DRIVER(clk_rs9) = {
+ .name = "clk-renesas-pcie-9series",
+ .id = UCLASS_CLK,
+ .of_match = clk_rs9_of_match,
+ .ops = &clk_rs9_ops,
+ .probe = clk_rs9_probe,
+ .priv_auto = sizeof(struct rs9_driver_data),
+};
diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c
index 79315912fd4..d66200f1938 100644
--- a/drivers/clk/mediatek/clk-mt7622.c
+++ b/drivers/clk/mediatek/clk-mt7622.c
@@ -85,7 +85,7 @@ static const struct mtk_gate_regs apmixed_cg_regs = {
.parent = _parent, \
.regs = &apmixed_cg_regs, \
.shift = _shift, \
- .flags = CLK_GATE_NO_SETCLR_INV, \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_APMIXED, \
}
static const struct mtk_gate apmixed_cgs[] = {
@@ -613,6 +613,21 @@ static const struct mtk_clk_tree mt7622_apmixed_clk_tree = {
.gates = apmixed_cgs,
.num_plls = ARRAY_SIZE(apmixed_plls),
.num_gates = ARRAY_SIZE(apmixed_cgs),
+ .type = MTK_CLK_TREE_APMIXED,
+};
+
+static const struct mtk_clk_tree mt7622_topckgen_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .fdivs_offs = CLK_TOP_TO_USB3_SYS,
+ .muxes_offs = CLK_TOP_AXI_SEL,
+ .fclks = top_fixed_clks,
+ .fdivs = top_fixed_divs,
+ .muxes = top_muxes,
+ .num_fclks = ARRAY_SIZE(top_fixed_clks),
+ .num_fdivs = ARRAY_SIZE(top_fixed_divs),
+ .num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_clk_tree mt7622_infra_clk_tree = {
@@ -637,17 +652,32 @@ static const struct mtk_clk_tree mt7622_peri_clk_tree = {
.num_gates = ARRAY_SIZE(peri_cgs),
};
-static const struct mtk_clk_tree mt7622_clk_tree = {
+static const struct mtk_clk_tree mt7622_pcie_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
- .fdivs_offs = CLK_TOP_TO_USB3_SYS,
- .muxes_offs = CLK_TOP_AXI_SEL,
- .fclks = top_fixed_clks,
- .fdivs = top_fixed_divs,
- .muxes = top_muxes,
- .num_fclks = ARRAY_SIZE(top_fixed_clks),
- .num_fdivs = ARRAY_SIZE(top_fixed_divs),
- .num_muxes = ARRAY_SIZE(top_muxes),
+ .gates = pcie_cgs,
+ .num_gates = ARRAY_SIZE(pcie_cgs),
+};
+
+static const struct mtk_clk_tree mt7622_eth_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = eth_cgs,
+ .num_gates = ARRAY_SIZE(eth_cgs),
+};
+
+static const struct mtk_clk_tree mt7622_sgmii_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = sgmii_cgs,
+ .num_gates = ARRAY_SIZE(sgmii_cgs),
+};
+
+static const struct mtk_clk_tree mt7622_ssusb_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = ssusb_cgs,
+ .num_gates = ARRAY_SIZE(ssusb_cgs),
};
static int mt7622_mcucfg_probe(struct udevice *dev)
@@ -671,7 +701,7 @@ static int mt7622_apmixedsys_probe(struct udevice *dev)
struct mtk_clk_priv *priv = dev_get_priv(dev);
int ret;
- ret = mtk_common_clk_init(dev, &mt7622_apmixed_clk_tree);
+ ret = mtk_clk_probe(dev);
if (ret)
return ret;
@@ -685,103 +715,68 @@ static int mt7622_apmixedsys_probe(struct udevice *dev)
return 0;
}
-static int mt7622_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7622_clk_tree);
-}
-
-static int mt7622_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7622_infra_clk_tree);
-}
-
-static int mt7622_pericfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7622_peri_clk_tree);
-}
-
-static int mt7622_pciesys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, pcie_cgs,
- ARRAY_SIZE(pcie_cgs), 0);
-}
-
-static int mt7622_pciesys_bind(struct udevice *dev)
+static int mt7622_reset_bind(struct udevice *dev)
{
int ret = 0;
- if (IS_ENABLED(CONFIG_RESET_MEDIATEK)) {
- ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
- if (ret)
- debug("Warning: failed to bind reset controller\n");
+ if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) {
+ ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
+ if (ret)
+ debug("Warning: failed to bind reset controller\n");
}
return ret;
}
-static int mt7622_ethsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, eth_cgs,
- ARRAY_SIZE(eth_cgs), 0);
-}
-
-static int mt7622_ethsys_bind(struct udevice *dev)
-{
- int ret = 0;
-
-#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
- ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
- if (ret)
- debug("Warning: failed to bind reset controller\n");
-#endif
-
- return ret;
-}
-
-static int mt7622_sgmiisys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, sgmii_cgs,
- ARRAY_SIZE(sgmii_cgs), 0);
-}
-
-static int mt7622_ssusbsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7622_clk_tree, ssusb_cgs,
- ARRAY_SIZE(ssusb_cgs), 0);
-}
-
static const struct udevice_id mt7622_apmixed_compat[] = {
- { .compatible = "mediatek,mt7622-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7622-apmixedsys",
+ .data = (ulong)&mt7622_apmixed_clk_tree,
+ },
{ }
};
static const struct udevice_id mt7622_topckgen_compat[] = {
- { .compatible = "mediatek,mt7622-topckgen" },
- { }
-};
-
-static const struct udevice_id mt7622_infracfg_compat[] = {
- { .compatible = "mediatek,mt7622-infracfg", },
- { }
-};
-
-static const struct udevice_id mt7622_pericfg_compat[] = {
- { .compatible = "mediatek,mt7622-pericfg", },
+ {
+ .compatible = "mediatek,mt7622-topckgen",
+ .data = (ulong)&mt7622_topckgen_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt7622_pciesys_compat[] = {
- { .compatible = "mediatek,mt7622-pciesys", },
+static const struct udevice_id of_match_mt7622_infracfg[] = {
+ {
+ .compatible = "mediatek,mt7622-infracfg",
+ .data = (ulong)&mt7622_infra_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7622-pericfg",
+ .data = (ulong)&mt7622_peri_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt7622_ethsys_compat[] = {
- { .compatible = "mediatek,mt7622-ethsys", },
+static const struct udevice_id of_match_mt7622_clk_eth[] = {
+ {
+ .compatible = "mediatek,mt7622-pciesys",
+ .data = (ulong)&mt7622_pcie_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7622-ethsys",
+ .data = (ulong)&mt7622_eth_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt7622_sgmiisys_compat[] = {
- { .compatible = "mediatek,mt7622-sgmiisys", },
+static const struct udevice_id of_match_mt7622_clk[] = {
+ {
+ .compatible = "mediatek,mt7622-sgmiisys",
+ .data = (ulong)&mt7622_sgmii_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7622-ssusbsys",
+ .data = (ulong)&mt7622_ssusb_clk_tree,
+ },
{ }
};
@@ -790,12 +785,7 @@ static const struct udevice_id mt7622_mcucfg_compat[] = {
{ }
};
-static const struct udevice_id mt7622_ssusbsys_compat[] = {
- { .compatible = "mediatek,mt7622-ssusbsys" },
- { }
-};
-
-U_BOOT_DRIVER(mtk_mcucfg) = {
+U_BOOT_DRIVER(mt7622_mcucfg) = {
.name = "mt7622-mcucfg",
.id = UCLASS_SYSCON,
.of_match = mt7622_mcucfg_compat,
@@ -803,7 +793,7 @@ U_BOOT_DRIVER(mtk_mcucfg) = {
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7622_clk_apmixedsys) = {
.name = "mt7622-clock-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt7622_apmixed_compat,
@@ -813,70 +803,41 @@ U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7622_clk_topckgen) = {
.name = "mt7622-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7622_topckgen_compat,
- .probe = mt7622_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7622_clk_infracfg) = {
.name = "mt7622-clock-infracfg",
.id = UCLASS_CLK,
- .of_match = mt7622_infracfg_compat,
- .probe = mt7622_infracfg_probe,
+ .of_match = of_match_mt7622_infracfg,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_pericfg) = {
- .name = "mt7622-clock-pericfg",
+U_BOOT_DRIVER(mt7622_clk_eth) = {
+ .name = "mt7622-clk-eth",
.id = UCLASS_CLK,
- .of_match = mt7622_pericfg_compat,
- .probe = mt7622_pericfg_probe,
+ .of_match = of_match_mt7622_clk_eth,
+ .probe = mtk_clk_probe,
+ .bind = mt7622_reset_bind,
.priv_auto = sizeof(struct mtk_clk_priv),
- .ops = &mtk_clk_infrasys_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_pciesys) = {
- .name = "mt7622-clock-pciesys",
- .id = UCLASS_CLK,
- .of_match = mt7622_pciesys_compat,
- .probe = mt7622_pciesys_probe,
- .bind = mt7622_pciesys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
-};
-
-U_BOOT_DRIVER(mtk_clk_ethsys) = {
- .name = "mt7622-clock-ethsys",
- .id = UCLASS_CLK,
- .of_match = mt7622_ethsys_compat,
- .probe = mt7622_ethsys_probe,
- .bind = mt7622_ethsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
-};
-
-U_BOOT_DRIVER(mtk_clk_sgmiisys) = {
- .name = "mt7622-clock-sgmiisys",
- .id = UCLASS_CLK,
- .of_match = mt7622_sgmiisys_compat,
- .probe = mt7622_sgmiisys_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .ops = &mtk_clk_topckgen_ops,
};
-U_BOOT_DRIVER(mtk_clk_ssusbsys) = {
- .name = "mt7622-clock-ssusbsys",
+U_BOOT_DRIVER(mt7622_clk) = {
+ .name = "mt7622-clk",
.id = UCLASS_CLK,
- .of_match = mt7622_ssusbsys_compat,
- .probe = mt7622_ssusbsys_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt7622_clk,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
index 0a302b405e2..cc075495b09 100644
--- a/drivers/clk/mediatek/clk-mt7623.c
+++ b/drivers/clk/mediatek/clk-mt7623.c
@@ -1009,6 +1009,7 @@ static const struct mtk_clk_tree mt7623_apmixedsys_clk_tree = {
.id_offs_map_size = ARRAY_SIZE(pll_id_offs_map),
.plls = apmixed_plls,
.num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
};
static const struct mtk_clk_tree mt7623_topckgen_clk_tree = {
@@ -1024,6 +1025,7 @@ static const struct mtk_clk_tree mt7623_topckgen_clk_tree = {
.num_fclks = ARRAY_SIZE(top_fixed_clks),
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static int mt7623_mcucfg_probe(struct udevice *dev)
@@ -1045,7 +1047,7 @@ static int mt7623_apmixedsys_probe(struct udevice *dev)
struct mtk_clk_priv *priv = dev_get_priv(dev);
int ret;
- ret = mtk_common_clk_init(dev, &mt7623_apmixedsys_clk_tree);
+ ret = mtk_clk_probe(dev);
if (ret)
return ret;
@@ -1057,21 +1059,29 @@ static int mt7623_apmixedsys_probe(struct udevice *dev)
return 0;
}
-static int mt7623_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7623_topckgen_clk_tree);
-}
+static const struct mtk_clk_tree mt7623_infracfg_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates_offs = 1,
+ .gates = infra_cgs,
+ .num_gates = ARRAY_SIZE(infra_cgs),
+};
-static const struct mtk_clk_tree mt7623_clk_gate_tree = {
+static const struct mtk_clk_tree mt7623_hifsys_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates_offs = 1,
+ .gates = hif_cgs,
+ .num_gates = ARRAY_SIZE(hif_cgs),
};
-static int mt7623_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7623_clk_gate_tree, infra_cgs,
- ARRAY_SIZE(infra_cgs), 1);
-}
+static const struct mtk_clk_tree mt7623_ethsys_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates_offs = 1,
+ .gates = eth_cgs,
+ .num_gates = ARRAY_SIZE(eth_cgs),
+};
static const struct mtk_clk_tree mt7623_clk_peri_tree = {
.ext_clk_rates = ext_clock_rates,
@@ -1086,23 +1096,6 @@ static const struct mtk_clk_tree mt7623_clk_peri_tree = {
.num_gates = ARRAY_SIZE(peri_cgs),
};
-static int mt7623_pericfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7623_clk_peri_tree);
-}
-
-static int mt7623_hifsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7623_clk_gate_tree, hif_cgs,
- ARRAY_SIZE(hif_cgs), 1);
-}
-
-static int mt7623_ethsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7623_clk_gate_tree, eth_cgs,
- ARRAY_SIZE(eth_cgs), 1);
-}
-
static int mt7623_ethsys_hifsys_bind(struct udevice *dev)
{
int ret = 0;
@@ -1117,32 +1110,46 @@ static int mt7623_ethsys_hifsys_bind(struct udevice *dev)
}
static const struct udevice_id mt7623_apmixed_compat[] = {
- { .compatible = "mediatek,mt7623-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7623-apmixedsys",
+ .data = (ulong)&mt7623_apmixedsys_clk_tree,
+ },
{ }
};
static const struct udevice_id mt7623_topckgen_compat[] = {
- { .compatible = "mediatek,mt7623-topckgen" },
+ {
+ .compatible = "mediatek,mt7623-topckgen",
+ .data = (ulong)&mt7623_topckgen_clk_tree,
+ },
{ }
};
static const struct udevice_id mt7623_infracfg_compat[] = {
- { .compatible = "mediatek,mt7623-infracfg", },
+ {
+ .compatible = "mediatek,mt7623-infracfg",
+ .data = (ulong)&mt7623_infracfg_tree,
+ },
{ }
};
static const struct udevice_id mt7623_pericfg_compat[] = {
- { .compatible = "mediatek,mt7623-pericfg", },
+ {
+ .compatible = "mediatek,mt7623-pericfg",
+ .data = (ulong)&mt7623_clk_peri_tree,
+ },
{ }
};
-static const struct udevice_id mt7623_ethsys_compat[] = {
- { .compatible = "mediatek,mt7623-ethsys" },
- { }
-};
-
-static const struct udevice_id mt7623_hifsys_compat[] = {
- { .compatible = "mediatek,mt7623-hifsys" },
+static const struct udevice_id of_match_mt7623_clk_eth[] = {
+ {
+ .compatible = "mediatek,mt7623-ethsys",
+ .data = (ulong)&mt7623_ethsys_tree,
+ },
+ {
+ .compatible = "mediatek,mt7623-hifsys",
+ .data = (ulong)&mt7623_hifsys_tree,
+ },
{ }
};
@@ -1151,7 +1158,7 @@ static const struct udevice_id mt7623_mcucfg_compat[] = {
{ }
};
-U_BOOT_DRIVER(mtk_mcucfg) = {
+U_BOOT_DRIVER(mt7623_mcucfg) = {
.name = "mt7623-mcucfg",
.id = UCLASS_SYSCON,
.of_match = mt7623_mcucfg_compat,
@@ -1159,7 +1166,7 @@ U_BOOT_DRIVER(mtk_mcucfg) = {
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7623_clk_apmixedsys) = {
.name = "mt7623-clock-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt7623_apmixed_compat,
@@ -1169,52 +1176,42 @@ U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7623_clk_topckgen) = {
.name = "mt7623-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7623_topckgen_compat,
- .probe = mt7623_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7623_clk_infracfg) = {
.name = "mt7623-infracfg",
.id = UCLASS_CLK,
.of_match = mt7623_infracfg_compat,
- .probe = mt7623_infracfg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_pericfg) = {
+U_BOOT_DRIVER(mt7623_clk_pericfg) = {
.name = "mt7623-pericfg",
.id = UCLASS_CLK,
.of_match = mt7623_pericfg_compat,
- .probe = mt7623_pericfg_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_hifsys) = {
- .name = "mt7623-clock-hifsys",
+U_BOOT_DRIVER(mt7623_clk_eth) = {
+ .name = "mt7623-clk-eth",
.id = UCLASS_CLK,
- .of_match = mt7623_hifsys_compat,
- .probe = mt7623_hifsys_probe,
+ .of_match = of_match_mt7623_clk_eth,
+ .probe = mtk_clk_probe,
.bind = mt7623_ethsys_hifsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
-};
-
-U_BOOT_DRIVER(mtk_clk_ethsys) = {
- .name = "mt7623-clock-ethsys",
- .id = UCLASS_CLK,
- .of_match = mt7623_ethsys_compat,
- .probe = mt7623_ethsys_probe,
- .bind = mt7623_ethsys_hifsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
index 74510ee36a9..b271b96ebf3 100644
--- a/drivers/clk/mediatek/clk-mt7629.c
+++ b/drivers/clk/mediatek/clk-mt7629.c
@@ -575,36 +575,64 @@ static const struct mtk_gate ssusb_cgs[] = {
GATE_SSUSB(CLK_SSUSB_DMA_EN, CLK_TOP_TO_USB3_DMA, 8),
};
-static const struct mtk_clk_tree mt7629_clk_tree = {
+static const struct mtk_clk_tree mt7629_apmixed_clk_tree = {
.pll_parent = EXT_PARENT(CLK_PAD_CLK20M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
- .fdivs_offs = CLK_TOP_TO_USB3_SYS,
- .muxes_offs = CLK_TOP_AXI_SEL,
.plls = apmixed_plls,
- .fclks = top_fixed_clks,
- .fdivs = top_fixed_divs,
- .muxes = top_muxes,
.num_plls = ARRAY_SIZE(apmixed_plls),
- .num_fclks = ARRAY_SIZE(top_fixed_clks),
- .num_fdivs = ARRAY_SIZE(top_fixed_divs),
- .num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_APMIXED,
};
-static const struct mtk_clk_tree mt7629_peri_clk_tree = {
- .pll_parent = EXT_PARENT(CLK_PAD_CLK20M),
+static const struct mtk_clk_tree mt7629_topckgen_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_TO_USB3_SYS,
.muxes_offs = CLK_TOP_AXI_SEL,
- .plls = apmixed_plls,
.fclks = top_fixed_clks,
.fdivs = top_fixed_divs,
.muxes = top_muxes,
- .num_plls = ARRAY_SIZE(apmixed_plls),
.num_fclks = ARRAY_SIZE(top_fixed_clks),
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
+};
+
+static const struct mtk_clk_tree mt7629_infracfg_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates_offs = CLK_INFRA_DBGCLK_PD,
+ .gates = infra_cgs,
+ .num_gates = ARRAY_SIZE(infra_cgs),
+};
+
+static const struct mtk_clk_tree mt7629_pericfg_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates_offs = CLK_PERI_PWM1_PD,
+ .gates = peri_cgs,
+ .num_gates = ARRAY_SIZE(peri_cgs),
+};
+
+static const struct mtk_clk_tree mt7629_ethsys_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = eth_cgs,
+ .num_gates = ARRAY_SIZE(eth_cgs),
+};
+
+static const struct mtk_clk_tree mt7629_sgmii_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = sgmii_cgs,
+ .num_gates = ARRAY_SIZE(sgmii_cgs),
+};
+
+static const struct mtk_clk_tree mt7629_ssusb_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = ssusb_cgs,
+ .num_gates = ARRAY_SIZE(ssusb_cgs),
};
static int mt7629_mcucfg_probe(struct udevice *dev)
@@ -628,7 +656,7 @@ static int mt7629_apmixedsys_probe(struct udevice *dev)
struct mtk_clk_priv *priv = dev_get_priv(dev);
int ret;
- ret = mtk_common_clk_init(dev, &mt7629_clk_tree);
+ ret = mtk_clk_probe(dev);
if (ret)
return ret;
@@ -640,29 +668,6 @@ static int mt7629_apmixedsys_probe(struct udevice *dev)
return 0;
}
-static int mt7629_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7629_clk_tree);
-}
-
-static int mt7629_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, infra_cgs,
- ARRAY_SIZE(infra_cgs), 0);
-}
-
-static int mt7629_pericfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7629_peri_clk_tree, peri_cgs,
- ARRAY_SIZE(peri_cgs), CLK_PERI_PWM1_PD);
-}
-
-static int mt7629_ethsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs,
- ARRAY_SIZE(eth_cgs), 0);
-}
-
static int mt7629_ethsys_bind(struct udevice *dev)
{
int ret = 0;
@@ -676,50 +681,51 @@ static int mt7629_ethsys_bind(struct udevice *dev)
return ret;
}
-static int mt7629_sgmiisys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs,
- ARRAY_SIZE(sgmii_cgs), 0);
-}
-
-static int mt7629_ssusbsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, ssusb_cgs,
- ARRAY_SIZE(ssusb_cgs), 0);
-}
-
static const struct udevice_id mt7629_apmixed_compat[] = {
- { .compatible = "mediatek,mt7629-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7629-apmixedsys",
+ .data = (ulong)&mt7629_apmixed_clk_tree,
+ },
{ }
};
static const struct udevice_id mt7629_topckgen_compat[] = {
- { .compatible = "mediatek,mt7629-topckgen" },
+ {
+ .compatible = "mediatek,mt7629-topckgen",
+ .data = (ulong)&mt7629_topckgen_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt7629_infracfg_compat[] = {
- { .compatible = "mediatek,mt7629-infracfg", },
- { }
-};
-
-static const struct udevice_id mt7629_pericfg_compat[] = {
- { .compatible = "mediatek,mt7629-pericfg", },
+static const struct udevice_id of_match_mt7629_infracfg[] = {
+ {
+ .compatible = "mediatek,mt7629-infracfg",
+ .data = (ulong)&mt7629_infracfg_tree,
+ },
+ {
+ .compatible = "mediatek,mt7629-pericfg",
+ .data = (ulong)&mt7629_pericfg_tree,
+ },
{ }
};
static const struct udevice_id mt7629_ethsys_compat[] = {
- { .compatible = "mediatek,mt7629-ethsys", },
- { }
-};
-
-static const struct udevice_id mt7629_sgmiisys_compat[] = {
- { .compatible = "mediatek,mt7629-sgmiisys", },
+ {
+ .compatible = "mediatek,mt7629-ethsys",
+ .data = (ulong)&mt7629_ethsys_tree,
+ },
{ }
};
-static const struct udevice_id mt7629_ssusbsys_compat[] = {
- { .compatible = "mediatek,mt7629-ssusbsys" },
+static const struct udevice_id of_match_mt7629_clk[] = {
+ {
+ .compatible = "mediatek,mt7629-sgmiisys",
+ .data = (ulong)&mt7629_sgmii_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7629-ssusbsys",
+ .data = (ulong)&mt7629_ssusb_clk_tree,
+ },
{ }
};
@@ -728,7 +734,7 @@ static const struct udevice_id mt7629_mcucfg_compat[] = {
{ }
};
-U_BOOT_DRIVER(mtk_mcucfg) = {
+U_BOOT_DRIVER(mt7629_mcucfg) = {
.name = "mt7629-mcucfg",
.id = UCLASS_SYSCON,
.of_match = mt7629_mcucfg_compat,
@@ -736,7 +742,7 @@ U_BOOT_DRIVER(mtk_mcucfg) = {
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7629_clk_apmixedsys) = {
.name = "mt7629-clock-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt7629_apmixed_compat,
@@ -746,60 +752,41 @@ U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7629_clk_topckgen) = {
.name = "mt7629-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7629_topckgen_compat,
- .probe = mt7629_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7629_clk_infracfg) = {
.name = "mt7629-clock-infracfg",
.id = UCLASS_CLK,
- .of_match = mt7629_infracfg_compat,
- .probe = mt7629_infracfg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_pericfg) = {
- .name = "mt7629-clock-pericfg",
- .id = UCLASS_CLK,
- .of_match = mt7629_pericfg_compat,
- .probe = mt7629_pericfg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt7629_infracfg,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_ethsys) = {
+U_BOOT_DRIVER(mt7629_clk_ethsys) = {
.name = "mt7629-clock-ethsys",
.id = UCLASS_CLK,
.of_match = mt7629_ethsys_compat,
- .probe = mt7629_ethsys_probe,
+ .probe = mtk_clk_probe,
.bind = mt7629_ethsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
-};
-
-U_BOOT_DRIVER(mtk_clk_sgmiisys) = {
- .name = "mt7629-clock-sgmiisys",
- .id = UCLASS_CLK,
- .of_match = mt7629_sgmiisys_compat,
- .probe = mt7629_sgmiisys_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
-U_BOOT_DRIVER(mtk_clk_ssusbsys) = {
- .name = "mt7629-clock-ssusbsys",
+U_BOOT_DRIVER(mt7629_clk) = {
+ .name = "mt7629-clk",
.id = UCLASS_CLK,
- .of_match = mt7629_ssusbsys_compat,
- .probe = mt7629_ssusbsys_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt7629_clk,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7981.c b/drivers/clk/mediatek/clk-mt7981.c
index 8c2944b7fb3..7e3e60477d9 100644
--- a/drivers/clk/mediatek/clk-mt7981.c
+++ b/drivers/clk/mediatek/clk-mt7981.c
@@ -622,6 +622,7 @@ static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = {
.fdivs_offs = CLK_APMIXED_NR_CLK,
.fclks = fixed_pll_clks,
.num_fclks = ARRAY_SIZE(fixed_pll_clks),
+ .type = MTK_CLK_TREE_APMIXED,
};
static const struct mtk_clk_tree mt7981_topckgen_clk_tree = {
@@ -636,6 +637,7 @@ static const struct mtk_clk_tree mt7981_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
.flags = CLK_PARENT_TOPCKGEN,
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_clk_tree mt7981_infracfg_clk_tree = {
@@ -651,24 +653,29 @@ static const struct mtk_clk_tree mt7981_infracfg_clk_tree = {
.num_muxes = ARRAY_SIZE(infra_muxes),
.num_gates = ARRAY_SIZE(infracfg_gates),
.flags = CLK_PARENT_INFRASYS,
+ .type = MTK_CLK_TREE_INFRASYS,
};
static const struct udevice_id mt7981_fixed_pll_compat[] = {
- { .compatible = "mediatek,mt7981-fixed-plls" },
- { .compatible = "mediatek,mt7981-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7981-fixed-plls",
+ .data = (ulong)&mt7981_fixed_pll_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7981-apmixedsys",
+ .data = (ulong)&mt7981_fixed_pll_clk_tree,
+ },
{}
};
static const struct udevice_id mt7981_topckgen_compat[] = {
- { .compatible = "mediatek,mt7981-topckgen" },
+ {
+ .compatible = "mediatek,mt7981-topckgen",
+ .data = (ulong)&mt7981_topckgen_clk_tree,
+ },
{}
};
-static int mt7981_fixed_pll_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree);
-}
-
static int mt7981_topckgen_probe(struct udevice *dev)
{
struct mtk_clk_priv *priv = dev_get_priv(dev);
@@ -676,20 +683,20 @@ static int mt7981_topckgen_probe(struct udevice *dev)
priv->base = dev_read_addr_ptr(dev);
writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN);
- return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree);
+ return mtk_clk_probe(dev);
}
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7981_clk_apmixedsys) = {
.name = "mt7981-clock-fixed-pll",
.id = UCLASS_CLK,
.of_match = mt7981_fixed_pll_compat,
- .probe = mt7981_fixed_pll_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_fixed_pll_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7981_clk_topckgen) = {
.name = "mt7981-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7981_topckgen_compat,
@@ -700,20 +707,18 @@ U_BOOT_DRIVER(mtk_clk_topckgen) = {
};
static const struct udevice_id mt7981_infracfg_compat[] = {
- { .compatible = "mediatek,mt7981-infracfg" },
+ {
+ .compatible = "mediatek,mt7981-infracfg",
+ .data = (ulong)&mt7981_infracfg_clk_tree,
+ },
{}
};
-static int mt7981_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7981_infracfg_clk_tree);
-}
-
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7981_clk_infracfg) = {
.name = "mt7981-clock-infracfg",
.id = UCLASS_CLK,
.of_match = mt7981_infracfg_compat,
- .probe = mt7981_infracfg_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
@@ -740,24 +745,11 @@ static const struct mtk_gate sgmii0_cgs[] = {
GATE_SGMII(CLK_SGM0_CDR_CK0_EN, "sgm0_cdr_ck0_en", CLK_TOP_USB_CDR_CK, 5),
};
-static int mt7981_sgmii0sys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree,
- sgmii0_cgs, ARRAY_SIZE(sgmii0_cgs), 0);
-}
-
-static const struct udevice_id mt7981_sgmii0sys_compat[] = {
- { .compatible = "mediatek,mt7981-sgmiisys_0", },
- {}
-};
-
-U_BOOT_DRIVER(mtk_clk_sgmii0sys) = {
- .name = "mt7981-clock-sgmii0sys",
- .id = UCLASS_CLK,
- .of_match = mt7981_sgmii0sys_compat,
- .probe = mt7981_sgmii0sys_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+static const struct mtk_clk_tree mt7981_sgmii0_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = sgmii0_cgs,
+ .num_gates = ARRAY_SIZE(sgmii0_cgs),
};
static const struct mtk_gate sgmii1_cgs[] = {
@@ -767,24 +759,32 @@ static const struct mtk_gate sgmii1_cgs[] = {
GATE_SGMII(CLK_SGM1_CDR_CK1_EN, "sgm1_cdr_ck1_en", CLK_TOP_USB_CDR_CK, 5),
};
-static int mt7981_sgmii1sys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree,
- sgmii1_cgs, ARRAY_SIZE(sgmii1_cgs), 0);
-}
+static const struct mtk_clk_tree mt7981_sgmii1_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = sgmii1_cgs,
+ .num_gates = ARRAY_SIZE(sgmii1_cgs),
+};
-static const struct udevice_id mt7981_sgmii1sys_compat[] = {
- { .compatible = "mediatek,mt7981-sgmiisys_1", },
+static const struct udevice_id of_match_mt7981_sgmiisys[] = {
+ {
+ .compatible = "mediatek,mt7981-sgmiisys_0",
+ .data = (ulong)&mt7981_sgmii0_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7981-sgmiisys_1",
+ .data = (ulong)&mt7981_sgmii1_clk_tree,
+ },
{}
};
-U_BOOT_DRIVER(mtk_clk_sgmii1sys) = {
- .name = "mt7981-clock-sgmii1sys",
+U_BOOT_DRIVER(mt7981_clk_sgmiisys) = {
+ .name = "mt7981-clock-sgmiisys",
.id = UCLASS_CLK,
- .of_match = mt7981_sgmii1sys_compat,
- .probe = mt7981_sgmii1sys_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt7981_sgmiisys,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
/* ethsys */
@@ -808,11 +808,12 @@ static const struct mtk_gate eth_cgs[] = {
GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", CLK_TOP_NETSYS_WED_MCU, 15),
};
-static int mt7981_ethsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree,
- eth_cgs, ARRAY_SIZE(eth_cgs), 0);
-}
+static const struct mtk_clk_tree mt7981_eth_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = eth_cgs,
+ .num_gates = ARRAY_SIZE(eth_cgs),
+};
static int mt7981_ethsys_bind(struct udevice *dev)
{
@@ -828,16 +829,19 @@ static int mt7981_ethsys_bind(struct udevice *dev)
}
static const struct udevice_id mt7981_ethsys_compat[] = {
- { .compatible = "mediatek,mt7981-ethsys", },
+ {
+ .compatible = "mediatek,mt7981-ethsys",
+ .data = (ulong)&mt7981_eth_clk_tree,
+ },
{}
};
-U_BOOT_DRIVER(mtk_clk_ethsys) = {
+U_BOOT_DRIVER(mt7981_clk_ethsys) = {
.name = "mt7981-clock-ethsys",
.id = UCLASS_CLK,
.of_match = mt7981_ethsys_compat,
- .probe = mt7981_ethsys_probe,
+ .probe = mtk_clk_probe,
.bind = mt7981_ethsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7986.c b/drivers/clk/mediatek/clk-mt7986.c
index 9c6514120a6..e4abddbd515 100644
--- a/drivers/clk/mediatek/clk-mt7986.c
+++ b/drivers/clk/mediatek/clk-mt7986.c
@@ -530,6 +530,7 @@ static const struct mtk_clk_tree mt7986_fixed_pll_clk_tree = {
.fclks = fixed_pll_clks,
.num_fclks = ARRAY_SIZE(fixed_pll_clks),
.flags = CLK_PARENT_APMIXED,
+ .type = MTK_CLK_TREE_APMIXED,
};
static const struct mtk_clk_tree mt7986_topckgen_clk_tree = {
@@ -544,6 +545,7 @@ static const struct mtk_clk_tree mt7986_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
.flags = CLK_PARENT_TOPCKGEN,
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_clk_tree mt7986_infracfg_clk_tree = {
@@ -559,24 +561,29 @@ static const struct mtk_clk_tree mt7986_infracfg_clk_tree = {
.num_muxes = ARRAY_SIZE(infra_muxes),
.num_gates = ARRAY_SIZE(infracfg_gates),
.flags = CLK_PARENT_INFRASYS,
+ .type = MTK_CLK_TREE_INFRASYS,
};
static const struct udevice_id mt7986_fixed_pll_compat[] = {
- { .compatible = "mediatek,mt7986-fixed-plls" },
- { .compatible = "mediatek,mt7986-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7986-fixed-plls",
+ .data = (ulong)&mt7986_fixed_pll_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7986-apmixedsys",
+ .data = (ulong)&mt7986_fixed_pll_clk_tree,
+ },
{}
};
static const struct udevice_id mt7986_topckgen_compat[] = {
- { .compatible = "mediatek,mt7986-topckgen" },
+ {
+ .compatible = "mediatek,mt7986-topckgen",
+ .data = (ulong)&mt7986_topckgen_clk_tree,
+ },
{}
};
-static int mt7986_fixed_pll_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7986_fixed_pll_clk_tree);
-}
-
static int mt7986_topckgen_probe(struct udevice *dev)
{
struct mtk_clk_priv *priv = dev_get_priv(dev);
@@ -584,20 +591,20 @@ static int mt7986_topckgen_probe(struct udevice *dev)
priv->base = dev_read_addr_ptr(dev);
writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN);
- return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree);
+ return mtk_clk_probe(dev);
}
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7986_clk_apmixedsys) = {
.name = "mt7986-clock-fixed-pll",
.id = UCLASS_CLK,
.of_match = mt7986_fixed_pll_compat,
- .probe = mt7986_fixed_pll_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_fixed_pll_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7986_clk_topckgen) = {
.name = "mt7986-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7986_topckgen_compat,
@@ -608,20 +615,18 @@ U_BOOT_DRIVER(mtk_clk_topckgen) = {
};
static const struct udevice_id mt7986_infracfg_compat[] = {
- { .compatible = "mediatek,mt7986-infracfg" },
+ {
+ .compatible = "mediatek,mt7986-infracfg",
+ .data = (ulong)&mt7986_infracfg_clk_tree,
+ },
{}
};
-static int mt7986_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7986_infracfg_clk_tree);
-}
-
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7986_clk_infracfg) = {
.name = "mt7986-clock-infracfg",
.id = UCLASS_CLK,
.of_match = mt7986_infracfg_compat,
- .probe = mt7986_infracfg_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
@@ -647,11 +652,12 @@ static const struct mtk_gate eth_cgs[] = {
GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", CLK_TOP_NETSYS_MCU_SEL, 15),
};
-static int mt7986_ethsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree, eth_cgs,
- ARRAY_SIZE(eth_cgs), 0);
-}
+static const struct mtk_clk_tree mt7986_eth_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = eth_cgs,
+ .num_gates = ARRAY_SIZE(eth_cgs),
+};
static int mt7986_ethsys_bind(struct udevice *dev)
{
@@ -667,16 +673,19 @@ static int mt7986_ethsys_bind(struct udevice *dev)
}
static const struct udevice_id mt7986_ethsys_compat[] = {
- { .compatible = "mediatek,mt7986-ethsys" },
+ {
+ .compatible = "mediatek,mt7986-ethsys",
+ .data = (ulong)&mt7986_eth_clk_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_ethsys) = {
+U_BOOT_DRIVER(mt7986_clk_ethsys) = {
.name = "mt7986-clock-ethsys",
.id = UCLASS_CLK,
.of_match = mt7986_ethsys_compat,
- .probe = mt7986_ethsys_probe,
+ .probe = mtk_clk_probe,
.bind = mt7986_ethsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7987.c b/drivers/clk/mediatek/clk-mt7987.c
index 5f102636079..6f2fe12a186 100644
--- a/drivers/clk/mediatek/clk-mt7987.c
+++ b/drivers/clk/mediatek/clk-mt7987.c
@@ -60,24 +60,26 @@ static const struct mtk_clk_tree mt7987_fixed_pll_clk_tree = {
.fclks = apmixedsys_mtk_plls,
.num_fclks = ARRAY_SIZE(apmixedsys_mtk_plls),
.flags = CLK_PARENT_APMIXED,
+ .type = MTK_CLK_TREE_APMIXED,
};
static const struct udevice_id mt7987_fixed_pll_compat[] = {
- { .compatible = "mediatek,mt7987-fixed-plls" },
- { .compatible = "mediatek,mt7987-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7987-fixed-plls",
+ .data = (ulong)&mt7987_fixed_pll_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7987-apmixedsys",
+ .data = (ulong)&mt7987_fixed_pll_clk_tree,
+ },
{}
};
-static int mt7987_fixed_pll_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7987_fixed_pll_clk_tree);
-}
-
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7987_clk_apmixedsys) = {
.name = "mt7987-clock-fixed-pll",
.id = UCLASS_CLK,
.of_match = mt7987_fixed_pll_compat,
- .probe = mt7987_fixed_pll_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_fixed_pll_ops,
.flags = DM_FLAG_PRE_RELOC,
@@ -457,10 +459,14 @@ static const struct mtk_clk_tree mt7987_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(topckgen_mtk_fixed_factors),
.num_muxes = ARRAY_SIZE(topckgen_mtk_muxes),
.flags = CLK_PARENT_TOPCKGEN,
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct udevice_id mt7987_topckgen_compat[] = {
- { .compatible = "mediatek,mt7987-topckgen" },
+ {
+ .compatible = "mediatek,mt7987-topckgen",
+ .data = (ulong)&mt7987_topckgen_clk_tree,
+ },
{}
};
@@ -473,10 +479,10 @@ static int mt7987_topckgen_probe(struct udevice *dev)
return -ENOENT;
writel(MT7987_CLK_PDN_EN_WRITE, priv->base + MT7987_CLK_PDN);
- return mtk_common_clk_init(dev, &mt7987_topckgen_clk_tree);
+ return mtk_clk_probe(dev);
}
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7987_clk_topckgen) = {
.name = "mt7987-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7987_topckgen_compat,
@@ -783,24 +789,26 @@ static const struct mtk_clk_tree mt7987_infracfg_clk_tree = {
.gates = infracfg_mtk_gates,
.num_muxes = ARRAY_SIZE(infracfg_mtk_mux),
.num_gates = ARRAY_SIZE(infracfg_mtk_gates),
+ .type = MTK_CLK_TREE_INFRASYS,
};
static const struct udevice_id mt7987_infracfg_compat[] = {
- { .compatible = "mediatek,mt7987-infracfg_ao" },
- { .compatible = "mediatek,mt7987-infracfg" },
+ {
+ .compatible = "mediatek,mt7987-infracfg_ao",
+ .data = (ulong)&mt7987_infracfg_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7987-infracfg",
+ .data = (ulong)&mt7987_infracfg_clk_tree,
+ },
{}
};
-static int mt7987_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7987_infracfg_clk_tree);
-}
-
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7987_clk_infracfg) = {
.name = "mt7987-clock-infracfg",
.id = UCLASS_CLK,
.of_match = mt7987_infracfg_compat,
- .probe = mt7987_infracfg_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
@@ -827,11 +835,12 @@ static const struct mtk_gate eth_cgs[] = {
GATE_ETH_TOP(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", CLK_TOP_NETSYS_500M_SEL, 10),
};
-static int mt7987_ethsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7987_topckgen_clk_tree, eth_cgs,
- ARRAY_SIZE(eth_cgs), 0);
-}
+static const struct mtk_clk_tree mt7987_eth_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = eth_cgs,
+ .num_gates = ARRAY_SIZE(eth_cgs),
+};
static int mt7987_ethsys_bind(struct udevice *dev)
{
@@ -849,16 +858,17 @@ static int mt7987_ethsys_bind(struct udevice *dev)
static const struct udevice_id mt7987_ethsys_compat[] = {
{
.compatible = "mediatek,mt7987-ethsys",
+ .data = (ulong)&mt7987_eth_clk_tree,
},
{}
};
-U_BOOT_DRIVER(mtk_clk_ethsys) = {
+U_BOOT_DRIVER(mt7987_clk_ethsys) = {
.name = "mt7987-clock-ethsys",
.id = UCLASS_CLK,
.of_match = mt7987_ethsys_compat,
- .probe = mt7987_ethsys_probe,
+ .probe = mtk_clk_probe,
.bind = mt7987_ethsys_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7988.c b/drivers/clk/mediatek/clk-mt7988.c
index 4e19f285da0..4728ca3e25a 100644
--- a/drivers/clk/mediatek/clk-mt7988.c
+++ b/drivers/clk/mediatek/clk-mt7988.c
@@ -808,6 +808,7 @@ static const struct mtk_clk_tree mt7988_fixed_pll_clk_tree = {
.fclks = apmixedsys_mtk_plls,
.num_fclks = ARRAY_SIZE(apmixedsys_mtk_plls),
.flags = CLK_PARENT_APMIXED,
+ .type = MTK_CLK_TREE_APMIXED,
};
static const struct mtk_clk_tree mt7988_topckgen_clk_tree = {
@@ -822,6 +823,7 @@ static const struct mtk_clk_tree mt7988_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(topckgen_mtk_fixed_factors),
.num_muxes = ARRAY_SIZE(topckgen_mtk_muxes),
.flags = CLK_PARENT_TOPCKGEN,
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_clk_tree mt7988_infracfg_clk_tree = {
@@ -833,24 +835,29 @@ static const struct mtk_clk_tree mt7988_infracfg_clk_tree = {
.gates = infracfg_mtk_gates,
.num_muxes = ARRAY_SIZE(infracfg_mtk_mux),
.num_gates = ARRAY_SIZE(infracfg_mtk_gates),
+ .type = MTK_CLK_TREE_INFRASYS,
};
static const struct udevice_id mt7988_fixed_pll_compat[] = {
- { .compatible = "mediatek,mt7988-fixed-plls" },
- { .compatible = "mediatek,mt7988-apmixedsys" },
+ {
+ .compatible = "mediatek,mt7988-fixed-plls",
+ .data = (ulong)&mt7988_fixed_pll_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt7988-apmixedsys",
+ .data = (ulong)&mt7988_fixed_pll_clk_tree,
+ },
{}
};
static const struct udevice_id mt7988_topckgen_compat[] = {
- { .compatible = "mediatek,mt7988-topckgen" },
+ {
+ .compatible = "mediatek,mt7988-topckgen",
+ .data = (ulong)&mt7988_topckgen_clk_tree,
+ },
{}
};
-static int mt7988_fixed_pll_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt7988_fixed_pll_clk_tree);
-}
-
static int mt7988_topckgen_probe(struct udevice *dev)
{
struct mtk_clk_priv *priv = dev_get_priv(dev);
@@ -860,20 +867,20 @@ static int mt7988_topckgen_probe(struct udevice *dev)
return -ENOENT;
writel(MT7988_CLK_PDN_EN_WRITE, priv->base + MT7988_CLK_PDN);
- return mtk_common_clk_init(dev, &mt7988_topckgen_clk_tree);
+ return mtk_clk_probe(dev);
}
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt7988_clk_apmixedsys) = {
.name = "mt7988-clock-fixed-pll",
.id = UCLASS_CLK,
.of_match = mt7988_fixed_pll_compat,
- .probe = mt7988_fixed_pll_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_fixed_pll_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt7988_clk_topckgen) = {
.name = "mt7988-clock-topckgen",
.id = UCLASS_CLK,
.of_match = mt7988_topckgen_compat,
@@ -884,20 +891,18 @@ U_BOOT_DRIVER(mtk_clk_topckgen) = {
};
static const struct udevice_id mt7988_infracfg_compat[] = {
- { .compatible = "mediatek,mt7988-infracfg" },
+ {
+ .compatible = "mediatek,mt7988-infracfg",
+ .data = (ulong)&mt7988_infracfg_clk_tree,
+ },
{}
};
-static int mt7988_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt7988_infracfg_clk_tree);
-}
-
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt7988_clk_infracfg) = {
.name = "mt7988-clock-infracfg",
.id = UCLASS_CLK,
.of_match = mt7988_infracfg_compat,
- .probe = mt7988_infracfg_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
@@ -922,12 +927,12 @@ static const struct mtk_gate ethdma_mtk_gate[] = {
GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", CLK_TOP_NETSYS_2X_SEL, 6),
};
-static int mt7988_ethdma_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7988_topckgen_clk_tree,
- ethdma_mtk_gate,
- ARRAY_SIZE(ethdma_mtk_gate), 0);
-}
+static const struct mtk_clk_tree mt7988_ethdma_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = ethdma_mtk_gate,
+ .num_gates = ARRAY_SIZE(ethdma_mtk_gate),
+};
static int mt7988_ethdma_bind(struct udevice *dev)
{
@@ -945,18 +950,19 @@ static int mt7988_ethdma_bind(struct udevice *dev)
static const struct udevice_id mt7988_ethdma_compat[] = {
{
.compatible = "mediatek,mt7988-ethdma",
+ .data = (ulong)&mt7988_ethdma_clk_tree,
},
{}
};
-U_BOOT_DRIVER(mtk_clk_ethdma) = {
+U_BOOT_DRIVER(mt7988_clk_ethdma) = {
.name = "mt7988-clock-ethdma",
.id = UCLASS_CLK,
.of_match = mt7988_ethdma_compat,
- .probe = mt7988_ethdma_probe,
+ .probe = mtk_clk_probe,
.bind = mt7988_ethdma_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
/* SGMIISYS_0 */
@@ -981,27 +987,11 @@ static const struct mtk_gate sgmiisys_0_mtk_gate[] = {
GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", CLK_TOP_XTAL, 3),
};
-static int mt7988_sgmiisys_0_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7988_topckgen_clk_tree,
- sgmiisys_0_mtk_gate,
- ARRAY_SIZE(sgmiisys_0_mtk_gate), 0);
-}
-
-static const struct udevice_id mt7988_sgmiisys_0_compat[] = {
- {
- .compatible = "mediatek,mt7988-sgmiisys_0",
- },
- {}
-};
-
-U_BOOT_DRIVER(mtk_clk_sgmiisys_0) = {
- .name = "mt7988-clock-sgmiisys_0",
- .id = UCLASS_CLK,
- .of_match = mt7988_sgmiisys_0_compat,
- .probe = mt7988_sgmiisys_0_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+static const struct mtk_clk_tree mt7988_sgmiisys_0_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = sgmiisys_0_mtk_gate,
+ .num_gates = ARRAY_SIZE(sgmiisys_0_mtk_gate),
};
/* SGMIISYS_1 */
@@ -1026,27 +1016,32 @@ static const struct mtk_gate sgmiisys_1_mtk_gate[] = {
GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", CLK_TOP_XTAL, 3),
};
-static int mt7988_sgmiisys_1_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7988_topckgen_clk_tree,
- sgmiisys_1_mtk_gate,
- ARRAY_SIZE(sgmiisys_1_mtk_gate), 0);
-}
+static const struct mtk_clk_tree mt7988_sgmiisys_1_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = sgmiisys_1_mtk_gate,
+ .num_gates = ARRAY_SIZE(sgmiisys_1_mtk_gate),
+};
-static const struct udevice_id mt7988_sgmiisys_1_compat[] = {
+static const struct udevice_id of_match_mt7988_sgmiisys[] = {
+ {
+ .compatible = "mediatek,mt7988-sgmiisys_0",
+ .data = (ulong)&mt7988_sgmiisys_0_clk_tree,
+ },
{
.compatible = "mediatek,mt7988-sgmiisys_1",
+ .data = (ulong)&mt7988_sgmiisys_1_clk_tree,
},
{}
};
-U_BOOT_DRIVER(mtk_clk_sgmiisys_1) = {
- .name = "mt7988-clock-sgmiisys_1",
+U_BOOT_DRIVER(mt7988_clk_sgmiisys) = {
+ .name = "mt7988-clock-sgmiisys",
.id = UCLASS_CLK,
- .of_match = mt7988_sgmiisys_1_compat,
- .probe = mt7988_sgmiisys_1_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt7988_sgmiisys,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
/* ETHWARP */
@@ -1073,12 +1068,12 @@ static const struct mtk_gate ethwarp_mtk_gate[] = {
CLK_TOP_NETSYS_MCU_SEL, 15),
};
-static int mt7988_ethwarp_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt7988_topckgen_clk_tree,
- ethwarp_mtk_gate,
- ARRAY_SIZE(ethwarp_mtk_gate), 0);
-}
+static const struct mtk_clk_tree mt7988_ethwarp_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = ethwarp_mtk_gate,
+ .num_gates = ARRAY_SIZE(ethwarp_mtk_gate),
+};
static int mt7988_ethwarp_bind(struct udevice *dev)
{
@@ -1096,16 +1091,17 @@ static int mt7988_ethwarp_bind(struct udevice *dev)
static const struct udevice_id mt7988_ethwarp_compat[] = {
{
.compatible = "mediatek,mt7988-ethwarp",
+ .data = (ulong)&mt7988_ethwarp_clk_tree,
},
{}
};
-U_BOOT_DRIVER(mtk_clk_ethwarp) = {
+U_BOOT_DRIVER(mt7988_clk_ethwarp) = {
.name = "mt7988-clock-ethwarp",
.id = UCLASS_CLK,
.of_match = mt7988_ethwarp_compat,
- .probe = mt7988_ethwarp_probe,
+ .probe = mtk_clk_probe,
.bind = mt7988_ethwarp_bind,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
index 7b2d796bc6c..5a4863049c5 100644
--- a/drivers/clk/mediatek/clk-mt8183.c
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -604,20 +604,27 @@ static const struct mtk_composite top_muxes[] = {
MUX(CLK_TOP_MUX_AUD_2, aud_2_parents, 0xe0, 8, 1),
};
-static const struct mtk_clk_tree mt8183_clk_tree = {
+static const struct mtk_clk_tree mt8183_apmixed_clk_tree = {
.pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .plls = apmixed_plls,
+ .num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
+};
+
+static const struct mtk_clk_tree mt8183_topckgen_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.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,
- .num_plls = ARRAY_SIZE(apmixed_plls),
.num_fclks = ARRAY_SIZE(top_fixed_clks),
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_gate_regs infra0_cg_regs = {
@@ -780,63 +787,63 @@ static const struct mtk_gate infra_clks[] = {
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,
- ARRAY_SIZE(infra_clks), 0);
-}
+static const struct mtk_clk_tree mt8183_infracfg_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = infra_clks,
+ .num_gates = ARRAY_SIZE(infra_clks),
+};
static const struct udevice_id mt8183_apmixed_compat[] = {
- { .compatible = "mediatek,mt8183-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8183-apmixedsys",
+ .data = (ulong)&mt8183_apmixed_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8183_topckgen_compat[] = {
- { .compatible = "mediatek,mt8183-topckgen", },
+ {
+ .compatible = "mediatek,mt8183-topckgen",
+ .data = (ulong)&mt8183_topckgen_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8183_infracfg_compat[] = {
- { .compatible = "mediatek,mt8183-infracfg", },
+ {
+ .compatible = "mediatek,mt8183-infracfg",
+ .data = (ulong)&mt8183_infracfg_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8183_clk_apmixedsys) = {
.name = "mt8183-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8183_apmixed_compat,
- .probe = mt8183_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8183_clk_topckgen) = {
.name = "mt8183-topckgen",
.id = UCLASS_CLK,
.of_match = mt8183_topckgen_compat,
- .probe = mt8183_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt8183_clk_infracfg) = {
.name = "mt8183-infracfg",
.id = UCLASS_CLK,
.of_match = mt8183_infracfg_compat,
- .probe = mt8183_infracfg_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
- .ops = &mtk_clk_gate_ops,
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8188.c b/drivers/clk/mediatek/clk-mt8188.c
index 3e413e111f1..0829ebf4f9a 100644
--- a/drivers/clk/mediatek/clk-mt8188.c
+++ b/drivers/clk/mediatek/clk-mt8188.c
@@ -89,6 +89,7 @@ static const struct mtk_clk_tree mt8188_apmixedsys_clk_tree = {
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
.num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
};
#define FIXED_CLK0(_id, _rate) \
@@ -1362,7 +1363,7 @@ static const struct mtk_gate_regs top1_cg_regs = {
.parent = _parent, \
.regs = &top0_cg_regs, \
.shift = _shift, \
- .flags = CLK_GATE_NO_SETCLR | CLK_PARENT_TOPCKGEN, \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \
}
#define GATE_TOP0E(_id, _parent, _shift) { \
@@ -1370,7 +1371,7 @@ static const struct mtk_gate_regs top1_cg_regs = {
.parent = _parent, \
.regs = &top0_cg_regs, \
.shift = _shift, \
- .flags = CLK_GATE_NO_SETCLR | CLK_PARENT_EXT, \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_EXT, \
}
#define GATE_TOP1(_id, _parent, _shift) { \
@@ -1422,6 +1423,7 @@ static const struct mtk_clk_tree mt8188_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
.num_gates = ARRAY_SIZE(topckgen_cg_clks),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_gate_regs infra_ao0_cg_regs = {
@@ -1620,6 +1622,8 @@ static const struct mtk_gate infracfg_ao_clks[] = {
static const struct mtk_clk_tree mt8188_infracfg_ao_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = infracfg_ao_clks,
+ .num_gates = ARRAY_SIZE(infracfg_ao_clks),
};
static const struct mtk_gate_regs peri_ao_cg_regs = {
@@ -1657,11 +1661,14 @@ static const struct mtk_gate pericfg_ao_clks[] = {
GATE_PERI_AO(CLK_PERI_AO_SSUSB_BUS, CLK_TOP_USB_TOP, 13),
GATE_PERI_AO(CLK_PERI_AO_SSUSB_XHCI, CLK_TOP_SSUSB_XHCI, 14),
GATE_PERI_AO(CLK_PERI_AO_ETHERNET_MAC, CLK_TOP_SNPS_ETH_250M, 16),
+ GATE_PERI_AO(CLK_PERI_AO_PCIE_P0_FMEM, CLK_TOP_466M_FMEM, 24),
};
static const struct mtk_clk_tree mt8188_pericfg_ao_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = pericfg_ao_clks,
+ .num_gates = ARRAY_SIZE(pericfg_ao_clks),
};
static const struct mtk_gate_regs imp_iic_wrap_cg_regs = {
@@ -1697,164 +1704,492 @@ static const struct mtk_gate imp_iic_wrap_en_clks[] = {
const struct mtk_clk_tree mt8188_imp_iic_wrap_c_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = imp_iic_wrap_c_clks,
+ .num_gates = ARRAY_SIZE(imp_iic_wrap_c_clks),
};
const struct mtk_clk_tree mt8188_imp_iic_wrap_w_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = imp_iic_wrap_w_clks,
+ .num_gates = ARRAY_SIZE(imp_iic_wrap_w_clks),
};
const struct mtk_clk_tree mt8188_imp_iic_wrap_en_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = imp_iic_wrap_en_clks,
+ .num_gates = ARRAY_SIZE(imp_iic_wrap_en_clks),
};
-static int mt8188_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8188_apmixedsys_clk_tree);
-}
+static const struct mtk_gate_regs vdo0_0_cg_regs = {
+ .set_ofs = 0x104,
+ .clr_ofs = 0x108,
+ .sta_ofs = 0x100,
+};
-static int mt8188_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8188_topckgen_clk_tree);
-}
+static const struct mtk_gate_regs vdo0_1_cg_regs = {
+ .set_ofs = 0x114,
+ .clr_ofs = 0x118,
+ .sta_ofs = 0x110,
+};
-static int mt8188_infracfg_ao_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8188_infracfg_ao_clk_tree,
- infracfg_ao_clks,
- ARRAY_SIZE(infracfg_ao_clks), 0);
-}
+static const struct mtk_gate_regs vdo0_2_cg_regs = {
+ .set_ofs = 0x124,
+ .clr_ofs = 0x128,
+ .sta_ofs = 0x120,
+};
-static int mt8188_pericfg_ao_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8188_pericfg_ao_clk_tree,
- pericfg_ao_clks,
- ARRAY_SIZE(pericfg_ao_clks), 0);
-}
+static const struct mtk_gate_regs vpp0_0_cg_regs = {
+ .set_ofs = 0x24,
+ .clr_ofs = 0x28,
+ .sta_ofs = 0x20,
+};
-static int mt8188_imp_iic_wrap_c_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8188_imp_iic_wrap_c_clk_tree,
- imp_iic_wrap_c_clks,
- ARRAY_SIZE(imp_iic_wrap_c_clks), 0);
-}
+static const struct mtk_gate_regs vpp0_1_cg_regs = {
+ .set_ofs = 0x30,
+ .clr_ofs = 0x34,
+ .sta_ofs = 0x2c,
+};
-static int mt8188_imp_iic_wrap_w_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8188_imp_iic_wrap_w_clk_tree,
- imp_iic_wrap_w_clks,
- ARRAY_SIZE(imp_iic_wrap_w_clks), 0);
-}
+static const struct mtk_gate_regs vpp0_2_cg_regs = {
+ .set_ofs = 0x3c,
+ .clr_ofs = 0x40,
+ .sta_ofs = 0x38,
+};
-static int mt8188_imp_iic_wrap_en_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8188_imp_iic_wrap_en_clk_tree,
- imp_iic_wrap_en_clks,
- ARRAY_SIZE(imp_iic_wrap_en_clks), 0);
-}
+#define GATE_VPP0_0(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vpp0_0_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
-static const struct udevice_id mt8188_apmixed_compat[] = {
- { .compatible = "mediatek,mt8188-apmixedsys", },
- { }
+#define GATE_VPP0_1(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vpp0_1_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VPP0_2(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vpp0_2_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+static const struct mtk_gate vpp0_clks[] = {
+ /* VPP0_0 */
+ GATE_VPP0_0(CLK_VPP0_MDP_FG, CLK_TOP_VPP, 1),
+ GATE_VPP0_0(CLK_VPP0_STITCH, CLK_TOP_VPP, 2),
+ GATE_VPP0_0(CLK_VPP0_PADDING, CLK_TOP_VPP, 7),
+ GATE_VPP0_0(CLK_VPP0_MDP_TCC, CLK_TOP_VPP, 8),
+ GATE_VPP0_0(CLK_VPP0_WARP0_ASYNC_TX, CLK_TOP_VPP, 10),
+ GATE_VPP0_0(CLK_VPP0_WARP1_ASYNC_TX, CLK_TOP_VPP, 11),
+ GATE_VPP0_0(CLK_VPP0_MUTEX, CLK_TOP_VPP, 13),
+ GATE_VPP0_0(CLK_VPP02VPP1_RELAY, CLK_TOP_VPP, 14),
+ GATE_VPP0_0(CLK_VPP0_VPP12VPP0_ASYNC, CLK_TOP_VPP, 15),
+ GATE_VPP0_0(CLK_VPP0_MMSYSRAM_TOP, CLK_TOP_VPP, 16),
+ GATE_VPP0_0(CLK_VPP0_MDP_AAL, CLK_TOP_VPP, 17),
+ GATE_VPP0_0(CLK_VPP0_MDP_RSZ, CLK_TOP_VPP, 18),
+ /* VPP0_1 */
+ GATE_VPP0_1(CLK_VPP0_SMI_COMMON_MMSRAM, CLK_TOP_VPP, 0),
+ GATE_VPP0_1(CLK_VPP0_GALS_VDO0_LARB0_MMSRAM, CLK_TOP_VPP, 1),
+ GATE_VPP0_1(CLK_VPP0_GALS_VDO0_LARB1_MMSRAM, CLK_TOP_VPP, 2),
+ GATE_VPP0_1(CLK_VPP0_GALS_VENCSYS_MMSRAM, CLK_TOP_VPP, 3),
+ GATE_VPP0_1(CLK_VPP0_GALS_VENCSYS_CORE1_MMSRAM, CLK_TOP_VPP, 4),
+ GATE_VPP0_1(CLK_VPP0_GALS_INFRA_MMSRAM, CLK_TOP_VPP, 5),
+ GATE_VPP0_1(CLK_VPP0_GALS_CAMSYS_MMSRAM, CLK_TOP_VPP, 6),
+ GATE_VPP0_1(CLK_VPP0_GALS_VPP1_LARB5_MMSRAM, CLK_TOP_VPP, 7),
+ GATE_VPP0_1(CLK_VPP0_GALS_VPP1_LARB6_MMSRAM, CLK_TOP_VPP, 8),
+ GATE_VPP0_1(CLK_VPP0_SMI_REORDER_MMSRAM, CLK_TOP_VPP, 9),
+ GATE_VPP0_1(CLK_VPP0_SMI_IOMMU, CLK_TOP_VPP, 10),
+ GATE_VPP0_1(CLK_VPP0_GALS_IMGSYS_CAMSYS, CLK_TOP_VPP, 11),
+ GATE_VPP0_1(CLK_VPP0_MDP_RDMA, CLK_TOP_VPP, 12),
+ GATE_VPP0_1(CLK_VPP0_MDP_WROT, CLK_TOP_VPP, 13),
+ GATE_VPP0_1(CLK_VPP0_GALS_EMI0_EMI1, CLK_TOP_VPP, 16),
+ GATE_VPP0_1(CLK_VPP0_SMI_SUB_COMMON_REORDER, CLK_TOP_VPP, 17),
+ GATE_VPP0_1(CLK_VPP0_SMI_RSI, CLK_TOP_VPP, 18),
+ GATE_VPP0_1(CLK_VPP0_SMI_COMMON_LARB4, CLK_TOP_VPP, 19),
+ GATE_VPP0_1(CLK_VPP0_GALS_VDEC_VDEC_CORE1, CLK_TOP_VPP, 20),
+ GATE_VPP0_1(CLK_VPP0_GALS_VPP1_WPESYS, CLK_TOP_VPP, 21),
+ GATE_VPP0_1(CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1, CLK_TOP_VPP, 22),
+ GATE_VPP0_1(CLK_VPP0_FAKE_ENG, CLK_TOP_VPP, 23),
+ GATE_VPP0_1(CLK_VPP0_MDP_HDR, CLK_TOP_VPP, 24),
+ GATE_VPP0_1(CLK_VPP0_MDP_TDSHP, CLK_TOP_VPP, 25),
+ GATE_VPP0_1(CLK_VPP0_MDP_COLOR, CLK_TOP_VPP, 26),
+ GATE_VPP0_1(CLK_VPP0_MDP_OVL, CLK_TOP_VPP, 27),
+ GATE_VPP0_1(CLK_VPP0_DSIP_RDMA, CLK_TOP_VPP, 28),
+ GATE_VPP0_1(CLK_VPP0_DISP_WDMA, CLK_TOP_VPP, 29),
+ GATE_VPP0_1(CLK_VPP0_MDP_HMS, CLK_TOP_VPP, 30),
+ /* VPP0_2 */
+ GATE_VPP0_2(CLK_VPP0_WARP0_RELAY, CLK_TOP_WPE_VPP, 0),
+ GATE_VPP0_2(CLK_VPP0_WARP0_ASYNC, CLK_TOP_WPE_VPP, 1),
+ GATE_VPP0_2(CLK_VPP0_WARP1_RELAY, CLK_TOP_WPE_VPP, 2),
+ GATE_VPP0_2(CLK_VPP0_WARP1_ASYNC, CLK_TOP_WPE_VPP, 3),
};
-static const struct udevice_id mt8188_topckgen_compat[] = {
- { .compatible = "mediatek,mt8188-topckgen", },
- { }
+static const struct mtk_gate_regs vpp1_0_cg_regs = {
+ .set_ofs = 0x104,
+ .clr_ofs = 0x108,
+ .sta_ofs = 0x100,
};
-static const struct udevice_id mt8188_infracfg_ao_compat[] = {
- { .compatible = "mediatek,mt8188-infracfg-ao", },
- { }
+static const struct mtk_gate_regs vpp1_1_cg_regs = {
+ .set_ofs = 0x114,
+ .clr_ofs = 0x118,
+ .sta_ofs = 0x110,
};
-static const struct udevice_id mt8188_pericfg_ao_compat[] = {
- { .compatible = "mediatek,mt8188-pericfg-ao", },
- { }
+#define GATE_VPP1_0(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vpp1_0_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VPP1_1(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vpp1_1_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+static const struct mtk_gate vpp1_clks[] = {
+ /* VPP1_0 */
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_OVL, CLK_TOP_VPP, 0),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_TCC, CLK_TOP_VPP, 1),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_WROT, CLK_TOP_VPP, 2),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_VPP_PAD, CLK_TOP_VPP, 3),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_WROT, CLK_TOP_VPP, 4),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_VPP_PAD, CLK_TOP_VPP, 5),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_WROT, CLK_TOP_VPP, 6),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_VPP_PAD, CLK_TOP_VPP, 7),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_RDMA, CLK_TOP_VPP, 8),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_FG, CLK_TOP_VPP, 9),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_RDMA, CLK_TOP_VPP, 10),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_FG, CLK_TOP_VPP, 11),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_RDMA, CLK_TOP_VPP, 12),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_FG, CLK_TOP_VPP, 13),
+ GATE_VPP1_0(CLK_VPP1_VPP_SPLIT, CLK_TOP_VPP, 14),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_VDO0_DL_RELAY, CLK_TOP_VPP, 15),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_RSZ, CLK_TOP_VPP, 16),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_TDSHP, CLK_TOP_VPP, 17),
+ GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_COLOR, CLK_TOP_VPP, 18),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_VDO1_DL_RELAY, CLK_TOP_VPP, 19),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_RSZ, CLK_TOP_VPP, 20),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_VPP_MERGE, CLK_TOP_VPP, 21),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_TDSHP, CLK_TOP_VPP, 22),
+ GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_COLOR, CLK_TOP_VPP, 23),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_RSZ, CLK_TOP_VPP, 24),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_VPP_MERGE, CLK_TOP_VPP, 25),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_TDSHP, CLK_TOP_VPP, 26),
+ GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_COLOR, CLK_TOP_VPP, 27),
+ GATE_VPP1_0(CLK_VPP1_GALS5, CLK_TOP_VPP, 28),
+ GATE_VPP1_0(CLK_VPP1_GALS6, CLK_TOP_VPP, 29),
+ GATE_VPP1_0(CLK_VPP1_LARB5, CLK_TOP_VPP, 30),
+ GATE_VPP1_0(CLK_VPP1_LARB6, CLK_TOP_VPP, 31),
+ /* VPP1_1 */
+ GATE_VPP1_1(CLK_VPP1_SVPP1_MDP_HDR, CLK_TOP_VPP, 0),
+ GATE_VPP1_1(CLK_VPP1_SVPP1_MDP_AAL, CLK_TOP_VPP, 1),
+ GATE_VPP1_1(CLK_VPP1_SVPP2_MDP_HDR, CLK_TOP_VPP, 2),
+ GATE_VPP1_1(CLK_VPP1_SVPP2_MDP_AAL, CLK_TOP_VPP, 3),
+ GATE_VPP1_1(CLK_VPP1_SVPP3_MDP_HDR, CLK_TOP_VPP, 4),
+ GATE_VPP1_1(CLK_VPP1_SVPP3_MDP_AAL, CLK_TOP_VPP, 5),
+ GATE_VPP1_1(CLK_VPP1_DISP_MUTEX, CLK_TOP_VPP, 7),
+ GATE_VPP1_1(CLK_VPP1_SVPP2_VDO1_DL_RELAY, CLK_TOP_VPP, 8),
+ GATE_VPP1_1(CLK_VPP1_SVPP3_VDO0_DL_RELAY, CLK_TOP_VPP, 9),
+ GATE_VPP1_1(CLK_VPP1_VPP0_DL_ASYNC, CLK_TOP_VPP, 10),
+ GATE_VPP1_1(CLK_VPP1_VPP0_DL1_RELAY, CLK_TOP_VPP, 11),
+ GATE_VPP1_1(CLK_VPP1_LARB5_FAKE_ENG, CLK_TOP_VPP, 12),
+ GATE_VPP1_1(CLK_VPP1_LARB6_FAKE_ENG, CLK_TOP_VPP, 13),
+ GATE_VPP1_1(CLK_VPP1_HDMI_META, CLK_TOP_VPP, 16),
+ GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_HDMI, CLK_TOP_VPP, 17),
+ GATE_VPP1_1(CLK_VPP1_DGI_IN, CLK_TOP_VPP, 18),
+ GATE_VPP1_1(CLK_VPP1_DGI_OUT, CLK_TOP_VPP, 19),
+ GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_DGI, CLK_TOP_VPP, 20),
+ GATE_VPP1_1(CLK_VPP1_DL_CON_OCC, CLK_TOP_VPP, 21),
+ GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_26M, CLK_TOP_VPP, 26),
+};
+
+#define GATE_VDO0_0(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo0_0_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO0_1(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo0_1_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO0_2(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo0_2_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+static const struct mtk_gate vdo0_clks[] = {
+ /* VDO0_0 */
+ GATE_VDO0_0(CLK_VDO0_DISP_OVL0, CLK_TOP_VPP, 0),
+ GATE_VDO0_0(CLK_VDO0_FAKE_ENG0, CLK_TOP_VPP, 2),
+ GATE_VDO0_0(CLK_VDO0_DISP_CCORR0, CLK_TOP_VPP, 4),
+ GATE_VDO0_0(CLK_VDO0_DISP_MUTEX0, CLK_TOP_VPP, 6),
+ GATE_VDO0_0(CLK_VDO0_DISP_GAMMA0, CLK_TOP_VPP, 8),
+ GATE_VDO0_0(CLK_VDO0_DISP_DITHER0, CLK_TOP_VPP, 10),
+ GATE_VDO0_0(CLK_VDO0_DISP_WDMA0, CLK_TOP_VPP, 17),
+ GATE_VDO0_0(CLK_VDO0_DISP_RDMA0, CLK_TOP_VPP, 19),
+ GATE_VDO0_0(CLK_VDO0_DSI0, CLK_TOP_VPP, 21),
+ GATE_VDO0_0(CLK_VDO0_DSI1, CLK_TOP_VPP, 22),
+ GATE_VDO0_0(CLK_VDO0_DSC_WRAP0, CLK_TOP_VPP, 23),
+ GATE_VDO0_0(CLK_VDO0_VPP_MERGE0, CLK_TOP_VPP, 24),
+ GATE_VDO0_0(CLK_VDO0_DP_INTF0, CLK_TOP_VPP, 25),
+ GATE_VDO0_0(CLK_VDO0_DISP_AAL0, CLK_TOP_VPP, 26),
+ GATE_VDO0_0(CLK_VDO0_INLINEROT0, CLK_TOP_VPP, 27),
+ GATE_VDO0_0(CLK_VDO0_APB_BUS, CLK_TOP_VPP, 28),
+ GATE_VDO0_0(CLK_VDO0_DISP_COLOR0, CLK_TOP_VPP, 29),
+ GATE_VDO0_0(CLK_VDO0_MDP_WROT0, CLK_TOP_VPP, 30),
+ GATE_VDO0_0(CLK_VDO0_DISP_RSZ0, CLK_TOP_VPP, 31),
+ /* VDO0_1 */
+ GATE_VDO0_1(CLK_VDO0_DISP_POSTMASK0, CLK_TOP_VPP, 0),
+ GATE_VDO0_1(CLK_VDO0_FAKE_ENG1, CLK_TOP_VPP, 1),
+ GATE_VDO0_1(CLK_VDO0_DL_ASYNC2, CLK_TOP_VPP, 5),
+ GATE_VDO0_1(CLK_VDO0_DL_RELAY3, CLK_TOP_VPP, 6),
+ GATE_VDO0_1(CLK_VDO0_DL_RELAY4, CLK_TOP_VPP, 7),
+ GATE_VDO0_1(CLK_VDO0_SMI_GALS, CLK_TOP_VPP, 10),
+ GATE_VDO0_1(CLK_VDO0_SMI_COMMON, CLK_TOP_VPP, 11),
+ GATE_VDO0_1(CLK_VDO0_SMI_EMI, CLK_TOP_VPP, 12),
+ GATE_VDO0_1(CLK_VDO0_SMI_IOMMU, CLK_TOP_VPP, 13),
+ GATE_VDO0_1(CLK_VDO0_SMI_LARB, CLK_TOP_VPP, 14),
+ GATE_VDO0_1(CLK_VDO0_SMI_RSI, CLK_TOP_VPP, 15),
+ /* VDO0_2 */
+ GATE_VDO0_2(CLK_VDO0_DSI0_DSI, CLK_TOP_DSI_OCC, 0),
+ GATE_VDO0_2(CLK_VDO0_DSI1_DSI, CLK_TOP_DSI_OCC, 8),
+ GATE_VDO0_2(CLK_VDO0_DP_INTF0_DP_INTF, CLK_TOP_EDP, 16),
+};
+
+static const struct mtk_gate_regs vdo1_0_cg_regs = {
+ .set_ofs = 0x104,
+ .clr_ofs = 0x108,
+ .sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs vdo1_1_cg_regs = {
+ .set_ofs = 0x114,
+ .clr_ofs = 0x118,
+ .sta_ofs = 0x110,
+};
+
+static const struct mtk_gate_regs vdo1_2_cg_regs = {
+ .set_ofs = 0x124,
+ .clr_ofs = 0x128,
+ .sta_ofs = 0x120,
+};
+
+static const struct mtk_gate_regs vdo1_3_cg_regs = {
+ .set_ofs = 0x134,
+ .clr_ofs = 0x138,
+ .sta_ofs = 0x130,
+};
+
+static const struct mtk_gate_regs vdo1_4_cg_regs = {
+ .set_ofs = 0x144,
+ .clr_ofs = 0x148,
+ .sta_ofs = 0x140,
+};
+
+static const struct mtk_gate_regs vdo1_5_cg_regs = {
+ .set_ofs = 0x400,
+ .clr_ofs = 0x400,
+ .sta_ofs = 0x400,
+};
+
+#define GATE_VDO1_0(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo1_0_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO1_1(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo1_1_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO1_2(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo1_2_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO1_3(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo1_3_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO1_4(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo1_4_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+#define GATE_VDO1_5(_id, _parent, _shift) \
+ GATE_FLAGS(_id, _parent, &vdo1_5_cg_regs, _shift, \
+ CLK_PARENT_TOPCKGEN | CLK_GATE_SETCLR)
+
+static const struct mtk_gate vdo1_clks[] = {
+ /* VDO1_0 */
+ GATE_VDO1_0(CLK_VDO1_SMI_LARB2, CLK_TOP_VPP, 0),
+ GATE_VDO1_0(CLK_VDO1_SMI_LARB3, CLK_TOP_VPP, 1),
+ GATE_VDO1_0(CLK_VDO1_GALS, CLK_TOP_VPP, 2),
+ GATE_VDO1_0(CLK_VDO1_FAKE_ENG0, CLK_TOP_VPP, 3),
+ GATE_VDO1_0(CLK_VDO1_FAKE_ENG1, CLK_TOP_VPP, 4),
+ GATE_VDO1_0(CLK_VDO1_MDP_RDMA0, CLK_TOP_VPP, 5),
+ GATE_VDO1_0(CLK_VDO1_MDP_RDMA1, CLK_TOP_VPP, 6),
+ GATE_VDO1_0(CLK_VDO1_MDP_RDMA2, CLK_TOP_VPP, 7),
+ GATE_VDO1_0(CLK_VDO1_MDP_RDMA3, CLK_TOP_VPP, 8),
+ GATE_VDO1_0(CLK_VDO1_VPP_MERGE0, CLK_TOP_VPP, 9),
+ GATE_VDO1_0(CLK_VDO1_VPP_MERGE1, CLK_TOP_VPP, 10),
+ GATE_VDO1_0(CLK_VDO1_VPP_MERGE2, CLK_TOP_VPP, 11),
+ /* VDO1_1 */
+ GATE_VDO1_1(CLK_VDO1_VPP_MERGE3, CLK_TOP_VPP, 0),
+ GATE_VDO1_1(CLK_VDO1_VPP_MERGE4, CLK_TOP_VPP, 1),
+ GATE_VDO1_1(CLK_VDO1_VPP2_TO_VDO1_DL_ASYNC, CLK_TOP_VPP, 2),
+ GATE_VDO1_1(CLK_VDO1_VPP3_TO_VDO1_DL_ASYNC, CLK_TOP_VPP, 3),
+ GATE_VDO1_1(CLK_VDO1_DISP_MUTEX, CLK_TOP_VPP, 4),
+ GATE_VDO1_1(CLK_VDO1_MDP_RDMA4, CLK_TOP_VPP, 5),
+ GATE_VDO1_1(CLK_VDO1_MDP_RDMA5, CLK_TOP_VPP, 6),
+ GATE_VDO1_1(CLK_VDO1_MDP_RDMA6, CLK_TOP_VPP, 7),
+ GATE_VDO1_1(CLK_VDO1_MDP_RDMA7, CLK_TOP_VPP, 8),
+ GATE_VDO1_1(CLK_VDO1_DP_INTF0_MMCK, CLK_TOP_VPP, 9),
+ GATE_VDO1_1(CLK_VDO1_DPI0_MM, CLK_TOP_VPP, 10),
+ GATE_VDO1_1(CLK_VDO1_DPI1_MM, CLK_TOP_VPP, 11),
+ GATE_VDO1_1(CLK_VDO1_MERGE0_DL_ASYNC, CLK_TOP_VPP, 13),
+ GATE_VDO1_1(CLK_VDO1_MERGE1_DL_ASYNC, CLK_TOP_VPP, 14),
+ GATE_VDO1_1(CLK_VDO1_MERGE2_DL_ASYNC, CLK_TOP_VPP, 15),
+ GATE_VDO1_1(CLK_VDO1_MERGE3_DL_ASYNC, CLK_TOP_VPP, 16),
+ GATE_VDO1_1(CLK_VDO1_MERGE4_DL_ASYNC, CLK_TOP_VPP, 17),
+ GATE_VDO1_1(CLK_VDO1_DSC_VDO1_DL_ASYNC, CLK_TOP_VPP, 18),
+ GATE_VDO1_1(CLK_VDO1_MERGE_VDO1_DL_ASYNC, CLK_TOP_VPP, 19),
+ GATE_VDO1_1(CLK_VDO1_PADDING0, CLK_TOP_VPP, 20),
+ GATE_VDO1_1(CLK_VDO1_PADDING1, CLK_TOP_VPP, 21),
+ GATE_VDO1_1(CLK_VDO1_PADDING2, CLK_TOP_VPP, 22),
+ GATE_VDO1_1(CLK_VDO1_PADDING3, CLK_TOP_VPP, 23),
+ GATE_VDO1_1(CLK_VDO1_PADDING4, CLK_TOP_VPP, 24),
+ GATE_VDO1_1(CLK_VDO1_PADDING5, CLK_TOP_VPP, 25),
+ GATE_VDO1_1(CLK_VDO1_PADDING6, CLK_TOP_VPP, 26),
+ GATE_VDO1_1(CLK_VDO1_PADDING7, CLK_TOP_VPP, 27),
+ GATE_VDO1_1(CLK_VDO1_DISP_RSZ0, CLK_TOP_VPP, 28),
+ GATE_VDO1_1(CLK_VDO1_DISP_RSZ1, CLK_TOP_VPP, 29),
+ GATE_VDO1_1(CLK_VDO1_DISP_RSZ2, CLK_TOP_VPP, 30),
+ GATE_VDO1_1(CLK_VDO1_DISP_RSZ3, CLK_TOP_VPP, 31),
+ /* VDO1_2 */
+ GATE_VDO1_2(CLK_VDO1_HDR_VDO_FE0, CLK_TOP_VPP, 0),
+ GATE_VDO1_2(CLK_VDO1_HDR_GFX_FE0, CLK_TOP_VPP, 1),
+ GATE_VDO1_2(CLK_VDO1_HDR_VDO_BE, CLK_TOP_VPP, 2),
+ GATE_VDO1_2(CLK_VDO1_HDR_VDO_FE1, CLK_TOP_VPP, 16),
+ GATE_VDO1_2(CLK_VDO1_HDR_GFX_FE1, CLK_TOP_VPP, 17),
+ GATE_VDO1_2(CLK_VDO1_DISP_MIXER, CLK_TOP_VPP, 18),
+ GATE_VDO1_2(CLK_VDO1_HDR_VDO_FE0_DL_ASYNC, CLK_TOP_VPP, 19),
+ GATE_VDO1_2(CLK_VDO1_HDR_VDO_FE1_DL_ASYNC, CLK_TOP_VPP, 20),
+ GATE_VDO1_2(CLK_VDO1_HDR_GFX_FE0_DL_ASYNC, CLK_TOP_VPP, 21),
+ GATE_VDO1_2(CLK_VDO1_HDR_GFX_FE1_DL_ASYNC, CLK_TOP_VPP, 22),
+ GATE_VDO1_2(CLK_VDO1_HDR_VDO_BE_DL_ASYNC, CLK_TOP_VPP, 23),
+ /* VDO1_3 */
+ GATE_VDO1_3(CLK_VDO1_DPI0, CLK_TOP_VPP, 0),
+ GATE_VDO1_3(CLK_VDO1_DISP_MONITOR_DPI0, CLK_TOP_VPP, 1),
+ GATE_VDO1_3(CLK_VDO1_DPI1, CLK_TOP_VPP, 8),
+ GATE_VDO1_3(CLK_VDO1_DISP_MONITOR_DPI1, CLK_TOP_VPP, 9),
+ GATE_VDO1_3(CLK_VDO1_DPINTF, CLK_TOP_VPP, 16),
+ GATE_VDO1_3(CLK_VDO1_DISP_MONITOR_DPINTF, CLK_TOP_VPP, 17),
+ /* VDO1_4 */
+ GATE_VDO1_4(CLK_VDO1_26M_SLOW, CLK_PAD_CLK26M, 8),
+ /* VDO1_5 */
+ GATE_VDO1_5(CLK_VDO1_DPI1_HDMI, CLK_TOP_VPP, 0),
+};
+
+const struct mtk_clk_tree mt8188_vpp0_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = vpp0_clks,
+ .num_gates = ARRAY_SIZE(vpp0_clks),
+};
+
+const struct mtk_clk_tree mt8188_vpp1_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = vpp1_clks,
+ .num_gates = ARRAY_SIZE(vpp1_clks),
+};
+
+const struct mtk_clk_tree mt8188_vdo0_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = vdo0_clks,
+ .num_gates = ARRAY_SIZE(vdo0_clks),
+};
+
+const struct mtk_clk_tree mt8188_vdo1_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = vdo1_clks,
+ .num_gates = ARRAY_SIZE(vdo1_clks),
};
-static const struct udevice_id mt8188_imp_iic_wrap_c_compat[] = {
- { .compatible = "mediatek,mt8188-imp-iic-wrap-c", },
+static const struct udevice_id mt8188_apmixed_compat[] = {
+ {
+ .compatible = "mediatek,mt8188-apmixedsys",
+ .data = (ulong)&mt8188_apmixedsys_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt8188_imp_iic_wrap_w_compat[] = {
- { .compatible = "mediatek,mt8188-imp-iic-wrap-w", },
+static const struct udevice_id mt8188_topckgen_compat[] = {
+ {
+ .compatible = "mediatek,mt8188-topckgen",
+ .data = (ulong)&mt8188_topckgen_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt8188_imp_iic_wrap_en_compat[] = {
- { .compatible = "mediatek,mt8188-imp-iic-wrap-en", },
+static const struct udevice_id of_match_mt8188_clk[] = {
+ {
+ .compatible = "mediatek,mt8188-infracfg-ao",
+ .data = (ulong)&mt8188_infracfg_ao_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-pericfg-ao",
+ .data = (ulong)&mt8188_pericfg_ao_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-imp-iic-wrap-c",
+ .data = (ulong)&mt8188_imp_iic_wrap_c_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-imp-iic-wrap-w",
+ .data = (ulong)&mt8188_imp_iic_wrap_w_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-imp-iic-wrap-en",
+ .data = (ulong)&mt8188_imp_iic_wrap_en_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-vppsys0",
+ .data = (ulong)&mt8188_vpp0_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-vppsys1",
+ .data = (ulong)&mt8188_vpp1_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-vdosys0",
+ .data = (ulong)&mt8188_vdo0_clk_tree,
+ },
+ {
+ .compatible = "mediatek,mt8188-vdosys1",
+ .data = (ulong)&mt8188_vdo1_clk_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8188_clk_apmixedsys) = {
.name = "mt8188-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8188_apmixed_compat,
- .probe = mt8188_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8188_clk_topckgen) = {
.name = "mt8188-topckgen",
.id = UCLASS_CLK,
.of_match = mt8188_topckgen_compat,
- .probe = mt8188_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infracfg_ao) = {
- .name = "mt8188-infracfg-ao",
- .id = UCLASS_CLK,
- .of_match = mt8188_infracfg_ao_compat,
- .probe = mt8188_infracfg_ao_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_pericfg_ao) = {
- .name = "mt8188-pericfg-ao",
- .id = UCLASS_CLK,
- .of_match = mt8188_pericfg_ao_compat,
- .probe = mt8188_pericfg_ao_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_imp_iic_wrap_c) = {
- .name = "mt8188-imp_iic_wrap_c",
+U_BOOT_DRIVER(mt8188_clk) = {
+ .name = "mt8188-clk",
.id = UCLASS_CLK,
- .of_match = mt8188_imp_iic_wrap_c_compat,
- .probe = mt8188_imp_iic_wrap_c_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_imp_iic_wrap_w) = {
- .name = "mt8188-imp_iic_wrap_w",
- .id = UCLASS_CLK,
- .of_match = mt8188_imp_iic_wrap_w_compat,
- .probe = mt8188_imp_iic_wrap_w_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_imp_iic_wrap_en) = {
- .name = "mt8188-imp_iic_wrap_en",
- .id = UCLASS_CLK,
- .of_match = mt8188_imp_iic_wrap_en_compat,
- .probe = mt8188_imp_iic_wrap_en_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt8188_clk,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8189.c b/drivers/clk/mediatek/clk-mt8189.c
index d11947ee461..15e040569e7 100644
--- a/drivers/clk/mediatek/clk-mt8189.c
+++ b/drivers/clk/mediatek/clk-mt8189.c
@@ -1898,6 +1898,7 @@ static const struct mtk_gate_regs vlpcfg_ao_regs = {
* arbitrary parent trees.
*/
#define CLK_PARENT_VLP_CK CLK_PARENT_INFRASYS
+#define MTK_CLK_TREE_VLP_CK MTK_CLK_TREE_INFRASYS
#define GATE_VLPCFG_AO(id, parent, shift, flags) \
GATE_FLAGS(id, parent, &vlpcfg_ao_regs, shift, flags | CLK_GATE_NO_SETCLR_INV)
@@ -1915,8 +1916,8 @@ static const struct mtk_gate vlpcfg_ao_clks[] = {
GATE_VLPCFG_AO_VLP(CLK_VLPCFG_REG_SCP, CLK_VLP_CK_SCP_SEL, 28),
GATE_VLPCFG_AO_EXT(CLK_VLPCFG_REG_RG_R_APXGPT_26M, CLK_PAD_CLK26M, 24),
GATE_VLPCFG_AO_EXT(CLK_VLPCFG_REG_DPMSRCK_TEST, CLK_PAD_CLK26M, 23),
- GATE_VLPCFG_AO_VLP(CLK_VLPCFG_REG_RG_DPMSRRTC_TEST, CLK_PAD_CLK32K, 22),
- GATE_VLPCFG_AO_VLP(CLK_VLPCFG_REG_DPMSRULP_TEST, CLK_TOP_OSC_D10, 21),
+ GATE_VLPCFG_AO_EXT(CLK_VLPCFG_REG_RG_DPMSRRTC_TEST, CLK_PAD_CLK32K, 22),
+ GATE_VLPCFG_AO_TOP(CLK_VLPCFG_REG_DPMSRULP_TEST, CLK_TOP_OSC_D10, 21),
GATE_VLPCFG_AO_VLP(CLK_VLPCFG_REG_SPMI_P_MST, CLK_VLP_CK_SPMI_P_MST_SEL, 20),
GATE_VLPCFG_AO_EXT(CLK_VLPCFG_REG_SPMI_P_MST_32K, CLK_PAD_CLK32K, 18),
GATE_VLPCFG_AO_VLP(CLK_VLPCFG_REG_PMIF_SPMI_P_SYS, CLK_VLP_CK_PWRAP_ULPOSC_SEL, 13),
@@ -1939,6 +1940,7 @@ static const struct mtk_clk_tree mt8189_apmixedsys_clk_tree = {
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
.num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
};
static const struct mtk_clk_tree mt8189_topckgen_clk_tree = {
@@ -1953,6 +1955,7 @@ static const struct mtk_clk_tree mt8189_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
.num_gates = ARRAY_SIZE(top_gates),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_clk_tree mt8189_vlpckgen_clk_tree = {
@@ -1964,114 +1967,97 @@ static const struct mtk_clk_tree mt8189_vlpckgen_clk_tree = {
.gates = vlp_ck_gates,
.num_muxes = ARRAY_SIZE(vlp_ck_muxes),
.num_gates = ARRAY_SIZE(vlp_ck_gates),
+ .type = MTK_CLK_TREE_VLP_CK,
};
static const struct udevice_id mt8189_apmixed[] = {
- { .compatible = "mediatek,mt8189-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8189-apmixedsys",
+ .data = (ulong)&mt8189_apmixedsys_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8189_topckgen_compat[] = {
- { .compatible = "mediatek,mt8189-topckgen", },
+ {
+ .compatible = "mediatek,mt8189-topckgen",
+ .data = (ulong)&mt8189_topckgen_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8189_vlpckgen[] = {
- { .compatible = "mediatek,mt8189-vlpckgen", },
+ {
+ .compatible = "mediatek,mt8189-vlpckgen",
+ .data = (ulong)&mt8189_vlpckgen_clk_tree,
+ },
{ }
};
-struct mt8189_gate_clk_data {
- const struct mtk_gate *gates;
- int num_gates;
-};
-
-#define GATE_CLK_DATA(name) \
-static const struct mt8189_gate_clk_data name##_data = { \
- .gates = name, .num_gates = ARRAY_SIZE(name) \
+#define GATE_CLK_TREE(_name) \
+static const struct mtk_clk_tree _name##_tree = { \
+ .ext_clk_rates = ext_clock_rates, \
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates), \
+ .gates = _name, \
+ .num_gates = ARRAY_SIZE(_name), \
+ .gates_offs = _name[0].id, \
}
-GATE_CLK_DATA(perao_clks);
-GATE_CLK_DATA(imp_clks);
-GATE_CLK_DATA(mm_clks);
-GATE_CLK_DATA(mminfra_config_clks);
-GATE_CLK_DATA(ufs_config_ao_clks);
-GATE_CLK_DATA(ufs_config_pdn_clks);
-GATE_CLK_DATA(vlpcfg_ao_clks);
+GATE_CLK_TREE(perao_clks);
+GATE_CLK_TREE(imp_clks);
+GATE_CLK_TREE(mm_clks);
+GATE_CLK_TREE(mminfra_config_clks);
+GATE_CLK_TREE(ufs_config_ao_clks);
+GATE_CLK_TREE(ufs_config_pdn_clks);
+GATE_CLK_TREE(vlpcfg_ao_clks);
static const struct udevice_id of_match_mt8189_clk_gate[] = {
- { .compatible = "mediatek,mt8189-peri-ao", .data = (ulong)&perao_clks_data },
- { .compatible = "mediatek,mt8189-iic-wrap", .data = (ulong)&imp_clks_data },
- { .compatible = "mediatek,mt8189-dispsys", .data = (ulong)&mm_clks_data },
- { .compatible = "mediatek,mt8189-mm-infra", .data = (ulong)&mminfra_config_clks_data },
- { .compatible = "mediatek,mt8189-ufscfg-ao", .data = (ulong)&ufs_config_ao_clks_data },
- { .compatible = "mediatek,mt8189-ufscfg-pdn", .data = (ulong)&ufs_config_pdn_clks_data },
- { .compatible = "mediatek,mt8189-vlpcfg-ao", .data = (ulong)&vlpcfg_ao_clks_data },
+ { .compatible = "mediatek,mt8189-peri-ao", .data = (ulong)&perao_clks_tree },
+ { .compatible = "mediatek,mt8189-iic-wrap", .data = (ulong)&imp_clks_tree },
+ { .compatible = "mediatek,mt8189-dispsys", .data = (ulong)&mm_clks_tree },
+ { .compatible = "mediatek,mt8189-mm-infra", .data = (ulong)&mminfra_config_clks_tree },
+ { .compatible = "mediatek,mt8189-ufscfg-ao", .data = (ulong)&ufs_config_ao_clks_tree },
+ { .compatible = "mediatek,mt8189-ufscfg-pdn", .data = (ulong)&ufs_config_pdn_clks_tree },
+ { .compatible = "mediatek,mt8189-vlpcfg-ao", .data = (ulong)&vlpcfg_ao_clks_tree },
{ }
};
-static int mt8189_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8189_apmixedsys_clk_tree);
-}
-
-static int mt8189_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8189_topckgen_clk_tree);
-}
-
-static int mt8189_infrasys_probe(struct udevice *dev)
-{
- return mtk_common_clk_infrasys_init(dev, &mt8189_vlpckgen_clk_tree);
-}
-
-static int mt8189_clk_gate_probe(struct udevice *dev)
-{
- struct mt8189_gate_clk_data *data;
-
- data = (void *)dev_get_driver_data(dev);
-
- return mtk_common_clk_gate_init(dev, &mt8189_topckgen_clk_tree,
- data->gates, data->num_gates,
- data->gates[0].id);
-}
-
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8189_clk_apmixedsys) = {
.name = "mt8189-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8189_apmixed,
- .probe = mt8189_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8189_clk_topckgen) = {
.name = "mt8189-topckgen",
.id = UCLASS_CLK,
.of_match = mt8189_topckgen_compat,
- .probe = mt8189_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_vlpckgen) = {
+U_BOOT_DRIVER(mt8189_clk_vlpckgen) = {
.name = "mt8189-vlpckgen",
.id = UCLASS_CLK,
.of_match = mt8189_vlpckgen,
- .probe = mt8189_infrasys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_infrasys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_gate) = {
+U_BOOT_DRIVER(mt8189_clk_gate) = {
.name = "mt8189-gate-clk",
.id = UCLASS_CLK,
.of_match = of_match_mt8189_clk_gate,
- .probe = mt8189_clk_gate_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8195.c b/drivers/clk/mediatek/clk-mt8195.c
index 37cceb5f32b..de40821100e 100644
--- a/drivers/clk/mediatek/clk-mt8195.c
+++ b/drivers/clk/mediatek/clk-mt8195.c
@@ -101,6 +101,7 @@ static const struct mtk_clk_tree mt8195_apmixedsys_clk_tree = {
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
.num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
};
#define FIXED_CLK0(_id, _rate) \
@@ -1423,6 +1424,7 @@ static const struct mtk_clk_tree mt8195_topckgen_clk_tree = {
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
.num_gates = ARRAY_SIZE(top_cg_clks),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
static const struct mtk_gate_regs infra_ao0_cg_regs = {
@@ -1597,66 +1599,60 @@ static const struct mtk_gate infra_ao_clks[] = {
static const struct mtk_clk_tree mt8195_infracfg_ao_clk_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = infra_ao_clks,
+ .num_gates = ARRAY_SIZE(infra_ao_clks),
};
-static int mt8195_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8195_apmixedsys_clk_tree);
-}
-
-static int mt8195_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8195_topckgen_clk_tree);
-}
-
-static int mt8195_infra_ao_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8195_infracfg_ao_clk_tree,
- infra_ao_clks,
- ARRAY_SIZE(infra_ao_clks), 0);
-}
-
static const struct udevice_id mt8195_apmixed[] = {
- { .compatible = "mediatek,mt8195-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8195-apmixedsys",
+ .data = (ulong)&mt8195_apmixedsys_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8195_topckgen_compat[] = {
- { .compatible = "mediatek,mt8195-topckgen", },
+ {
+ .compatible = "mediatek,mt8195-topckgen",
+ .data = (ulong)&mt8195_topckgen_clk_tree,
+ },
{ }
};
static const struct udevice_id of_match_clk_mt8195_infra_ao[] = {
- { .compatible = "mediatek,mt8195-infracfg_ao", },
+ {
+ .compatible = "mediatek,mt8195-infracfg_ao",
+ .data = (ulong)&mt8195_infracfg_ao_clk_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8195_clk_apmixedsys) = {
.name = "mt8195-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8195_apmixed,
- .probe = mt8195_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8195_clk_topckgen) = {
.name = "mt8195-topckgen",
.id = UCLASS_CLK,
.of_match = mt8195_topckgen_compat,
- .probe = mt8195_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infra_ao) = {
+U_BOOT_DRIVER(mt8195_clk_infra_ao) = {
.name = "mt8195-infra_ao",
.id = UCLASS_CLK,
.of_match = of_match_clk_mt8195_infra_ao,
- .probe = mt8195_infra_ao_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8365.c b/drivers/clk/mediatek/clk-mt8365.c
index eb94b86622c..3fa030d7218 100644
--- a/drivers/clk/mediatek/clk-mt8365.c
+++ b/drivers/clk/mediatek/clk-mt8365.c
@@ -79,6 +79,7 @@ static const struct mtk_clk_tree mt8365_apmixed_tree = {
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
.num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
};
/* topckgen */
@@ -595,6 +596,7 @@ static const struct mtk_clk_tree mt8365_topckgen_tree = {
.num_fdivs = ARRAY_SIZE(top_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
.num_gates = ARRAY_SIZE(top_clk_gates),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
/* infracfg */
@@ -755,65 +757,60 @@ static const struct mtk_gate ifr_clks[] = {
static const struct mtk_clk_tree mt8365_infracfg_tree = {
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = ifr_clks,
+ .num_gates = ARRAY_SIZE(ifr_clks),
};
-static int mt8365_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8365_apmixed_tree);
-}
-
-static int mt8365_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8365_topckgen_tree);
-}
-
-static int mt8365_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8365_infracfg_tree, ifr_clks,
- ARRAY_SIZE(ifr_clks), 0);
-}
-
static const struct udevice_id mt8365_apmixed_compat[] = {
- { .compatible = "mediatek,mt8365-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8365-apmixedsys",
+ .data = (ulong)&mt8365_apmixed_tree,
+ },
{ }
};
static const struct udevice_id mt8365_topckgen_compat[] = {
- { .compatible = "mediatek,mt8365-topckgen", },
+ {
+ .compatible = "mediatek,mt8365-topckgen",
+ .data = (ulong)&mt8365_topckgen_tree,
+ },
{ }
};
static const struct udevice_id mt8365_infracfg_compat[] = {
- { .compatible = "mediatek,mt8365-infracfg", },
+ {
+ .compatible = "mediatek,mt8365-infracfg",
+ .data = (ulong)&mt8365_infracfg_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8365_clk_apmixedsys) = {
.name = "mt8365-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8365_apmixed_compat,
- .probe = mt8365_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8365_clk_topckgen) = {
.name = "mt8365-topckgen",
.id = UCLASS_CLK,
.of_match = mt8365_topckgen_compat,
- .probe = mt8365_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
+U_BOOT_DRIVER(mt8365_clk_infracfg) = {
.name = "mt8365-infracfg",
.id = UCLASS_CLK,
.of_match = mt8365_infracfg_compat,
- .probe = mt8365_infracfg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8512.c b/drivers/clk/mediatek/clk-mt8512.c
index d6e58be8e22..a0beae8fa5f 100644
--- a/drivers/clk/mediatek/clk-mt8512.c
+++ b/drivers/clk/mediatek/clk-mt8512.c
@@ -792,100 +792,97 @@ static const struct mtk_gate infra_clks[] = {
GATE_INFRA5(CLK_INFRA_USB_XHCI, CLK_TOP_SSUSB_XHCI_SEL, 11),
};
-static const struct mtk_clk_tree mt8512_clk_tree = {
+static const struct mtk_clk_tree mt8512_apmixed_clk_tree = {
.pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .plls = apmixed_plls,
+ .num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
+};
+
+static const struct mtk_clk_tree mt8512_topckgen_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_SYSPLL1_D2,
.muxes_offs = CLK_TOP_AXI_SEL,
- .plls = apmixed_plls,
.fclks = top_fixed_clks,
.fdivs = top_fixed_divs,
.muxes = top_muxes,
- .num_plls = ARRAY_SIZE(apmixed_plls),
.num_fclks = ARRAY_SIZE(top_fixed_clks),
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
-static int mt8512_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8512_clk_tree);
-}
-
-static int mt8512_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8512_clk_tree);
-}
-
-static int mt8512_topckgen_cg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8512_clk_tree, top_clks,
- ARRAY_SIZE(top_clks), 0);
-}
+static const struct mtk_clk_tree mt8512_topckgen_cg_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = top_clks,
+ .num_gates = ARRAY_SIZE(top_clks),
+};
-static int mt8512_infracfg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8512_clk_tree, infra_clks,
- ARRAY_SIZE(infra_clks), 0);
-}
+static const struct mtk_clk_tree mt8512_infracfg_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = infra_clks,
+ .num_gates = ARRAY_SIZE(infra_clks),
+};
static const struct udevice_id mt8512_apmixed_compat[] = {
- { .compatible = "mediatek,mt8512-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8512-apmixedsys",
+ .data = (ulong)&mt8512_apmixed_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8512_topckgen_compat[] = {
- { .compatible = "mediatek,mt8512-topckgen", },
- { }
-};
-
-static const struct udevice_id mt8512_topckgen_cg_compat[] = {
- { .compatible = "mediatek,mt8512-topckgen-cg", },
+ {
+ .compatible = "mediatek,mt8512-topckgen",
+ .data = (ulong)&mt8512_topckgen_clk_tree,
+ },
{ }
};
-static const struct udevice_id mt8512_infracfg_compat[] = {
- { .compatible = "mediatek,mt8512-infracfg", },
+static const struct udevice_id of_match_mt8512_clk_gate[] = {
+ {
+ .compatible = "mediatek,mt8512-topckgen-cg",
+ .data = (ulong)&mt8512_topckgen_cg_tree,
+ },
+ {
+ .compatible = "mediatek,mt8512-infracfg",
+ .data = (ulong)&mt8512_infracfg_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8512_clk_apmixedsys) = {
.name = "mt8512-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8512_apmixed_compat,
- .probe = mt8512_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8512_clk_topckgen) = {
.name = "mt8512-topckgen",
.id = UCLASS_CLK,
.of_match = mt8512_topckgen_compat,
- .probe = mt8512_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen_cg) = {
- .name = "mt8512-topckgen-cg",
- .id = UCLASS_CLK,
- .of_match = mt8512_topckgen_cg_compat,
- .probe = mt8512_topckgen_cg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
-U_BOOT_DRIVER(mtk_clk_infracfg) = {
- .name = "mt8512-infracfg",
+U_BOOT_DRIVER(mt8512_clk_gate) = {
+ .name = "mt8512-clk-gate",
.id = UCLASS_CLK,
- .of_match = mt8512_infracfg_compat,
- .probe = mt8512_infracfg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .of_match = of_match_mt8512_clk_gate,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c
index 1070dd1551b..ea00b8dbca1 100644
--- a/drivers/clk/mediatek/clk-mt8516.c
+++ b/drivers/clk/mediatek/clk-mt8516.c
@@ -744,79 +744,86 @@ static const struct mtk_gate top_clks[] = {
GATE_TOP5(CLK_TOP_APLL12_DIV6, CLK_TOP_APLL12_CK_DIV6, 8),
};
-static const struct mtk_clk_tree mt8516_clk_tree = {
+static const struct mtk_clk_tree mt8516_apmixed_clk_tree = {
.pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .plls = apmixed_plls,
+ .num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
+};
+
+static const struct mtk_clk_tree mt8516_topckgen_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_DMPLL,
.muxes_offs = CLK_TOP_UART0_SEL,
- .plls = apmixed_plls,
.fclks = top_fixed_clks,
.fdivs = top_fixed_divs,
.muxes = top_muxes,
- .num_plls = ARRAY_SIZE(apmixed_plls),
.num_fclks = ARRAY_SIZE(top_fixed_clks),
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
-static int mt8516_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8516_clk_tree);
-}
-
-static int mt8516_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8516_clk_tree);
-}
-
-static int mt8516_topckgen_cg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8516_clk_tree, top_clks,
- ARRAY_SIZE(top_clks), 0);
-}
+static const struct mtk_clk_tree mt8516_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = top_clks,
+ .num_gates = ARRAY_SIZE(top_clks),
+};
static const struct udevice_id mt8516_apmixed_compat[] = {
- { .compatible = "mediatek,mt8516-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8516-apmixedsys",
+ .data = (ulong)&mt8516_apmixed_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8516_topckgen_compat[] = {
- { .compatible = "mediatek,mt8516-topckgen", },
+ {
+ .compatible = "mediatek,mt8516-topckgen",
+ .data = (ulong)&mt8516_topckgen_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8516_topckgen_cg_compat[] = {
- { .compatible = "mediatek,mt8516-topckgen-cg", },
+ {
+ .compatible = "mediatek,mt8516-topckgen-cg",
+ .data = (ulong)&mt8516_clk_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8516_clk_apmixedsys) = {
.name = "mt8516-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8516_apmixed_compat,
- .probe = mt8516_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8516_clk_topckgen) = {
.name = "mt8516-topckgen",
.id = UCLASS_CLK,
.of_match = mt8516_topckgen_compat,
- .probe = mt8516_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen_cg) = {
+U_BOOT_DRIVER(mt8516_clk_topckgen_cg) = {
.name = "mt8516-topckgen-cg",
.id = UCLASS_CLK,
.of_match = mt8516_topckgen_cg_compat,
- .probe = mt8516_topckgen_cg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mt8518.c b/drivers/clk/mediatek/clk-mt8518.c
index 2b213e720a0..4fef36f458a 100644
--- a/drivers/clk/mediatek/clk-mt8518.c
+++ b/drivers/clk/mediatek/clk-mt8518.c
@@ -1500,79 +1500,86 @@ static const struct mtk_gate top_clks[] = {
GATE_TOP7(CLK_TOP_DISP_DPI, CLK_TOP_DISP_DPI_CK_SEL, 0),
};
-static const struct mtk_clk_tree mt8518_clk_tree = {
+static const struct mtk_clk_tree mt8518_apmixed_clk_tree = {
.pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .plls = apmixed_plls,
+ .num_plls = ARRAY_SIZE(apmixed_plls),
+ .type = MTK_CLK_TREE_APMIXED,
+};
+
+static const struct mtk_clk_tree mt8518_topckgen_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_DMPLL,
.muxes_offs = CLK_TOP_UART0_SEL,
- .plls = apmixed_plls,
.fclks = top_fixed_clks,
.fdivs = top_fixed_divs,
.muxes = top_muxes,
- .num_plls = ARRAY_SIZE(apmixed_plls),
.num_fclks = ARRAY_SIZE(top_fixed_clks),
.num_fdivs = ARRAY_SIZE(top_fixed_divs),
.num_muxes = ARRAY_SIZE(top_muxes),
+ .type = MTK_CLK_TREE_TOPCKGEN,
};
-static int mt8518_apmixedsys_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8518_clk_tree);
-}
-
-static int mt8518_topckgen_probe(struct udevice *dev)
-{
- return mtk_common_clk_init(dev, &mt8518_clk_tree);
-}
-
-static int mt8518_topckgen_cg_probe(struct udevice *dev)
-{
- return mtk_common_clk_gate_init(dev, &mt8518_clk_tree, top_clks,
- ARRAY_SIZE(top_clks), 0);
-}
+static const struct mtk_clk_tree mt8518_clk_tree = {
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
+ .gates = top_clks,
+ .num_gates = ARRAY_SIZE(top_clks),
+};
static const struct udevice_id mt8518_apmixed_compat[] = {
- { .compatible = "mediatek,mt8518-apmixedsys", },
+ {
+ .compatible = "mediatek,mt8518-apmixedsys",
+ .data = (ulong)&mt8518_apmixed_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8518_topckgen_compat[] = {
- { .compatible = "mediatek,mt8518-topckgen", },
+ {
+ .compatible = "mediatek,mt8518-topckgen",
+ .data = (ulong)&mt8518_topckgen_clk_tree,
+ },
{ }
};
static const struct udevice_id mt8518_topckgen_cg_compat[] = {
- { .compatible = "mediatek,mt8518-topckgen-cg", },
+ {
+ .compatible = "mediatek,mt8518-topckgen-cg",
+ .data = (ulong)&mt8518_clk_tree,
+ },
{ }
};
-U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+U_BOOT_DRIVER(mt8518_clk_apmixedsys) = {
.name = "mt8518-apmixedsys",
.id = UCLASS_CLK,
.of_match = mt8518_apmixed_compat,
- .probe = mt8518_apmixedsys_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_apmixedsys_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen) = {
+U_BOOT_DRIVER(mt8518_clk_topckgen) = {
.name = "mt8518-topckgen",
.id = UCLASS_CLK,
.of_match = mt8518_topckgen_compat,
- .probe = mt8518_topckgen_probe,
+ .probe = mtk_clk_probe,
.priv_auto = sizeof(struct mtk_clk_priv),
.ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-U_BOOT_DRIVER(mtk_clk_topckgen_cg) = {
+U_BOOT_DRIVER(mt8518_clk_topckgen_cg) = {
.name = "mt8518-topckgen-cg",
.id = UCLASS_CLK,
.of_match = mt8518_topckgen_cg_compat,
- .probe = mt8518_topckgen_cg_probe,
- .priv_auto = sizeof(struct mtk_cg_priv),
- .ops = &mtk_clk_gate_ops,
+ .probe = mtk_clk_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
.flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 9d0a6cd79cf..13c248c93a6 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -9,6 +9,7 @@
#include <clk-uclass.h>
#include <div64.h>
#include <dm.h>
+#include <dm/device-internal.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/delay.h>
@@ -34,6 +35,88 @@
#define SCP_AXICK_DCM_DIS_EN BIT(0)
#define SCP_AXICK_26M_SEL_EN BIT(4)
+static struct udevice *mtk_clk_providers[MTK_CLK_TREE_NUM_TYPES];
+
+static bool mtk_clk_tree_type_is_provider(enum mtk_clk_tree_type type)
+{
+ return type != MTK_CLK_TREE_NONE && type < MTK_CLK_TREE_NUM_TYPES;
+}
+
+static enum mtk_clk_tree_type mtk_clk_tree_type_from_parent_flags(u16 flags)
+{
+ switch (flags & CLK_PARENT_MASK) {
+ case CLK_PARENT_APMIXED:
+ return MTK_CLK_TREE_APMIXED;
+ case CLK_PARENT_TOPCKGEN:
+ return MTK_CLK_TREE_TOPCKGEN;
+ case CLK_PARENT_INFRASYS:
+ return MTK_CLK_TREE_INFRASYS;
+ default:
+ return MTK_CLK_TREE_NONE;
+ }
+}
+
+static struct udevice *mtk_clk_tree_get_provider(enum mtk_clk_tree_type type)
+{
+ if (!mtk_clk_tree_type_is_provider(type))
+ return NULL;
+
+ if (!mtk_clk_providers[type]) {
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ /* Lazily probe and register the requested provider. */
+ ret = uclass_get(UCLASS_CLK, &uc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ uclass_foreach_dev(dev, uc) {
+ const struct mtk_clk_tree *tree;
+ const void *ops;
+
+ ops = dev_get_driver_ops(dev);
+ if (ops != &mtk_clk_apmixedsys_ops &&
+ ops != &mtk_clk_fixed_pll_ops &&
+ ops != &mtk_clk_topckgen_ops &&
+ ops != &mtk_clk_infrasys_ops)
+ continue;
+
+ tree = (const void *)dev_get_driver_data(dev);
+ if (tree->type != type)
+ continue;
+
+ /* Probe will add it to mtk_clk_providers[type]. */
+ ret = device_probe(dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ break;
+ }
+ }
+
+ return mtk_clk_providers[type] ?: ERR_PTR(-ENOENT);
+}
+
+static struct udevice *mtk_clk_parent_get_provider(u16 flags)
+{
+ return mtk_clk_tree_get_provider(mtk_clk_tree_type_from_parent_flags(flags));
+}
+
+static int mtk_clk_tree_register_provider(struct udevice *dev,
+ const struct mtk_clk_tree *tree)
+{
+ if (!mtk_clk_tree_type_is_provider(tree->type))
+ return 0;
+
+ if (mtk_clk_providers[tree->type])
+ return -EEXIST;
+
+ mtk_clk_providers[tree->type] = dev;
+
+ return 0;
+}
+
/* shared functions */
static const int mtk_common_clk_of_xlate(struct clk *clk,
@@ -207,50 +290,16 @@ static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
static ulong mtk_find_parent_rate(struct mtk_clk_priv *priv, struct clk *clk,
const int parent, u16 flags)
{
- struct udevice *parent_dev;
-
- switch (flags & CLK_PARENT_MASK) {
- case CLK_PARENT_APMIXED:
- /* APMIXEDSYS can be parent or grandparent. */
- if (dev_get_driver_ops(clk->dev) == &mtk_clk_apmixedsys_ops ||
- dev_get_driver_ops(clk->dev) == &mtk_clk_fixed_pll_ops) {
- parent_dev = clk->dev;
- } else if (dev_get_driver_ops(priv->parent) == &mtk_clk_apmixedsys_ops ||
- dev_get_driver_ops(priv->parent) == &mtk_clk_fixed_pll_ops) {
- parent_dev = priv->parent;
- } else {
- struct udevice *grandparent_dev = dev_get_parent(priv->parent);
-
- if (dev_get_driver_ops(grandparent_dev) == &mtk_clk_apmixedsys_ops ||
- dev_get_driver_ops(grandparent_dev) == &mtk_clk_fixed_pll_ops)
- parent_dev = grandparent_dev;
- else
- return -EINVAL;
- }
- break;
- case CLK_PARENT_TOPCKGEN:
- if (dev_get_driver_ops(clk->dev) == &mtk_clk_topckgen_ops)
- parent_dev = clk->dev;
- else if (dev_get_driver_ops(priv->parent) == &mtk_clk_topckgen_ops)
- parent_dev = priv->parent;
- else
- return -EINVAL;
+ struct udevice *pdev;
- break;
- case CLK_PARENT_INFRASYS:
- if (dev_get_driver_ops(clk->dev) != &mtk_clk_infrasys_ops)
- return -EINVAL;
-
- parent_dev = clk->dev;
- break;
- case CLK_PARENT_EXT:
+ if ((flags & CLK_PARENT_MASK) == CLK_PARENT_EXT)
return mtk_ext_clock_get_rate(priv->tree, parent);
- default:
- parent_dev = NULL;
- break;
- }
- return mtk_clk_find_parent_rate(clk, parent, parent_dev);
+ pdev = mtk_clk_parent_get_provider(flags);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return mtk_clk_find_parent_rate(clk, parent, pdev);
}
static ulong mtk_clk_mux_get_rate(struct clk *clk, u32 off)
@@ -306,11 +355,6 @@ static int mtk_clk_mux_set_parent(void __iomem *base, u32 parent,
}
#if CONFIG_IS_ENABLED(CMD_CLK)
-static void mtk_clk_print_dev_parent(struct udevice *parent)
-{
- printf("Parent device: %s %s\n", parent->driver->name, parent->name);
-}
-
static void mtk_clk_print_mapped_id(int unmapped_id, int mapped_id, bool has_map)
{
/*
@@ -663,8 +707,6 @@ static void mtk_apmixedsys_dump(struct udevice *dev)
const struct mtk_clk_tree *tree = priv->tree;
u32 i;
- mtk_clk_print_dev_parent(priv->parent);
-
for (i = 0; i < tree->num_plls; i++) {
const struct mtk_pll_data *pll = &tree->plls[i];
@@ -869,8 +911,6 @@ static void mtk_topckgen_dump(struct udevice *dev)
const struct mtk_clk_tree *tree = priv->tree;
u32 i;
- mtk_clk_print_dev_parent(priv->parent);
-
for (i = 0; i < tree->num_fclks; i++) {
const struct mtk_fixed_clk *fclk = &tree->fclks[i];
@@ -1005,8 +1045,6 @@ static void mtk_infrasys_dump(struct udevice *dev)
const struct mtk_clk_tree *tree = priv->tree;
u32 i;
- mtk_clk_print_dev_parent(priv->parent);
-
for (i = 0; i < tree->num_fdivs; i++) {
const struct mtk_fixed_factor *fdiv = &tree->fdivs[i];
@@ -1036,99 +1074,6 @@ static void mtk_infrasys_dump(struct udevice *dev)
}
#endif
-/* CG functions */
-
-static const int mtk_clk_gate_of_xlate(struct clk *clk,
- struct ofnode_phandle_args *args)
-{
- struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
- const struct mtk_clk_tree *tree = priv->tree;
- int ret;
-
- ret = mtk_common_clk_of_xlate(clk, args, tree);
- if (ret)
- return ret;
-
- if (clk->id >= priv->gates_offs &&
- clk->id < priv->gates_offs + priv->num_gates)
- return 0;
-
- return -ENOENT;
-}
-
-static int mtk_clk_gate_enable(struct clk *clk)
-{
- struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
- const struct mtk_gate *gate;
-
- if (clk->id < priv->gates_offs)
- return -EINVAL;
-
- gate = &priv->gates[clk->id - priv->gates_offs];
- return mtk_gate_enable(priv->base, gate);
-}
-
-static int mtk_clk_gate_disable(struct clk *clk)
-{
- struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
- const struct mtk_gate *gate;
-
- if (clk->id < priv->gates_offs)
- return -EINVAL;
-
- gate = &priv->gates[clk->id - priv->gates_offs];
- return mtk_gate_disable(priv->base, gate);
-}
-
-static ulong mtk_clk_gate_get_rate(struct clk *clk)
-{
- struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
- struct udevice *parent = priv->parent;
- const struct mtk_gate *gate;
-
- if (clk->id < priv->gates_offs)
- return -EINVAL;
-
- gate = &priv->gates[clk->id - priv->gates_offs];
- /*
- * With requesting a TOPCKGEN parent, make sure the dev parent
- * is actually topckgen. This might not be the case for an
- * infracfg-ao implementation where:
- * parent = infracfg
- * parent->parent = topckgen
- */
- if (gate->flags & CLK_PARENT_TOPCKGEN &&
- parent->driver != DM_DRIVER_GET(mtk_clk_topckgen)) {
- priv = dev_get_priv(parent);
- parent = priv->parent;
- } else if (gate->flags & CLK_PARENT_EXT) {
- return mtk_ext_clock_get_rate(priv->tree, gate->parent);
- }
-
- return mtk_clk_find_parent_rate(clk, gate->parent, parent);
-}
-
-#if CONFIG_IS_ENABLED(CMD_CLK)
-static void mtk_clk_gate_dump(struct udevice *dev)
-{
- struct mtk_cg_priv *priv = dev_get_priv(dev);
- const struct mtk_clk_tree *tree = priv->tree;
- u32 i;
-
- mtk_clk_print_dev_parent(priv->parent);
-
- for (i = 0; i < priv->num_gates; i++) {
- const struct mtk_gate *gate = &priv->gates[i];
-
- printf("[GATE%u] DT: %u", i, gate->id);
- mtk_clk_print_mapped_id(gate->id, i + priv->gates_offs, tree->id_offs_map);
- mtk_clk_print_rate(dev, i + priv->gates_offs);
- mtk_clk_print_single_parent(gate->parent, gate->flags);
- printf("\n");
- }
-}
-#endif
-
const struct clk_ops mtk_clk_apmixedsys_ops = {
.of_xlate = mtk_apmixedsys_of_xlate,
.enable = mtk_apmixedsys_enable,
@@ -1172,81 +1117,16 @@ const struct clk_ops mtk_clk_infrasys_ops = {
#endif
};
-const struct clk_ops mtk_clk_gate_ops = {
- .of_xlate = mtk_clk_gate_of_xlate,
- .enable = mtk_clk_gate_enable,
- .disable = mtk_clk_gate_disable,
- .get_rate = mtk_clk_gate_get_rate,
-#if CONFIG_IS_ENABLED(CMD_CLK)
- .dump = mtk_clk_gate_dump,
-#endif
-};
-
-static int mtk_common_clk_init_drv(struct udevice *dev,
- const struct mtk_clk_tree *tree,
- const struct driver *drv)
+int mtk_clk_probe(struct udevice *dev)
{
struct mtk_clk_priv *priv = dev_get_priv(dev);
- struct udevice *parent;
- int ret;
+ const struct mtk_clk_tree *tree = (void *)dev_get_driver_data(dev);
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
return -ENOENT;
- ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
- if (ret || !parent) {
- ret = uclass_get_device_by_driver(UCLASS_CLK, drv, &parent);
- if (ret || !parent)
- return -ENOENT;
- }
-
- priv->parent = parent;
priv->tree = tree;
- return 0;
-}
-
-int mtk_common_clk_init(struct udevice *dev,
- const struct mtk_clk_tree *tree)
-{
- return mtk_common_clk_init_drv(dev, tree,
- DM_DRIVER_GET(mtk_clk_apmixedsys));
-}
-
-int mtk_common_clk_infrasys_init(struct udevice *dev,
- const struct mtk_clk_tree *tree)
-{
- return mtk_common_clk_init_drv(dev, tree,
- DM_DRIVER_GET(mtk_clk_topckgen));
-}
-
-int mtk_common_clk_gate_init(struct udevice *dev,
- const struct mtk_clk_tree *tree,
- const struct mtk_gate *gates, int num_gates,
- int gates_offs)
-{
- struct mtk_cg_priv *priv = dev_get_priv(dev);
- struct udevice *parent;
- int ret;
-
- priv->base = dev_read_addr_ptr(dev);
- if (!priv->base)
- return -ENOENT;
-
- ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
- if (ret || !parent) {
- ret = uclass_get_device_by_driver(UCLASS_CLK,
- DM_DRIVER_GET(mtk_clk_topckgen), &parent);
- if (ret || !parent)
- return -ENOENT;
- }
-
- priv->parent = parent;
- priv->tree = tree;
- priv->gates = gates;
- priv->num_gates = num_gates;
- priv->gates_offs = gates_offs;
-
- return 0;
+ return mtk_clk_tree_register_provider(dev, tree);
}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index b39a62edc43..9244542a2a5 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -32,6 +32,15 @@
#define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
+/* These get matched to CLK_PARENT_* when looking up parent clocks. */
+enum mtk_clk_tree_type {
+ MTK_CLK_TREE_NONE,
+ MTK_CLK_TREE_APMIXED,
+ MTK_CLK_TREE_TOPCKGEN,
+ MTK_CLK_TREE_INFRASYS,
+ MTK_CLK_TREE_NUM_TYPES
+};
+
/* struct mtk_pll_data - hardware-specific PLLs data */
struct mtk_pll_data {
/* unmapped ID of clock */
@@ -261,36 +270,20 @@ struct mtk_clk_tree {
const int num_muxes;
const int num_gates;
u32 flags;
+ /* Set this if this tree provides a specific type for parent lookup. */
+ enum mtk_clk_tree_type type;
};
struct mtk_clk_priv {
- struct udevice *parent;
void __iomem *base;
const struct mtk_clk_tree *tree;
};
-struct mtk_cg_priv {
- struct udevice *parent;
- void __iomem *base;
- const struct mtk_clk_tree *tree;
- const struct mtk_gate *gates;
- int num_gates;
- int gates_offs;
-};
-
extern const struct clk_ops mtk_clk_apmixedsys_ops;
extern const struct clk_ops mtk_clk_fixed_pll_ops;
extern const struct clk_ops mtk_clk_topckgen_ops;
extern const struct clk_ops mtk_clk_infrasys_ops;
-extern const struct clk_ops mtk_clk_gate_ops;
-int mtk_common_clk_init(struct udevice *dev,
- const struct mtk_clk_tree *tree);
-int mtk_common_clk_infrasys_init(struct udevice *dev,
- const struct mtk_clk_tree *tree);
-int mtk_common_clk_gate_init(struct udevice *dev,
- const struct mtk_clk_tree *tree,
- const struct mtk_gate *gates, int num_gates,
- int gates_offs);
+int mtk_clk_probe(struct udevice *dev);
#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/renesas/r8a78000-cpg.c b/drivers/clk/renesas/r8a78000-cpg.c
index e9ca06476f6..67d820bbde8 100644
--- a/drivers/clk/renesas/r8a78000-cpg.c
+++ b/drivers/clk/renesas/r8a78000-cpg.c
@@ -105,6 +105,7 @@ struct clk_map_in {
#define GEN5_SCMI_SDK_4_30 0x010c0000
#define GEN5_SCMI_SDK_4_31 0x010d0000
#define GEN5_SCMI_SDK_4_32 0x010e0000
+#define GEN5_SCMI_SDK_4_36 0x01100000
static const struct clk_map_in gen5_clk_map_dt_sdk_4_28[] = {
{ SCP_CLOCK_ID_MDLC_UFS0, 202 },
@@ -186,7 +187,8 @@ static int gen5_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
map = gen5_clk_map_dt_sdk_4_28;
map_size = ARRAY_SIZE(gen5_clk_map_dt_sdk_4_28);
} else if (priv->basever == GEN5_SCMI_SDK_4_31 ||
- priv->basever == GEN5_SCMI_SDK_4_32) {
+ priv->basever == GEN5_SCMI_SDK_4_32 ||
+ priv->basever == GEN5_SCMI_SDK_4_36) {
map = gen5_clk_map_dt_sdk_4_31;
map_size = ARRAY_SIZE(gen5_clk_map_dt_sdk_4_31);
} else {
diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig
new file mode 100644
index 00000000000..25a3c1e4a45
--- /dev/null
+++ b/drivers/clk/spacemit/Kconfig
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2025, Junhui Liu <[email protected]>
+
+config CLK_SPACEMIT
+ bool "Clock support for SpacemiT SoCs"
+ depends on CLK || COMPILE_TEST
+ select REGMAP
+ select LIB_RATIONAL
+ help
+ This enables support clock driver for Spacemit SoC
+ family.
+
+if CLK_SPACEMIT
+
+config CLK_SPACEMIT_K1
+ bool "SpacemiT K1 clock support"
+ select CLK_CCF
+ help
+ This enables support clock driver for Spacemit K1 SoC.
+ It's based on Common Clock Framework.
+
+endif
diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile
new file mode 100644
index 00000000000..824e94d1f74
--- /dev/null
+++ b/drivers/clk/spacemit/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025 Junhui Liu <[email protected]>
+
+obj-$(CONFIG_CLK_SPACEMIT) += clk_ddn.o clk_mix.o clk_pll.o
+
+obj-$(CONFIG_CLK_SPACEMIT_K1) += clk-k1.o
diff --git a/drivers/clk/spacemit/clk-k1.c b/drivers/clk/spacemit/clk-k1.c
new file mode 100644
index 00000000000..07adc126ee3
--- /dev/null
+++ b/drivers/clk/spacemit/clk-k1.c
@@ -0,0 +1,1878 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <regmap.h>
+#include <linux/clk-provider.h>
+#include <soc/spacemit/k1-reset.h>
+#include <soc/spacemit/k1-syscon.h>
+
+#include "clk_common.h"
+#include "clk_ddn.h"
+#include "clk_mix.h"
+#include "clk_pll.h"
+
+#include <dt-bindings/clock/spacemit,k1-syscon.h>
+
+#define K1_PLL_ID 100
+#define K1_MPMU_ID 200
+#define K1_APBC_ID 300
+#define K1_APMU_ID 400
+
+struct spacemit_ccu_data {
+ struct clk **clks;
+ size_t num;
+ unsigned long offset;
+};
+
+/* APBS clocks start, APBS region contains and only contains all PLL clocks */
+
+/*
+ * PLL{1,2} must run at fixed frequencies to provide clocks in correct rates for
+ * peripherals.
+ */
+static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = {
+ CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+CCU_PLL_DEFINE(CLK_PLL1, pll1, pll1, "clock-24m", pll1_rate_tbl,
+ APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, POSR_PLL1_LOCK,
+ CLK_SET_RATE_GATE);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D4, pll1_d4, pll1_d4, "pll1", APBS_PLL1_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D6, pll1_d6, pll1_d6, "pll1", APBS_PLL1_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_FLAGS_DEFINE(CLK_PLL1_D8, pll1_d8, pll1_d8, "pll1",
+ APBS_PLL1_SWCR2, BIT(7), 8, 1, CLK_IS_CRITICAL);
+#else
+static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = {
+ CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),
+};
+
+static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = {
+ CCU_PLL_RATE(1600000000UL, 0x0050cd61, 0x43eaaaab),
+ CCU_PLL_RATE(1800000000UL, 0x0050cd61, 0x4b000000),
+ CCU_PLL_RATE(2000000000UL, 0x0050dd62, 0x2aeaaaab),
+ CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+ CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),
+ CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab),
+};
+
+CCU_PLL_DEFINE(CLK_PLL1, pll1, pll1, "clock-24m", pll1_rate_tbl,
+ APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, POSR_PLL1_LOCK,
+ CLK_SET_RATE_GATE);
+CCU_PLL_DEFINE(CLK_PLL2, pll2, pll2, "clock-24m", pll2_rate_tbl,
+ APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, MPMU_POSR, POSR_PLL2_LOCK,
+ CLK_SET_RATE_GATE);
+CCU_PLL_DEFINE(CLK_PLL3, pll3, pll3, "clock-24m", pll3_rate_tbl,
+ APBS_PLL3_SWCR1, APBS_PLL3_SWCR3, MPMU_POSR, POSR_PLL3_LOCK,
+ CLK_SET_RATE_GATE);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D2, pll1_d2, pll1_d2, "pll1", APBS_PLL1_SWCR2,
+ BIT(1), 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D3, pll1_d3, pll1_d3, "pll1", APBS_PLL1_SWCR2,
+ BIT(2), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D4, pll1_d4, pll1_d4, "pll1", APBS_PLL1_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D5, pll1_d5, pll1_d5, "pll1", APBS_PLL1_SWCR2,
+ BIT(4), 5, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D6, pll1_d6, pll1_d6, "pll1", APBS_PLL1_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D7, pll1_d7, pll1_d7, "pll1", APBS_PLL1_SWCR2,
+ BIT(6), 7, 1);
+CCU_FACTOR_GATE_FLAGS_DEFINE(CLK_PLL1_D8, pll1_d8, pll1_d8, "pll1",
+ APBS_PLL1_SWCR2, BIT(7), 8, 1, CLK_IS_CRITICAL);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D11, pll1_d11_223p4, pll1_d11_223p4, "pll1",
+ APBS_PLL1_SWCR2, BIT(15), 11, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D13, pll1_d13_189, pll1_d13_189, "pll1",
+ APBS_PLL1_SWCR2, BIT(16), 13, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D23, pll1_d23_106p8, pll1_d23_106p8, "pll1",
+ APBS_PLL1_SWCR2, BIT(20), 23, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D64, pll1_d64_38p4, pll1_d64_38p4, "pll1",
+ APBS_PLL1_SWCR2, BIT(0), 64, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D10_AUD, pll1_aud_245p7, pll1_aud_245p7, "pll1",
+ APBS_PLL1_SWCR2, BIT(10), 10, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D100_AUD, pll1_aud_24p5, pll1_aud_24p5, "pll1",
+ APBS_PLL1_SWCR2, BIT(11), 100, 1);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D1, pll2_d1, pll2_d1, "pll2", APBS_PLL2_SWCR2,
+ BIT(0), 1, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D2, pll2_d2, pll2_d2, "pll2", APBS_PLL2_SWCR2,
+ BIT(1), 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D3, pll2_d3, pll2_d3, "pll2", APBS_PLL2_SWCR2,
+ BIT(2), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D4, pll2_d4, pll2_d4, "pll2", APBS_PLL2_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D5, pll2_d5, pll2_d5, "pll2", APBS_PLL2_SWCR2,
+ BIT(4), 5, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D6, pll2_d6, pll2_d6, "pll2", APBS_PLL2_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D7, pll2_d7, pll2_d7, "pll2", APBS_PLL2_SWCR2,
+ BIT(6), 7, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D8, pll2_d8, pll2_d8, "pll2", APBS_PLL2_SWCR2,
+ BIT(7), 8, 1);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D1, pll3_d1, pll3_d1, "pll3", APBS_PLL3_SWCR2,
+ BIT(0), 1, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D2, pll3_d2, pll3_d2, "pll3", APBS_PLL3_SWCR2,
+ BIT(1), 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D3, pll3_d3, pll3_d3, "pll3", APBS_PLL3_SWCR2,
+ BIT(2), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D4, pll3_d4, pll3_d4, "pll3", APBS_PLL3_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D5, pll3_d5, pll3_d5, "pll3", APBS_PLL3_SWCR2,
+ BIT(4), 5, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D6, pll3_d6, pll3_d6, "pll3", APBS_PLL3_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D7, pll3_d7, pll3_d7, "pll3", APBS_PLL3_SWCR2,
+ BIT(6), 7, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D8, pll3_d8, pll3_d8, "pll3", APBS_PLL3_SWCR2,
+ BIT(7), 8, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL3_20, pll3_20, pll3_20, "pll3_d8", 20, 1);
+CCU_FACTOR_DEFINE(CLK_PLL3_40, pll3_40, pll3_40, "pll3_d8", 10, 1);
+CCU_FACTOR_DEFINE(CLK_PLL3_80, pll3_80, pll3_80, "pll3_d8", 5, 1);
+#endif
+/* APBS clocks end */
+
+/* MPMU clocks start */
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+CCU_GATE_DEFINE(CLK_PLL1_614, pll1_d4_614p4, pll1_d4_614p4, "pll1_d4",
+ MPMU_ACGR, BIT(15), 0);
+CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, "pll1_d6",
+ MPMU_ACGR, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8",
+ MPMU_ACGR, BIT(13), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5,
+ "pll1_d4", MPMU_ACGR, BIT(6), 39, 2);
+CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48,
+ "pll1_d4_614p4", MPMU_SUCCR_1,
+ CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
+#else
+CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8",
+ MPMU_ACGR, BIT(13), 0);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_76P8, pll1_d32_76p8, pll1_d32_76p8, "pll1_d8_307p2",
+ 4, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_61P44, pll1_d40_61p44, pll1_d40_61p44,
+ "pll1_d8_307p2", 5, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_153P6, pll1_d16_153p6, pll1_d16_153p6,
+ "pll1_d8", 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_102P4, pll1_d24_102p4, pll1_d24_102p4,
+ "pll1_d8", MPMU_ACGR, BIT(12), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2, pll1_d48_51p2, pll1_d48_51p2,
+ "pll1_d8", MPMU_ACGR, BIT(7), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2_AP, pll1_d48_51p2_ap, pll1_d48_51p2_ap,
+ "pll1_d8", MPMU_ACGR, BIT(11), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_57P6, pll1_m3d128_57p6, pll1_m3d128_57p6,
+ "pll1_d8", MPMU_ACGR, BIT(8), 16, 3);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_25P6, pll1_d96_25p6, pll1_d96_25p6,
+ "pll1_d8", MPMU_ACGR, BIT(4), 12, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8, pll1_d192_12p8, pll1_d192_12p8,
+ "pll1_d8", MPMU_ACGR, BIT(3), 24, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8_WDT, pll1_d192_12p8_wdt, pll1_d192_12p8_wdt,
+ "pll1_d8", MPMU_ACGR, BIT(19), 24, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_6P4, pll1_d384_6p4, pll1_d384_6p4,
+ "pll1_d8", MPMU_ACGR, BIT(2), 48, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_3P2, pll1_d768_3p2, pll1_d768_3p2,
+ "pll1_d384_6p4", 2, 1);
+CCU_FACTOR_DEFINE(CLK_PLL1_1P6, pll1_d1536_1p6, pll1_d1536_1p6,
+ "pll1_d384_6p4", 4, 1);
+CCU_FACTOR_DEFINE(CLK_PLL1_0P8, pll1_d3072_0p8, pll1_d3072_0p8,
+ "pll1_d384_6p4", 8, 1);
+
+CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, "pll1_d6",
+ MPMU_ACGR, BIT(0), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_204P8, pll1_d12_204p8, pll1_d12_204p8,
+ "pll1_d6", MPMU_ACGR, BIT(5), 2, 1);
+
+CCU_GATE_DEFINE(CLK_PLL1_491, pll1_d5_491p52, pll1_d5_491p52, "pll1_d5",
+ MPMU_ACGR, BIT(21), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_245P76, pll1_d10_245p76, pll1_d10_245p76,
+ "pll1_d5", MPMU_ACGR, BIT(18), 2, 1);
+
+CCU_GATE_DEFINE(CLK_PLL1_614, pll1_d4_614p4, pll1_d4_614p4, "pll1_d4",
+ MPMU_ACGR, BIT(15), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_47P26, pll1_d52_47p26, pll1_d52_47p26,
+ "pll1_d4", MPMU_ACGR, BIT(10), 13, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5,
+ "pll1_d4", MPMU_ACGR, BIT(6), 39, 2);
+
+CCU_GATE_DEFINE(CLK_PLL1_819, pll1_d3_819p2, pll1_d3_819p2, "pll1_d3",
+ MPMU_ACGR, BIT(14), 0);
+
+CCU_GATE_DEFINE(CLK_PLL1_1228, pll1_d2_1228p8, pll1_d2_1228p8, "pll1_d2",
+ MPMU_ACGR, BIT(16), 0);
+
+CCU_GATE_DEFINE(CLK_SLOW_UART, slow_uart, slow_uart, "clock-32k", MPMU_ACGR,
+ BIT(1), CLK_IGNORE_UNUSED);
+CCU_DDN_DEFINE(CLK_SLOW_UART1, slow_uart1_14p74, slow_uart1_14p74,
+ "pll1_d16_153p6", MPMU_SUCCR,
+ CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
+CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48,
+ "pll1_d4_614p4", MPMU_SUCCR_1,
+ CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
+
+CCU_GATE_DEFINE(CLK_WDT, wdt_clk, wdt_clk, "pll1_d96_25p6", MPMU_WDTPCR,
+ BIT(1), 0);
+
+CCU_FACTOR_DEFINE(CLK_I2S_153P6, i2s_153p6, i2s_153p6, "pll1_d8_307p2", 2, 1);
+
+static const char * const i2s_153p6_base_parents[] = {
+ "i2s_153p6",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DEFINE(CLK_I2S_153P6_BASE, i2s_153p6_base, i2s_153p6_base,
+ i2s_153p6_base_parents, ARRAY_SIZE(i2s_153p6_base_parents),
+ MPMU_FCCR, 29, 1, 0);
+
+static const char * const i2s_sysclk_src_parents[] = {
+ "pll1_d96_25p6",
+ "i2s_153p6_base"
+};
+
+CCU_MUX_GATE_DEFINE(CLK_I2S_SYSCLK_SRC, i2s_sysclk_src, i2s_sysclk_src,
+ i2s_sysclk_src_parents, ARRAY_SIZE(i2s_sysclk_src_parents),
+ MPMU_ISCCR, 30, 1, BIT(31), 0);
+
+CCU_DDN_DEFINE(CLK_I2S_SYSCLK, i2s_sysclk, i2s_sysclk, "i2s_sysclk_src",
+ MPMU_ISCCR, CCU_DDN_MASK(0, 15), 0, CCU_DDN_MASK(15, 12),
+ 15, 1, 0);
+
+CCU_FACTOR_DEFINE(CLK_I2S_BCLK_FACTOR, i2s_bclk_factor, i2s_bclk_factor,
+ "i2s_sysclk", 2, 1);
+/*
+ * Divider of i2s_bclk always implies a 1/2 factor, which is
+ * described by i2s_bclk_factor.
+ */
+CCU_DIV_GATE_DEFINE(CLK_I2S_BCLK, i2s_bclk, i2s_bclk, "i2s_bclk_factor",
+ MPMU_ISCCR, 27, 2, BIT(29), 0);
+
+static const char * const apb_parents[] = {
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d96_25p6",
+ "pll1_d24_102p4",
+};
+
+CCU_MUX_DEFINE(CLK_APB, apb_clk, apb_clk, apb_parents, ARRAY_SIZE(apb_parents),
+ MPMU_APBCSCR, 0, 2, 0);
+
+CCU_GATE_DEFINE(CLK_WDT_BUS, wdt_bus_clk, wdt_bus_clk, "apb_clk", MPMU_WDTPCR,
+ BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_RIPC, ripc_clk, ripc_clk, "apb_clk", MPMU_RIPCCR, 0x1, 0);
+#endif
+/* MPMU clocks end */
+
+/* APBC clocks start */
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static const char * const uart_clk_parents[] = {
+ "clock-dummy",
+ "clock-dummy",
+ "slow_uart2_48",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_UART0, uart0_clk, uart0_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART1_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+static const char * const twsi_parents[] = {
+ "pll1_d78_31p5",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+/*
+ * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.
+ * Combine functional and bus bits together as a gate to avoid sharing the
+ * write-only register between different clock hardwares.
+ */
+CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, "pll1_d78_31p5",
+ APBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0);
+
+#else
+static const char * const uart_clk_parents[] = {
+ "pll1_m3d128_57p6",
+ "slow_uart1_14p74",
+ "slow_uart2_48",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_UART0, uart0_clk, uart0_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART1_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+static const char * const twsi_parents[] = {
+ "pll1_d78_31p5",
+ "pll1_d48_51p2",
+ "pll1_d40_61p44",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+/*
+ * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.
+ * Combine functional and bus bits together as a gate to avoid sharing the
+ * write-only register between different clock hardwares.
+ */
+CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, "pll1_d78_31p5",
+ APBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0);
+
+CCU_MUX_GATE_DEFINE(CLK_UART2, uart2_clk, uart2_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART2_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART3, uart3_clk, uart3_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART3_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART4, uart4_clk, uart4_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART4_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART5, uart5_clk, uart5_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART5_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART6, uart6_clk, uart6_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART6_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART7, uart7_clk, uart7_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART7_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART8, uart8_clk, uart8_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART8_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART9, uart9_clk, uart9_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART9_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_GPIO, gpio_clk, gpio_clk, "clock-24m", APBC_GPIO_CLK_RST,
+ BIT(1) | BIT(0), 0);
+
+static const char * const pwm_parents[] = {
+ "pll1_d192_12p8",
+ "clock-32k",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_PWM0, pwm0_clk, pwm0_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM0_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM1, pwm1_clk, pwm1_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM1_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM2, pwm2_clk, pwm2_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM2_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM3, pwm3_clk, pwm3_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM3_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM4, pwm4_clk, pwm4_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM4_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM5, pwm5_clk, pwm5_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM5_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM6, pwm6_clk, pwm6_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM6_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM7, pwm7_clk, pwm7_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM7_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM8, pwm8_clk, pwm8_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM8_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM9, pwm9_clk, pwm9_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM9_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM10, pwm10_clk, pwm10_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM10_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM11, pwm11_clk, pwm11_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM11_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM12, pwm12_clk, pwm12_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM12_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM13, pwm13_clk, pwm13_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM13_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM14, pwm14_clk, pwm14_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM14_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM15, pwm15_clk, pwm15_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM15_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM16, pwm16_clk, pwm16_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM16_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM17, pwm17_clk, pwm17_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM17_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM18, pwm18_clk, pwm18_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM18_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM19, pwm19_clk, pwm19_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM19_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+
+static const char * const ssp_parents[] = {
+ "pll1_d384_6p4",
+ "pll1_d192_12p8",
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d768_3p2",
+ "pll1_d1536_1p6",
+ "pll1_d3072_0p8",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_SSP3, ssp3_clk, ssp3_clk, ssp_parents,
+ ARRAY_SIZE(ssp_parents), APBC_SSP3_CLK_RST, 4, 3,
+ BIT(1), 0);
+
+CCU_GATE_DEFINE(CLK_RTC, rtc_clk, rtc_clk, "clock-32k", APBC_RTC_CLK_RST,
+ BIT(7) | BIT(1) | BIT(0), 0);
+
+CCU_MUX_GATE_DEFINE(CLK_TWSI0, twsi0_clk, twsi0_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI0_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI1, twsi1_clk, twsi1_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI1_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI4, twsi4_clk, twsi4_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI4_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI5, twsi5_clk, twsi5_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI5_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI6, twsi6_clk, twsi6_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI6_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI7, twsi7_clk, twsi7_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI7_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+static const char * const timer_parents[] = {
+ "pll1_d192_12p8",
+ "clock-32k",
+ "pll1_d384_6p4",
+ "clock-3m",
+ "clock-1m",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_TIMERS1, timers1_clk, timers1_clk, timer_parents,
+ ARRAY_SIZE(timer_parents), APBC_TIMERS1_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TIMERS2, timers2_clk, timers2_clk, timer_parents,
+ ARRAY_SIZE(timer_parents), APBC_TIMERS2_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_AIB, aib_clk, aib_clk, "clock-24m", APBC_AIB_CLK_RST,
+ BIT(1) | BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_ONEWIRE, onewire_clk, onewire_clk, "clock-24m",
+ APBC_ONEWIRE_CLK_RST, BIT(1) | BIT(0), 0);
+
+/*
+ * When i2s_bclk is selected as the parent clock of sspa,
+ * the hardware requires bit3 to be set
+ */
+CCU_GATE_DEFINE(CLK_SSPA0_I2S_BCLK, sspa0_i2s_bclk, sspa0_i2s_bclk, "i2s_bclk",
+ APBC_SSPA0_CLK_RST, BIT(3), 0);
+CCU_GATE_DEFINE(CLK_SSPA1_I2S_BCLK, sspa1_i2s_bclk, sspa1_i2s_bclk, "i2s_bclk",
+ APBC_SSPA1_CLK_RST, BIT(3), 0);
+
+static const char * const sspa0_parents[] = {
+ "pll1_d384_6p4",
+ "pll1_d192_12p8",
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d768_3p2",
+ "pll1_d1536_1p6",
+ "pll1_d3072_0p8",
+ "sspa0_i2s_bclk",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_SSPA0, sspa0_clk, sspa0_clk, sspa0_parents,
+ ARRAY_SIZE(sspa0_parents), APBC_SSPA0_CLK_RST, 4, 3,
+ BIT(1), 0);
+
+static const char * const sspa1_parents[] = {
+ "pll1_d384_6p4",
+ "pll1_d192_12p8",
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d768_3p2",
+ "pll1_d1536_1p6",
+ "pll1_d3072_0p8",
+ "sspa1_i2s_bclk",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_SSPA1, sspa1_clk, sspa1_clk, sspa1_parents,
+ ARRAY_SIZE(sspa1_parents), APBC_SSPA1_CLK_RST, 4, 3,
+ BIT(1), 0);
+
+CCU_GATE_DEFINE(CLK_DRO, dro_clk, dro_clk, "apb_clk", APBC_DRO_CLK_RST,
+ BIT(1) | BIT(0), 0);
+CCU_GATE_DEFINE(CLK_IR, ir_clk, ir_clk, "apb_clk", APBC_IR_CLK_RST,
+ BIT(1) | BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TSEN, tsen_clk, tsen_clk, "apb_clk", APBC_TSEN_CLK_RST,
+ BIT(1) | BIT(0), 0);
+CCU_GATE_DEFINE(CLK_IPC_AP2AUD, ipc_ap2aud_clk, ipc_ap2aud_clk, "apb_clk",
+ APBC_IPC_AP2AUD_CLK_RST, BIT(1) | BIT(0), 0);
+
+static const char * const can_parents[] = {
+ "pll3_20",
+ "pll3_40",
+ "pll3_80",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CAN0, can0_clk, can0_clk, can_parents,
+ ARRAY_SIZE(can_parents), APBC_CAN0_CLK_RST, 4, 3,
+ BIT(1), 0);
+CCU_GATE_DEFINE(CLK_CAN0_BUS, can0_bus_clk, can0_bus_clk, "clock-24m",
+ APBC_CAN0_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_UART0_BUS, uart0_bus_clk, uart0_bus_clk, "apb_clk",
+ APBC_UART1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART2_BUS, uart2_bus_clk, uart2_bus_clk, "apb_clk",
+ APBC_UART2_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART3_BUS, uart3_bus_clk, uart3_bus_clk, "apb_clk",
+ APBC_UART3_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART4_BUS, uart4_bus_clk, uart4_bus_clk, "apb_clk",
+ APBC_UART4_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART5_BUS, uart5_bus_clk, uart5_bus_clk, "apb_clk",
+ APBC_UART5_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART6_BUS, uart6_bus_clk, uart6_bus_clk, "apb_clk",
+ APBC_UART6_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART7_BUS, uart7_bus_clk, uart7_bus_clk, "apb_clk",
+ APBC_UART7_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART8_BUS, uart8_bus_clk, uart8_bus_clk, "apb_clk",
+ APBC_UART8_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART9_BUS, uart9_bus_clk, uart9_bus_clk, "apb_clk",
+ APBC_UART9_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_GPIO_BUS, gpio_bus_clk, gpio_bus_clk, "apb_clk",
+ APBC_GPIO_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PWM0_BUS, pwm0_bus_clk, pwm0_bus_clk, "apb_clk",
+ APBC_PWM0_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM1_BUS, pwm1_bus_clk, pwm1_bus_clk, "apb_clk",
+ APBC_PWM1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM2_BUS, pwm2_bus_clk, pwm2_bus_clk, "apb_clk",
+ APBC_PWM2_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM3_BUS, pwm3_bus_clk, pwm3_bus_clk, "apb_clk",
+ APBC_PWM3_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM4_BUS, pwm4_bus_clk, pwm4_bus_clk, "apb_clk",
+ APBC_PWM4_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM5_BUS, pwm5_bus_clk, pwm5_bus_clk, "apb_clk",
+ APBC_PWM5_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM6_BUS, pwm6_bus_clk, pwm6_bus_clk, "apb_clk",
+ APBC_PWM6_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM7_BUS, pwm7_bus_clk, pwm7_bus_clk, "apb_clk",
+ APBC_PWM7_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM8_BUS, pwm8_bus_clk, pwm8_bus_clk, "apb_clk",
+ APBC_PWM8_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM9_BUS, pwm9_bus_clk, pwm9_bus_clk, "apb_clk",
+ APBC_PWM9_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM10_BUS, pwm10_bus_clk, pwm10_bus_clk, "apb_clk",
+ APBC_PWM10_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM11_BUS, pwm11_bus_clk, pwm11_bus_clk, "apb_clk",
+ APBC_PWM11_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM12_BUS, pwm12_bus_clk, pwm12_bus_clk, "apb_clk",
+ APBC_PWM12_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM13_BUS, pwm13_bus_clk, pwm13_bus_clk, "apb_clk",
+ APBC_PWM13_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM14_BUS, pwm14_bus_clk, pwm14_bus_clk, "apb_clk",
+ APBC_PWM14_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM15_BUS, pwm15_bus_clk, pwm15_bus_clk, "apb_clk",
+ APBC_PWM15_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM16_BUS, pwm16_bus_clk, pwm16_bus_clk, "apb_clk",
+ APBC_PWM16_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM17_BUS, pwm17_bus_clk, pwm17_bus_clk, "apb_clk",
+ APBC_PWM17_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM18_BUS, pwm18_bus_clk, pwm18_bus_clk, "apb_clk",
+ APBC_PWM18_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM19_BUS, pwm19_bus_clk, pwm19_bus_clk, "apb_clk",
+ APBC_PWM19_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_SSP3_BUS, ssp3_bus_clk, ssp3_bus_clk, "apb_clk",
+ APBC_SSP3_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_RTC_BUS, rtc_bus_clk, rtc_bus_clk, "apb_clk",
+ APBC_RTC_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_TWSI0_BUS, twsi0_bus_clk, twsi0_bus_clk, "apb_clk",
+ APBC_TWSI0_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI1_BUS, twsi1_bus_clk, twsi1_bus_clk, "apb_clk",
+ APBC_TWSI1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI2_BUS, twsi2_bus_clk, twsi2_bus_clk, "apb_clk",
+ APBC_TWSI2_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI4_BUS, twsi4_bus_clk, twsi4_bus_clk, "apb_clk",
+ APBC_TWSI4_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI5_BUS, twsi5_bus_clk, twsi5_bus_clk, "apb_clk",
+ APBC_TWSI5_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI6_BUS, twsi6_bus_clk, twsi6_bus_clk, "apb_clk",
+ APBC_TWSI6_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI7_BUS, twsi7_bus_clk, twsi7_bus_clk, "apb_clk",
+ APBC_TWSI7_CLK_RST, BIT(0), 0);
+CCU_FACTOR_DEFINE(CLK_TWSI8_BUS, twsi8_bus_clk, twsi8_bus_clk, "apb_clk", 1, 1);
+
+CCU_GATE_DEFINE(CLK_TIMERS1_BUS, timers1_bus_clk, timers1_bus_clk, "apb_clk",
+ APBC_TIMERS1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TIMERS2_BUS, timers2_bus_clk, timers2_bus_clk, "apb_clk",
+ APBC_TIMERS2_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_AIB_BUS, aib_bus_clk, aib_bus_clk, "apb_clk",
+ APBC_AIB_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_ONEWIRE_BUS, onewire_bus_clk, onewire_bus_clk, "apb_clk",
+ APBC_ONEWIRE_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_SSPA0_BUS, sspa0_bus_clk, sspa0_bus_clk, "apb_clk",
+ APBC_SSPA0_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_SSPA1_BUS, sspa1_bus_clk, sspa1_bus_clk, "apb_clk",
+ APBC_SSPA1_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_TSEN_BUS, tsen_bus_clk, tsen_bus_clk, "apb_clk",
+ APBC_TSEN_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_IPC_AP2AUD_BUS, ipc_ap2aud_bus_clk, ipc_ap2aud_bus_clk,
+ "apb_clk", APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0);
+#endif
+/* APBC clocks end */
+
+/* APMU clocks start */
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static const char * const pmua_aclk_parents[] = {
+ "clock-dummy",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_FC_DEFINE(CLK_PMUA_ACLK, pmua_aclk, pmua_aclk, pmua_aclk_parents,
+ ARRAY_SIZE(pmua_aclk_parents),
+ APMU_ACLK_CLK_CTRL, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4),
+ 0, 1, 0);
+
+CCU_GATE_DEFINE(CLK_SDH_AXI, sdh_axi_aclk, sdh_axi_aclk, "pmua_aclk",
+ APMU_SDH0_CLK_RES_CTRL, BIT(3), 0);
+
+static const char * const sdh01_parents[] = {
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH0, sdh0_clk, sdh0_clk, sdh01_parents,
+ ARRAY_SIZE(sdh01_parents),
+ APMU_SDH0_CLK_RES_CTRL,
+ APMU_SDH0_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+
+static const char * const sdh2_parents[] = {
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH2, sdh2_clk, sdh2_clk, sdh2_parents,
+ ARRAY_SIZE(sdh2_parents),
+ APMU_SDH2_CLK_RES_CTRL,
+ APMU_SDH2_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+#else
+static const char * const pmua_aclk_parents[] = {
+ "pll1_d10_245p76",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_FC_DEFINE(CLK_PMUA_ACLK, pmua_aclk, pmua_aclk, pmua_aclk_parents,
+ ARRAY_SIZE(pmua_aclk_parents),
+ APMU_ACLK_CLK_CTRL, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4),
+ 0, 1, 0);
+
+static const char * const emmc_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll1_d52_47p26",
+ "pll1_d3_819p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_EMMC, emmc_clk, emmc_clk, emmc_parents,
+ ARRAY_SIZE(emmc_parents),
+ APMU_PMUA_EM_CLK_RES_CTRL,
+ APMU_PMUA_EM_CLK_RES_CTRL, 8, 3, BIT(11),
+ 6, 2, BIT(4), 0);
+CCU_DIV_GATE_DEFINE(CLK_EMMC_X, emmc_x_clk, emmc_x_clk, "pll1_d2_1228p8",
+ APMU_PMUA_EM_CLK_RES_CTRL, 12,
+ 3, BIT(15), 0);
+
+CCU_GATE_DEFINE(CLK_EMMC_BUS, emmc_bus_clk, emmc_bus_clk, "pmua_aclk",
+ APMU_PMUA_EM_CLK_RES_CTRL, BIT(3), 0);
+
+static const char * const cci550_clk_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll2_d3",
+};
+
+CCU_MUX_DIV_FC_DEFINE(CLK_CCI550, cci550_clk, cci550_clk, cci550_clk_parents,
+ ARRAY_SIZE(cci550_clk_parents),
+ APMU_CCI550_CLK_CTRL, APMU_CCI550_CLK_CTRL, 8, 3,
+ BIT(12), 0, 2, CLK_IS_CRITICAL);
+
+static const char * const cpu_c0_hi_clk_parents[] = {
+ "pll3_d2",
+ "pll3_d1",
+};
+
+CCU_MUX_DEFINE(CLK_CPU_C0_HI, cpu_c0_hi_clk, cpu_c0_hi_clk,
+ cpu_c0_hi_clk_parents, ARRAY_SIZE(cpu_c0_hi_clk_parents),
+ APMU_CPU_C0_CLK_CTRL, 13, 1, 0);
+static const char * const cpu_c0_clk_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d2_1228p8",
+ "pll3_d3",
+ "pll2_d3",
+ "cpu_c0_hi_clk",
+};
+
+CCU_MUX_FC_DEFINE(CLK_CPU_C0_CORE, cpu_c0_core_clk, cpu_c0_core_clk,
+ cpu_c0_clk_parents, ARRAY_SIZE(cpu_c0_clk_parents),
+ APMU_CPU_C0_CLK_CTRL, APMU_CPU_C0_CLK_CTRL,
+ BIT(12), 0, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(CLK_CPU_C0_ACE, cpu_c0_ace_clk, cpu_c0_ace_clk,
+ "cpu_c0_core_clk", APMU_CPU_C0_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(CLK_CPU_C0_TCM, cpu_c0_tcm_clk, cpu_c0_tcm_clk,
+ "cpu_c0_core_clk", APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL);
+
+static const char * const cpu_c1_hi_clk_parents[] = {
+ "pll3_d2",
+ "pll3_d1",
+};
+
+CCU_MUX_DEFINE(CLK_CPU_C1_HI, cpu_c1_hi_clk, cpu_c1_hi_clk,
+ cpu_c1_hi_clk_parents, ARRAY_SIZE(cpu_c1_hi_clk_parents),
+ APMU_CPU_C1_CLK_CTRL, 13, 1, 0);
+static const char * const cpu_c1_clk_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d2_1228p8",
+ "pll3_d3",
+ "pll2_d3",
+ "cpu_c1_hi_clk",
+};
+
+CCU_MUX_FC_DEFINE(CLK_CPU_C1_CORE, cpu_c1_core_clk, cpu_c1_core_clk,
+ cpu_c1_clk_parents, ARRAY_SIZE(cpu_c1_clk_parents),
+ APMU_CPU_C1_CLK_CTRL, APMU_CPU_C1_CLK_CTRL,
+ BIT(12), 0, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(CLK_CPU_C1_ACE, cpu_c1_ace_clk, cpu_c1_ace_clk,
+ "cpu_c1_core_clk", APMU_CPU_C1_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);
+
+static const char * const jpg_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d3_819p2",
+ "pll1_d2_1228p8",
+ "pll2_d4",
+ "pll2_d3",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_JPG, jpg_clk, jpg_clk, jpg_parents,
+ ARRAY_SIZE(jpg_parents),
+ APMU_JPG_CLK_RES_CTRL,
+ APMU_JPG_CLK_RES_CTRL,
+ 5, 3, BIT(15), 2, 3, BIT(1), 0);
+
+static const char * const ccic2phy_parents[] = {
+ "pll1_d24_102p4",
+ "pll1_d48_51p2_ap",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CCIC2PHY, ccic2phy_clk, ccic2phy_clk, ccic2phy_parents,
+ ARRAY_SIZE(ccic2phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL,
+ 7, 1, BIT(5), 0);
+
+static const char * const ccic3phy_parents[] = {
+ "pll1_d24_102p4",
+ "pll1_d48_51p2_ap",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CCIC3PHY, ccic3phy_clk, ccic3phy_clk, ccic3phy_parents,
+ ARRAY_SIZE(ccic3phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL,
+ 31, 1, BIT(30), 0);
+
+static const char * const csi_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll2_d2",
+ "pll2_d3",
+ "pll2_d4",
+ "pll1_d2_1228p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CSI, csi_clk, csi_clk, csi_parents,
+ ARRAY_SIZE(csi_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL,
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 20, 3, BIT(15),
+ 16, 3, BIT(4), 0);
+
+static const char * const camm_parents[] = {
+ "pll1_d8_307p2",
+ "pll2_d5",
+ "pll1_d6_409p6",
+ "clock-24m",
+};
+
+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM0, camm0_clk, camm0_clk, camm_parents,
+ ARRAY_SIZE(camm_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,
+ BIT(28), 0);
+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM1, camm1_clk, camm1_clk, camm_parents,
+ ARRAY_SIZE(camm_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,
+ BIT(6), 0);
+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM2, camm2_clk, camm2_clk, camm_parents,
+ ARRAY_SIZE(camm_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,
+ BIT(3), 0);
+
+static const char * const isp_cpp_parents[] = {
+ "pll1_d8_307p2",
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_DEFINE(CLK_ISP_CPP, isp_cpp_clk, isp_cpp_clk, isp_cpp_parents,
+ ARRAY_SIZE(isp_cpp_parents),
+ APMU_ISP_CLK_RES_CTRL, 24, 2, 26, 1,
+ BIT(28), 0);
+static const char * const isp_bus_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d8_307p2",
+ "pll1_d10_245p76",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP_BUS, isp_bus_clk, isp_bus_clk,
+ isp_bus_parents, ARRAY_SIZE(isp_cpp_parents),
+ APMU_ISP_CLK_RES_CTRL,
+ APMU_ISP_CLK_RES_CTRL, 18, 3, BIT(23),
+ 21, 2, BIT(17), 0);
+static const char * const isp_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP, isp_clk, isp_clk, isp_parents,
+ ARRAY_SIZE(isp_parents),
+ APMU_ISP_CLK_RES_CTRL,
+ APMU_ISP_CLK_RES_CTRL,
+ 4, 3, BIT(7), 8, 2, BIT(1), 0);
+
+static const char * const dpumclk_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_MCLK, dpu_mclk, dpu_mclk,
+ dpumclk_parents, ARRAY_SIZE(dpumclk_parents),
+ APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,
+ 1, 4, BIT(29), 5, 3, BIT(0), 0);
+
+static const char * const dpuesc_parents[] = {
+ "pll1_d48_51p2_ap",
+ "pll1_d52_47p26",
+ "pll1_d96_25p6",
+ "pll1_d32_76p8",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_DPU_ESC, dpu_esc_clk, dpu_esc_clk, dpuesc_parents,
+ ARRAY_SIZE(dpuesc_parents), APMU_LCD_CLK_RES_CTRL1, 0, 2,
+ BIT(2), 0);
+
+static const char * const dpubit_parents[] = {
+ "pll1_d3_819p2",
+ "pll2_d2",
+ "pll2_d3",
+ "pll1_d2_1228p8",
+ "pll2_d4",
+ "pll2_d5",
+ "pll2_d7",
+ "pll2_d8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_BIT, dpu_bit_clk, dpu_bit_clk,
+ dpubit_parents, ARRAY_SIZE(dpubit_parents),
+ APMU_LCD_CLK_RES_CTRL1,
+ APMU_LCD_CLK_RES_CTRL1, 17, 3, BIT(31),
+ 20, 3, BIT(16), 0);
+
+static const char * const dpupx_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+ "pll2_d7",
+ "pll2_d8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_PXCLK, dpu_pxclk, dpu_pxclk,
+ dpupx_parents, ARRAY_SIZE(dpupx_parents),
+ APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,
+ 17, 4, BIT(30), 21, 3, BIT(16), 0);
+
+CCU_GATE_DEFINE(CLK_DPU_HCLK, dpu_hclk, dpu_hclk, "pmua_aclk",
+ APMU_LCD_CLK_RES_CTRL1, BIT(5), 0);
+
+static const char * const dpu_spi_parents[] = {
+ "pll1_d8_307p2",
+ "pll1_d6_409p6",
+ "pll1_d10_245p76",
+ "pll1_d11_223p4",
+ "pll1_d13_189",
+ "pll1_d23_106p8",
+ "pll2_d3",
+ "pll2_d5",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_SPI, dpu_spi_clk, dpu_spi_clk,
+ dpu_spi_parents, ARRAY_SIZE(dpu_spi_parents),
+ APMU_LCD_SPI_CLK_RES_CTRL,
+ APMU_LCD_SPI_CLK_RES_CTRL, 8, 3,
+ BIT(7), 12, 3, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_DPU_SPI_HBUS, dpu_spi_hbus_clk, dpu_spi_hbus_clk,
+ "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(3), 0);
+CCU_GATE_DEFINE(CLK_DPU_SPIBUS, dpu_spi_bus_clk, dpu_spi_bus_clk,
+ "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(5), 0);
+CCU_GATE_DEFINE(CLK_DPU_SPI_ACLK, dpu_spi_aclk, dpu_spi_aclk,
+ "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(6), 0);
+
+static const char * const v2d_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d6_409p6",
+ "pll1_d8_307p2",
+ "pll1_d4_614p4",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_V2D, v2d_clk, v2d_clk, v2d_parents,
+ ARRAY_SIZE(v2d_parents),
+ APMU_LCD_CLK_RES_CTRL1,
+ APMU_LCD_CLK_RES_CTRL1, 9, 3, BIT(28), 12, 2,
+ BIT(8), 0);
+
+static const char * const ccic_4x_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll2_d2",
+ "pll2_d3",
+ "pll2_d4",
+ "pll1_d2_1228p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CCIC_4X, ccic_4x_clk, ccic_4x_clk,
+ ccic_4x_parents, ARRAY_SIZE(ccic_4x_parents),
+ APMU_CCIC_CLK_RES_CTRL,
+ APMU_CCIC_CLK_RES_CTRL, 18, 3,
+ BIT(15), 23, 2, BIT(4), 0);
+
+static const char * const ccic1phy_parents[] = {
+ "pll1_d24_102p4",
+ "pll1_d48_51p2_ap",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CCIC1PHY, ccic1phy_clk, ccic1phy_clk, ccic1phy_parents,
+ ARRAY_SIZE(ccic1phy_parents), APMU_CCIC_CLK_RES_CTRL, 7, 1,
+ BIT(5), 0);
+
+CCU_GATE_DEFINE(CLK_SDH_AXI, sdh_axi_aclk, sdh_axi_aclk, "pmua_aclk",
+ APMU_SDH0_CLK_RES_CTRL, BIT(3), 0);
+static const char * const sdh01_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll2_d8",
+ "pll2_d5",
+ "pll1_d11_223p4",
+ "pll1_d13_189",
+ "pll1_d23_106p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH0, sdh0_clk, sdh0_clk, sdh01_parents,
+ ARRAY_SIZE(sdh01_parents),
+ APMU_SDH0_CLK_RES_CTRL,
+ APMU_SDH0_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH1, sdh1_clk, sdh1_clk, sdh01_parents,
+ ARRAY_SIZE(sdh01_parents),
+ APMU_SDH1_CLK_RES_CTRL,
+ APMU_SDH1_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+static const char * const sdh2_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll2_d8",
+ "pll1_d3_819p2",
+ "pll1_d11_223p4",
+ "pll1_d13_189",
+ "pll1_d23_106p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH2, sdh2_clk, sdh2_clk, sdh2_parents,
+ ARRAY_SIZE(sdh2_parents),
+ APMU_SDH2_CLK_RES_CTRL,
+ APMU_SDH2_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+
+CCU_GATE_DEFINE(CLK_USB_AXI, usb_axi_clk, usb_axi_clk, "pmua_aclk",
+ APMU_USB_CLK_RES_CTRL, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_USB_P1, usb_p1_aclk, usb_p1_aclk, "pmua_aclk",
+ APMU_USB_CLK_RES_CTRL, BIT(5), 0);
+CCU_GATE_DEFINE(CLK_USB30, usb30_clk, usb30_clk, "pmua_aclk",
+ APMU_USB_CLK_RES_CTRL, BIT(8), 0);
+
+static const char * const qspi_parents[] = {
+ "pll1_d6_409p6",
+ "pll2_d8",
+ "pll1_d8_307p2",
+ "pll1_d10_245p76",
+ "pll1_d11_223p4",
+ "pll1_d23_106p8",
+ "pll1_d5_491p52",
+ "pll1_d13_189",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_QSPI, qspi_clk, qspi_clk, qspi_parents,
+ ARRAY_SIZE(qspi_parents),
+ APMU_QSPI_CLK_RES_CTRL,
+ APMU_QSPI_CLK_RES_CTRL, 9, 3, BIT(12), 6, 3,
+ BIT(4), 0);
+CCU_GATE_DEFINE(CLK_QSPI_BUS, qspi_bus_clk, qspi_bus_clk, "pmua_aclk",
+ APMU_QSPI_CLK_RES_CTRL, BIT(3), 0);
+CCU_GATE_DEFINE(CLK_DMA, dma_clk, dma_clk, "pmua_aclk", APMU_DMA_CLK_RES_CTRL,
+ BIT(3), 0);
+
+static const char * const aes_parents[] = {
+ "pll1_d12_204p8",
+ "pll1_d24_102p4",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_AES, aes_clk, aes_clk, aes_parents,
+ ARRAY_SIZE(aes_parents), APMU_AES_CLK_RES_CTRL, 6, 1,
+ BIT(5), 0);
+
+static const char * const vpu_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d5_491p52",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll3_d6",
+ "pll2_d3",
+ "pll2_d4",
+ "pll2_d5",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_VPU, vpu_clk, vpu_clk, vpu_parents,
+ ARRAY_SIZE(vpu_parents), APMU_VPU_CLK_RES_CTRL,
+ APMU_VPU_CLK_RES_CTRL, 13, 3, BIT(21), 10, 3,
+ BIT(3), 0);
+
+static const char * const gpu_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d5_491p52",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll3_d6",
+ "pll2_d3",
+ "pll2_d4",
+ "pll2_d5",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_GPU, gpu_clk, gpu_clk, gpu_parents,
+ ARRAY_SIZE(gpu_parents), APMU_GPU_CLK_RES_CTRL,
+ APMU_GPU_CLK_RES_CTRL, 12, 3, BIT(15), 18, 3,
+ BIT(4), 0);
+
+static const char * const audio_parents[] = {
+ "pll1_aud_245p7",
+ "pll1_d8_307p2",
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_AUDIO, audio_clk, audio_clk, audio_parents,
+ ARRAY_SIZE(audio_parents),
+ APMU_AUDIO_CLK_RES_CTRL,
+ APMU_AUDIO_CLK_RES_CTRL, 4, 3, BIT(15),
+ 7, 3, BIT(12), 0);
+
+static const char * const hdmi_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_HDMI, hdmi_mclk, hdmi_mclk, hdmi_parents,
+ ARRAY_SIZE(hdmi_parents),
+ APMU_HDMI_CLK_RES_CTRL,
+ APMU_HDMI_CLK_RES_CTRL, 1, 4, BIT(29), 5,
+ 3, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PCIE0_MASTER, pcie0_master_clk, pcie0_master_clk,
+ "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_0, BIT(2), 0);
+CCU_GATE_DEFINE(CLK_PCIE0_SLAVE, pcie0_slave_clk, pcie0_slave_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_0, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_PCIE0_DBI, pcie0_dbi_clk, pcie0_dbi_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_0, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PCIE1_MASTER, pcie1_master_clk, pcie1_master_clk,
+ "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_1, BIT(2), 0);
+CCU_GATE_DEFINE(CLK_PCIE1_SLAVE, pcie1_slave_clk, pcie1_slave_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_1, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_PCIE1_DBI, pcie1_dbi_clk, pcie1_dbi_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_1, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PCIE2_MASTER, pcie2_master_clk, pcie2_master_clk,
+ "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_2, BIT(2), 0);
+CCU_GATE_DEFINE(CLK_PCIE2_SLAVE, pcie2_slave_clk, pcie2_slave_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_2, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_PCIE2_DBI, pcie2_dbi_clk, pcie2_dbi_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_2, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_EMAC0_BUS, emac0_bus_clk, emac0_bus_clk, "pmua_aclk",
+ APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_EMAC0_PTP, emac0_ptp_clk, emac0_ptp_clk, "pll2_d6",
+ APMU_EMAC0_CLK_RES_CTRL, BIT(15), 0);
+CCU_GATE_DEFINE(CLK_EMAC1_BUS, emac1_bus_clk, emac1_bus_clk, "pmua_aclk",
+ APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_EMAC1_PTP, emac1_ptp_clk, emac1_ptp_clk, "pll2_d6",
+ APMU_EMAC1_CLK_RES_CTRL, BIT(15), 0);
+
+#endif
+/* APMU clocks end */
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_pll_clks[] = {
+ &pll1.common.clk,
+ &pll1_d4.common.clk,
+ &pll1_d6.common.clk,
+ &pll1_d8.common.clk,
+};
+#else
+static struct clk *k1_ccu_pll_clks[] = {
+ &pll1.common.clk,
+ &pll2.common.clk,
+ &pll3.common.clk,
+ &pll1_d2.common.clk,
+ &pll1_d3.common.clk,
+ &pll1_d4.common.clk,
+ &pll1_d5.common.clk,
+ &pll1_d6.common.clk,
+ &pll1_d7.common.clk,
+ &pll1_d8.common.clk,
+ &pll1_d11_223p4.common.clk,
+ &pll1_d13_189.common.clk,
+ &pll1_d23_106p8.common.clk,
+ &pll1_d64_38p4.common.clk,
+ &pll1_aud_245p7.common.clk,
+ &pll1_aud_24p5.common.clk,
+ &pll2_d1.common.clk,
+ &pll2_d2.common.clk,
+ &pll2_d3.common.clk,
+ &pll2_d4.common.clk,
+ &pll2_d5.common.clk,
+ &pll2_d6.common.clk,
+ &pll2_d7.common.clk,
+ &pll2_d8.common.clk,
+ &pll3_d1.common.clk,
+ &pll3_d2.common.clk,
+ &pll3_d3.common.clk,
+ &pll3_d4.common.clk,
+ &pll3_d5.common.clk,
+ &pll3_d6.common.clk,
+ &pll3_d7.common.clk,
+ &pll3_d8.common.clk,
+ &pll3_80.common.clk,
+ &pll3_40.common.clk,
+ &pll3_20.common.clk,
+};
+#endif
+
+static const struct spacemit_ccu_data k1_ccu_pll_data = {
+ .clks = k1_ccu_pll_clks,
+ .num = ARRAY_SIZE(k1_ccu_pll_clks),
+ .offset = K1_PLL_ID,
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_mpmu_clks[] = {
+ &pll1_d4_614p4.common.clk,
+ &pll1_d6_409p6.common.clk,
+ &pll1_d8_307p2.common.clk,
+ &pll1_d78_31p5.common.clk,
+ &slow_uart2_48.common.clk,
+};
+#else
+static struct clk *k1_ccu_mpmu_clks[] = {
+ &pll1_d8_307p2.common.clk,
+ &pll1_d32_76p8.common.clk,
+ &pll1_d40_61p44.common.clk,
+ &pll1_d16_153p6.common.clk,
+ &pll1_d24_102p4.common.clk,
+ &pll1_d48_51p2.common.clk,
+ &pll1_d48_51p2_ap.common.clk,
+ &pll1_m3d128_57p6.common.clk,
+ &pll1_d96_25p6.common.clk,
+ &pll1_d192_12p8.common.clk,
+ &pll1_d192_12p8_wdt.common.clk,
+ &pll1_d384_6p4.common.clk,
+ &pll1_d768_3p2.common.clk,
+ &pll1_d1536_1p6.common.clk,
+ &pll1_d3072_0p8.common.clk,
+ &pll1_d6_409p6.common.clk,
+ &pll1_d12_204p8.common.clk,
+ &pll1_d5_491p52.common.clk,
+ &pll1_d10_245p76.common.clk,
+ &pll1_d4_614p4.common.clk,
+ &pll1_d52_47p26.common.clk,
+ &pll1_d78_31p5.common.clk,
+ &pll1_d3_819p2.common.clk,
+ &pll1_d2_1228p8.common.clk,
+ &slow_uart.common.clk,
+ &slow_uart1_14p74.common.clk,
+ &slow_uart2_48.common.clk,
+ &wdt_clk.common.clk,
+ &apb_clk.common.clk,
+ &ripc_clk.common.clk,
+ &i2s_153p6.common.clk,
+ &i2s_153p6_base.common.clk,
+ &i2s_sysclk_src.common.clk,
+ &i2s_sysclk.common.clk,
+ &i2s_bclk_factor.common.clk,
+ &i2s_bclk.common.clk,
+ &wdt_bus_clk.common.clk,
+};
+#endif
+
+static const struct spacemit_ccu_data k1_ccu_mpmu_data = {
+ .clks = k1_ccu_mpmu_clks,
+ .num = ARRAY_SIZE(k1_ccu_mpmu_clks),
+ .offset = K1_MPMU_ID,
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_apbc_clks[] = {
+ &uart0_clk.common.clk,
+ &twsi2_clk.common.clk,
+ &twsi8_clk.common.clk,
+};
+#else
+static struct clk *k1_ccu_apbc_clks[] = {
+ &uart0_clk.common.clk,
+ &uart2_clk.common.clk,
+ &uart3_clk.common.clk,
+ &uart4_clk.common.clk,
+ &uart5_clk.common.clk,
+ &uart6_clk.common.clk,
+ &uart7_clk.common.clk,
+ &uart8_clk.common.clk,
+ &uart9_clk.common.clk,
+ &gpio_clk.common.clk,
+ &pwm0_clk.common.clk,
+ &pwm1_clk.common.clk,
+ &pwm2_clk.common.clk,
+ &pwm3_clk.common.clk,
+ &pwm4_clk.common.clk,
+ &pwm5_clk.common.clk,
+ &pwm6_clk.common.clk,
+ &pwm7_clk.common.clk,
+ &pwm8_clk.common.clk,
+ &pwm9_clk.common.clk,
+ &pwm10_clk.common.clk,
+ &pwm11_clk.common.clk,
+ &pwm12_clk.common.clk,
+ &pwm13_clk.common.clk,
+ &pwm14_clk.common.clk,
+ &pwm15_clk.common.clk,
+ &pwm16_clk.common.clk,
+ &pwm17_clk.common.clk,
+ &pwm18_clk.common.clk,
+ &pwm19_clk.common.clk,
+ &ssp3_clk.common.clk,
+ &rtc_clk.common.clk,
+ &twsi0_clk.common.clk,
+ &twsi1_clk.common.clk,
+ &twsi2_clk.common.clk,
+ &twsi4_clk.common.clk,
+ &twsi5_clk.common.clk,
+ &twsi6_clk.common.clk,
+ &twsi7_clk.common.clk,
+ &twsi8_clk.common.clk,
+ &timers1_clk.common.clk,
+ &timers2_clk.common.clk,
+ &aib_clk.common.clk,
+ &onewire_clk.common.clk,
+ &sspa0_clk.common.clk,
+ &sspa1_clk.common.clk,
+ &dro_clk.common.clk,
+ &ir_clk.common.clk,
+ &tsen_clk.common.clk,
+ &ipc_ap2aud_clk.common.clk,
+ &can0_clk.common.clk,
+ &can0_bus_clk.common.clk,
+ &uart0_bus_clk.common.clk,
+ &uart2_bus_clk.common.clk,
+ &uart3_bus_clk.common.clk,
+ &uart4_bus_clk.common.clk,
+ &uart5_bus_clk.common.clk,
+ &uart6_bus_clk.common.clk,
+ &uart7_bus_clk.common.clk,
+ &uart8_bus_clk.common.clk,
+ &uart9_bus_clk.common.clk,
+ &gpio_bus_clk.common.clk,
+ &pwm0_bus_clk.common.clk,
+ &pwm1_bus_clk.common.clk,
+ &pwm2_bus_clk.common.clk,
+ &pwm3_bus_clk.common.clk,
+ &pwm4_bus_clk.common.clk,
+ &pwm5_bus_clk.common.clk,
+ &pwm6_bus_clk.common.clk,
+ &pwm7_bus_clk.common.clk,
+ &pwm8_bus_clk.common.clk,
+ &pwm9_bus_clk.common.clk,
+ &pwm10_bus_clk.common.clk,
+ &pwm11_bus_clk.common.clk,
+ &pwm12_bus_clk.common.clk,
+ &pwm13_bus_clk.common.clk,
+ &pwm14_bus_clk.common.clk,
+ &pwm15_bus_clk.common.clk,
+ &pwm16_bus_clk.common.clk,
+ &pwm17_bus_clk.common.clk,
+ &pwm18_bus_clk.common.clk,
+ &pwm19_bus_clk.common.clk,
+ &ssp3_bus_clk.common.clk,
+ &rtc_bus_clk.common.clk,
+ &twsi0_bus_clk.common.clk,
+ &twsi1_bus_clk.common.clk,
+ &twsi2_bus_clk.common.clk,
+ &twsi4_bus_clk.common.clk,
+ &twsi5_bus_clk.common.clk,
+ &twsi6_bus_clk.common.clk,
+ &twsi7_bus_clk.common.clk,
+ &twsi8_bus_clk.common.clk,
+ &timers1_bus_clk.common.clk,
+ &timers2_bus_clk.common.clk,
+ &aib_bus_clk.common.clk,
+ &onewire_bus_clk.common.clk,
+ &sspa0_bus_clk.common.clk,
+ &sspa1_bus_clk.common.clk,
+ &tsen_bus_clk.common.clk,
+ &ipc_ap2aud_bus_clk.common.clk,
+ &sspa0_i2s_bclk.common.clk,
+ &sspa1_i2s_bclk.common.clk,
+};
+#endif
+
+static const struct spacemit_ccu_data k1_ccu_apbc_data = {
+ .clks = k1_ccu_apbc_clks,
+ .num = ARRAY_SIZE(k1_ccu_apbc_clks),
+ .offset = K1_APBC_ID,
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_apmu_clks[] = {
+ &pmua_aclk.common.clk,
+ &sdh_axi_aclk.common.clk,
+ &sdh0_clk.common.clk,
+ &sdh2_clk.common.clk,
+};
+#else
+static struct clk *k1_ccu_apmu_clks[] = {
+ &cci550_clk.common.clk,
+ &cpu_c0_hi_clk.common.clk,
+ &cpu_c0_core_clk.common.clk,
+ &cpu_c0_ace_clk.common.clk,
+ &cpu_c0_tcm_clk.common.clk,
+ &cpu_c1_hi_clk.common.clk,
+ &cpu_c1_core_clk.common.clk,
+ &cpu_c1_ace_clk.common.clk,
+ &ccic_4x_clk.common.clk,
+ &ccic1phy_clk.common.clk,
+ &pmua_aclk.common.clk,
+ &sdh_axi_aclk.common.clk,
+ &sdh0_clk.common.clk,
+ &sdh1_clk.common.clk,
+ &sdh2_clk.common.clk,
+ &usb_p1_aclk.common.clk,
+ &usb_axi_clk.common.clk,
+ &usb30_clk.common.clk,
+ &qspi_clk.common.clk,
+ &qspi_bus_clk.common.clk,
+ &dma_clk.common.clk,
+ &aes_clk.common.clk,
+ &vpu_clk.common.clk,
+ &gpu_clk.common.clk,
+ &emmc_clk.common.clk,
+ &emmc_x_clk.common.clk,
+ &audio_clk.common.clk,
+ &hdmi_mclk.common.clk,
+ &pcie0_master_clk.common.clk,
+ &pcie0_slave_clk.common.clk,
+ &pcie0_dbi_clk.common.clk,
+ &pcie1_master_clk.common.clk,
+ &pcie1_slave_clk.common.clk,
+ &pcie1_dbi_clk.common.clk,
+ &pcie2_master_clk.common.clk,
+ &pcie2_slave_clk.common.clk,
+ &pcie2_dbi_clk.common.clk,
+ &emac0_bus_clk.common.clk,
+ &emac0_ptp_clk.common.clk,
+ &emac1_bus_clk.common.clk,
+ &emac1_ptp_clk.common.clk,
+ &jpg_clk.common.clk,
+ &ccic2phy_clk.common.clk,
+ &ccic3phy_clk.common.clk,
+ &csi_clk.common.clk,
+ &camm0_clk.common.clk,
+ &camm1_clk.common.clk,
+ &camm2_clk.common.clk,
+ &isp_cpp_clk.common.clk,
+ &isp_bus_clk.common.clk,
+ &isp_clk.common.clk,
+ &dpu_mclk.common.clk,
+ &dpu_esc_clk.common.clk,
+ &dpu_bit_clk.common.clk,
+ &dpu_pxclk.common.clk,
+ &dpu_hclk.common.clk,
+ &dpu_spi_clk.common.clk,
+ &dpu_spi_hbus_clk.common.clk,
+ &dpu_spi_bus_clk.common.clk,
+ &dpu_spi_aclk.common.clk,
+ &v2d_clk.common.clk,
+ &emmc_bus_clk.common.clk,
+};
+#endif
+
+static int clk_k1_enable(struct clk *clk)
+{
+ const struct spacemit_ccu_data *data;
+ struct clk *c;
+ struct clk *pclk;
+ int ret, i;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev);
+ for (i = 0; i < data->num; i++) {
+ if (clk->id == data->clks[i]->id) {
+ c = data->clks[i];
+ break;
+ }
+ }
+ if (i == data->num)
+ c = clk;
+
+ pclk = clk_get_parent(c);
+ if (!IS_ERR_OR_NULL(pclk)) {
+ ret = ccf_clk_enable(pclk);
+ if (ret)
+ return ret;
+ }
+ ret = ccu_gate_enable(c);
+ return ret;
+}
+
+static int clk_k1_disable(struct clk *clk)
+{
+ const struct spacemit_ccu_data *data;
+ struct clk *c;
+ struct clk *pclk;
+ int ret, i;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev);
+ for (i = 0; i < data->num; i++) {
+ if (clk->id == data->clks[i]->id) {
+ c = data->clks[i];
+ break;
+ }
+ }
+ if (i == data->num)
+ c = clk;
+
+ pclk = clk_get_parent(c);
+ if (!IS_ERR_OR_NULL(pclk)) {
+ ret = ccf_clk_disable(pclk);
+ if (ret)
+ return ret;
+ }
+ ret = ccu_gate_disable(c);
+ return ret;
+}
+
+#define K1_CLK_OPS(name) \
+static const struct clk_ops k1_##name##_clk_ops = { \
+ .set_rate = ccf_clk_set_rate, \
+ .get_rate = ccf_clk_get_rate, \
+ .enable = clk_k1_enable, \
+ .disable = clk_k1_disable, \
+ .set_parent = ccf_clk_set_parent, \
+ .of_xlate = k1_##name##_clk_of_xlate, \
+}
+
+static const struct spacemit_ccu_data k1_ccu_apmu_data = {
+ .clks = k1_ccu_apmu_clks,
+ .num = ARRAY_SIZE(k1_ccu_apmu_clks),
+ .offset = K1_APMU_ID,
+};
+
+/*
+ * The K1 clock providers are split across separate syscon devices (PLL,
+ * MPMU, APMU, APBC) whose clocks parent across device boundaries. U-Boot's
+ * CCF resolves a parent by name at registration time and silently binds an
+ * orphan if the parent is not registered yet, so a controller must not
+ * register its clocks before the controllers owning its parents have probed.
+ * Force the parent controller to probe by its driver: this is robust against
+ * device tree node/phandle ordering and needs no helper "clocks" wiring in
+ * the syscon nodes.
+ */
+static int k1_clk_force_probe(const struct driver *drv)
+{
+ struct udevice *dev;
+
+ return uclass_get_device_by_driver(UCLASS_CLK, drv, &dev);
+}
+
+static int k1_clk_register(struct udevice *dev, struct regmap *regmap,
+ struct regmap *lock_regmap,
+ const struct spacemit_ccu_data *data)
+{
+ int i, ret;
+
+ for (i = 0; i < data->num; i++) {
+ struct clk *clk = data->clks[i];
+ struct ccu_common *common;
+
+ if (!clk)
+ continue;
+
+ common = clk_to_ccu_common(clk);
+ common->regmap = regmap;
+ common->lock_regmap = lock_regmap;
+
+ if (common->clk.id < K1_PLL_ID)
+ clk->id = common->clk.id + data->offset;
+ else
+ clk->id = common->clk.id;
+
+ ret = common->init(common);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int k1_pll_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ clk_register_fixed_rate(NULL, "clock-dummy", 0);
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ /*
+ * The lock status of PLLs locate in MPMU region, while PLLs themselves
+ * are in APBS region. Reference to MPMU syscon is required to check PLL
+ * status.
+ */
+ if (device_is_compatible(dev, "spacemit,k1-pll")) {
+ struct ofnode_phandle_args mpmu_args;
+
+ ret = dev_read_phandle_with_args(dev, "spacemit,mpmu", NULL, 0, 0,
+ &mpmu_args);
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(mpmu_args.node, &lock_regmap);
+ if (ret)
+ return ret;
+ }
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_mpmu_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ /* MPMU clocks parent off the PLL controller */
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_pll_clk));
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_apmu_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ /* APMU clocks parent off the PLL and MPMU controllers */
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_pll_clk));
+ if (ret)
+ return ret;
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_mpmu_clk));
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_apbc_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ /* APBC clocks parent off the PLL, MPMU and APMU controllers */
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_pll_clk));
+ if (ret)
+ return ret;
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_mpmu_clk));
+ if (ret)
+ return ret;
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_apmu_clk));
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_pll_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_PLL_ID + args->args[0];
+ else
+ clk->id = K1_PLL_ID;
+
+ return 0;
+}
+
+static int k1_mpmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_MPMU_ID + args->args[0];
+ else
+ clk->id = K1_MPMU_ID;
+
+ return 0;
+}
+
+static int k1_apbc_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_APBC_ID + args->args[0];
+ else
+ clk->id = K1_APBC_ID;
+
+ return 0;
+}
+
+static int k1_apmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_APMU_ID + args->args[0];
+ else
+ clk->id = K1_APMU_ID;
+
+ return 0;
+}
+
+static const struct udevice_id k1_pll_clk_match[] = {
+ { .compatible = "spacemit,k1-pll",
+ .data = (ulong)&k1_ccu_pll_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(pll);
+
+U_BOOT_DRIVER(k1_pll_clk) = {
+ .name = "k1_pll_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_pll_clk_match,
+ .probe = k1_pll_clk_probe,
+ .ops = &k1_pll_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static int k1_mpmu_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_MPMU);
+}
+
+static int k1_apbc_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_APBC);
+}
+
+static int k1_apmu_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_APMU);
+}
+
+static int k1_apbc2_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_APBC2);
+}
+
+static const struct udevice_id k1_mpmu_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-mpmu",
+ .data = (ulong)&k1_ccu_mpmu_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(mpmu);
+
+U_BOOT_DRIVER(k1_mpmu_clk) = {
+ .name = "k1_mpmu_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_mpmu_clk_match,
+ .bind = k1_mpmu_clk_bind,
+ .probe = k1_mpmu_clk_probe,
+ .ops = &k1_mpmu_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id k1_apbc_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-apbc",
+ .data = (ulong)&k1_ccu_apbc_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(apbc);
+
+U_BOOT_DRIVER(k1_apbc_clk) = {
+ .name = "k1_apbc_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_apbc_clk_match,
+ .bind = k1_apbc_clk_bind,
+ .probe = k1_apbc_clk_probe,
+ .ops = &k1_apbc_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id k1_apmu_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-apmu",
+ .data = (ulong)&k1_ccu_apmu_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(apmu);
+
+U_BOOT_DRIVER(k1_apmu_clk) = {
+ .name = "k1_apmu_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_apmu_clk_match,
+ .bind = k1_apmu_clk_bind,
+ .probe = k1_apmu_clk_probe,
+ .ops = &k1_apmu_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id k1_apbc2_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-apbc2" },
+ { /* sentinel */ },
+};
+
+U_BOOT_DRIVER(k1_apbc2_clk) = {
+ .name = "k1_apbc2_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_apbc2_clk_match,
+ .bind = k1_apbc2_clk_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_common.h b/drivers/clk/spacemit/clk_common.h
new file mode 100644
index 00000000000..ea5ebf57784
--- /dev/null
+++ b/drivers/clk/spacemit/clk_common.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_COMMON_H_
+#define _CLK_COMMON_H_
+
+#include <linux/clk-provider.h>
+
+struct ccu_common;
+
+typedef int (*ccu_init_fn)(struct ccu_common *common);
+
+struct ccu_common {
+ struct regmap *regmap;
+ struct regmap *lock_regmap;
+ const char *name;
+ const char * const *parents;
+ size_t num_parents;
+ ccu_init_fn init;
+
+ union {
+ /* For DDN and MIX */
+ struct {
+ u32 reg_ctrl;
+ u32 reg_fc;
+ u32 mask_fc;
+ };
+
+ /* For PLL */
+ struct {
+ u32 reg_swcr1;
+ u32 reg_swcr3;
+ };
+ };
+
+ struct clk clk;
+};
+
+#define CCU_COMMON(_id, _name, _parent, _init, _flags) \
+ .name = #_name, \
+ .parents = (const char *[]) { _parent }, \
+ .num_parents = 1, \
+ .init = _init, \
+ .clk = { .flags = _flags, .id = _id, } \
+
+#define CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, _init, _flags) \
+ .name = #_name, \
+ .parents = _parents, \
+ .num_parents = _num_p, \
+ .init = _init, \
+ .clk = { .flags = _flags, .id = _id, } \
+
+static inline struct ccu_common *clk_to_ccu_common(struct clk *clk)
+{
+ return container_of(clk, struct ccu_common, clk);
+}
+
+#define ccu_read(c, reg) \
+ ({ \
+ struct ccu_common * const __ccu = (c); \
+ u32 tmp; \
+ regmap_read(__ccu->regmap, __ccu->reg_##reg, &tmp); \
+ tmp; \
+ })
+#define ccu_update(c, reg, mask, val) \
+ ({ \
+ struct ccu_common * const __ccu = (c); \
+ regmap_update_bits(__ccu->regmap, __ccu->reg_##reg, \
+ mask, val); \
+ })
+
+#endif /* _CLK_COMMON_H_ */
diff --git a/drivers/clk/spacemit/clk_ddn.c b/drivers/clk/spacemit/clk_ddn.c
new file mode 100644
index 00000000000..7b93f30d5c3
--- /dev/null
+++ b/drivers/clk/spacemit/clk_ddn.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Authors: Haylen Chu <[email protected]>
+ *
+ * DDN stands for "Divider Denominator Numerator", it's M/N clock with a
+ * constant x2 factor. This clock hardware follows the equation below,
+ *
+ * numerator Fin
+ * 2 * ------------- = -------
+ * denominator Fout
+ *
+ * Thus, Fout could be calculated with,
+ *
+ * Fin denominator
+ * Fout = ----- * -------------
+ * 2 numerator
+ */
+
+#include <dm/device.h>
+#include <regmap.h>
+#include <linux/clk-provider.h>
+#include <linux/rational.h>
+
+#include "clk_ddn.h"
+
+#define UBOOT_DM_SPACEMIT_CLK_DDN "spacemit_clk_ddn"
+
+static unsigned long ccu_ddn_calc_rate(unsigned long prate, unsigned long num,
+ unsigned long den, unsigned int pre_div)
+{
+ return prate * den / pre_div / num;
+}
+
+static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn,
+ unsigned long rate, unsigned long prate,
+ unsigned long *num, unsigned long *den)
+{
+ rational_best_approximation(rate, prate / ddn->pre_div,
+ ddn->den_mask >> ddn->den_shift,
+ ddn->num_mask >> ddn->num_shift,
+ den, num);
+ return ccu_ddn_calc_rate(prate, *num, *den, ddn->pre_div);
+}
+
+static unsigned long ccu_ddn_recalc_rate(struct clk *clk)
+{
+ struct ccu_ddn *ddn = clk_to_ccu_ddn(clk);
+ unsigned int val, num, den;
+
+ val = ccu_read(&ddn->common, ctrl);
+
+ num = (val & ddn->num_mask) >> ddn->num_shift;
+ den = (val & ddn->den_mask) >> ddn->den_shift;
+
+ return ccu_ddn_calc_rate(clk_get_parent_rate(clk), num, den, ddn->pre_div);
+}
+
+static unsigned long ccu_ddn_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct ccu_ddn *ddn = clk_to_ccu_ddn(clk);
+ unsigned long num, den;
+
+ ccu_ddn_calc_best_rate(ddn, rate, clk_get_parent_rate(clk), &num, &den);
+
+ ccu_update(&ddn->common, ctrl,
+ ddn->num_mask | ddn->den_mask,
+ (num << ddn->num_shift) | (den << ddn->den_shift));
+
+ return 0;
+}
+
+static const struct clk_ops spacemit_clk_ddn_ops = {
+ .get_rate = ccu_ddn_recalc_rate,
+ .set_rate = ccu_ddn_set_rate,
+};
+
+int spacemit_ddn_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DDN,
+ common->name, common->parents[0]);
+}
+
+U_BOOT_DRIVER(spacemit_clk_ddn) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_DDN,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_ddn_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_ddn.h b/drivers/clk/spacemit/clk_ddn.h
new file mode 100644
index 00000000000..1330ced23b1
--- /dev/null
+++ b/drivers/clk/spacemit/clk_ddn.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_DDN_H_
+#define _CLK_DDN_H_
+
+#include <linux/clk-provider.h>
+
+#include "clk_common.h"
+
+struct ccu_ddn {
+ struct ccu_common common;
+ unsigned int num_mask;
+ unsigned int num_shift;
+ unsigned int den_mask;
+ unsigned int den_shift;
+ unsigned int pre_div;
+};
+
+#define CCU_DDN_MASK(_num_shift, _num_width) \
+ GENMASK((_num_shift) + (_num_width) - 1, _num_shift)
+
+#define CCU_DDN_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _num_mask, \
+ _num_shift, _den_mask, _den_shift, _pre_div, _flags) \
+static struct ccu_ddn _var = { \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, spacemit_ddn_init, _flags) \
+ }, \
+ .num_mask = _num_mask, \
+ .num_shift = _num_shift, \
+ .den_mask = _den_mask, \
+ .den_shift = _den_shift, \
+ .pre_div = _pre_div, \
+}
+
+static inline struct ccu_ddn *clk_to_ccu_ddn(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ return container_of(common, struct ccu_ddn, common);
+}
+
+int spacemit_ddn_init(struct ccu_common *common);
+
+#endif /* _CLK_DDN_H_ */
diff --git a/drivers/clk/spacemit/clk_mix.c b/drivers/clk/spacemit/clk_mix.c
new file mode 100644
index 00000000000..a1158512a92
--- /dev/null
+++ b/drivers/clk/spacemit/clk_mix.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Authors: Haylen Chu <[email protected]>
+ *
+ * MIX clock type is the combination of mux, factor or divider, and gate
+ */
+
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <div64.h>
+#include <regmap.h>
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+
+#include "clk_mix.h"
+
+#define UBOOT_DM_SPACEMIT_CLK_GATE "spacemit_clk_gate"
+#define UBOOT_DM_SPACEMIT_CLK_FACTOR "spacemit_clk_factor"
+#define UBOOT_DM_SPACEMIT_CLK_MUX "spacemit_clk_mux"
+#define UBOOT_DM_SPACEMIT_CLK_DIV "spacemit_clk_div"
+#define UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE "spacemit_clk_factor_gate"
+#define UBOOT_DM_SPACEMIT_CLK_MUX_GATE "spacemit_clk_mux_gate"
+#define UBOOT_DM_SPACEMIT_CLK_DIV_GATE "spacemit_clk_div_gate"
+#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV "spacemit_clk_mux_div"
+#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE "spacemit_clk_mux_div_gate"
+
+#define MIX_FC_TIMEOUT_US 10000
+#define MIX_FC_DELAY_US 5
+
+int ccu_gate_disable(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+
+ ccu_update(&mix->common, ctrl, mix->gate.mask, 0);
+
+ return 0;
+}
+
+int ccu_gate_enable(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_gate_config *gate = &mix->gate;
+
+ ccu_update(&mix->common, ctrl, gate->mask, gate->mask);
+
+ return 0;
+}
+
+static unsigned long ccu_factor_recalc_rate(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+
+ return clk_get_parent_rate(clk) * mix->factor.mul / mix->factor.div;
+}
+
+static unsigned long ccu_div_recalc_rate(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_div_config *div = &mix->div;
+ unsigned long val;
+
+ val = ccu_read(&mix->common, ctrl) >> div->shift;
+ val &= (1 << div->width) - 1;
+
+ return divider_recalc_rate(clk, clk_get_parent_rate(clk), val, NULL, 0, div->width);
+}
+
+/*
+ * Some clocks require a "FC" (frequency change) bit to be set after changing
+ * their rates or reparenting. This bit will be automatically cleared by
+ * hardware in MIX_FC_TIMEOUT_US, which indicates the operation is completed.
+ */
+static int ccu_mix_trigger_fc(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+ unsigned int val;
+
+ if (common->reg_fc)
+ return 0;
+
+ ccu_update(common, fc, common->mask_fc, common->mask_fc);
+
+ return regmap_read_poll_timeout(common->regmap, common->reg_fc,
+ val, !(val & common->mask_fc),
+ MIX_FC_DELAY_US,
+ MIX_FC_TIMEOUT_US);
+}
+
+static unsigned long
+ccu_mix_calc_best_rate(struct clk *clk, unsigned long rate,
+ struct clk **best_parent,
+ unsigned long *best_parent_rate,
+ u32 *div_val)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ unsigned int parent_num = common->num_parents;
+ struct ccu_div_config *div = &mix->div;
+ u32 div_max = 1 << div->width;
+ unsigned long best_rate = 0;
+
+ for (int i = 0; i < parent_num; i++) {
+ struct udevice *parent_dev;
+ unsigned long parent_rate;
+ struct clk *parent;
+
+ if (uclass_get_device_by_name(UCLASS_CLK, common->parents[i],
+ &parent_dev))
+ continue;
+ parent = dev_get_clk_ptr(parent_dev);
+ if (!parent)
+ continue;
+
+ parent_rate = clk_get_rate(parent);
+
+ for (int j = 1; j <= div_max; j++) {
+ unsigned long tmp = DIV_ROUND_CLOSEST_ULL(parent_rate, j);
+
+ if (abs(tmp - rate) < abs(best_rate - rate)) {
+ best_rate = tmp;
+
+ if (div_val)
+ *div_val = j - 1;
+
+ if (best_parent) {
+ *best_parent = parent;
+ *best_parent_rate = parent_rate;
+ }
+ }
+ }
+ }
+
+ return best_rate;
+}
+
+static unsigned long ccu_mix_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_common *common = &mix->common;
+ struct ccu_div_config *div = &mix->div;
+ u32 current_div, target_div, mask;
+
+ ccu_mix_calc_best_rate(clk, rate, NULL, NULL, &target_div);
+
+ current_div = ccu_read(common, ctrl) >> div->shift;
+ current_div &= (1 << div->width) - 1;
+
+ if (current_div == target_div)
+ return 0;
+
+ mask = GENMASK(div->width + div->shift - 1, div->shift);
+
+ ccu_update(common, ctrl, mask, target_div << div->shift);
+
+ return ccu_mix_trigger_fc(clk);
+}
+
+static u8 ccu_mux_get_parent(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_mux_config *mux = &mix->mux;
+ u8 parent;
+
+ parent = ccu_read(&mix->common, ctrl) >> mux->shift;
+ parent &= (1 << mux->width) - 1;
+
+ return parent;
+}
+
+static int ccu_mux_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_mux_config *mux = &mix->mux;
+ u32 mask;
+ int i = 0;
+
+ mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
+
+ for (i = 0; i < common->num_parents; i++) {
+ if (!strcmp(parent->dev->name, common->parents[i]))
+ break;
+ }
+
+ if (i == common->num_parents)
+ return -EINVAL;
+
+ ccu_update(&mix->common, ctrl, mask, i << mux->shift);
+
+ return ccu_mix_trigger_fc(clk);
+}
+
+int spacemit_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_GATE,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .get_rate = clk_generic_get_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_factor_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_factor_ops = {
+ .get_rate = ccu_factor_recalc_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_factor) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_FACTOR,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_factor_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_ops = {
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = clk_generic_get_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_div_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_div_ops = {
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_div) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_DIV,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_div_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_factor_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_factor_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .get_rate = ccu_factor_recalc_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_factor_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_factor_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_GATE,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = clk_generic_get_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_div_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV_GATE,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_div_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_div_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_DIV_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_div_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_div_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_div_ops = {
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux_div) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX_DIV,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_div_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_div_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_div_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux_div_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_div_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_mix.h b/drivers/clk/spacemit/clk_mix.h
new file mode 100644
index 00000000000..26a12cedd0d
--- /dev/null
+++ b/drivers/clk/spacemit/clk_mix.h
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_MIX_H_
+#define _CLK_MIX_H_
+
+#include <linux/clk-provider.h>
+
+#include "clk_common.h"
+
+/**
+ * struct ccu_gate_config - Gate configuration
+ *
+ * @mask: Mask to enable the gate. Some clocks may have more than one bit
+ * set in this field.
+ */
+struct ccu_gate_config {
+ u32 mask;
+};
+
+struct ccu_factor_config {
+ u32 div;
+ u32 mul;
+};
+
+struct ccu_mux_config {
+ u8 shift;
+ u8 width;
+};
+
+struct ccu_div_config {
+ u8 shift;
+ u8 width;
+};
+
+struct ccu_mix {
+ struct ccu_factor_config factor;
+ struct ccu_gate_config gate;
+ struct ccu_div_config div;
+ struct ccu_mux_config mux;
+ struct ccu_common common;
+};
+
+#define CCU_GATE_INIT(_mask) { .mask = _mask }
+#define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul }
+#define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width }
+#define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width }
+
+#define CCU_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \
+ _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, spacemit_gate_init, \
+ _flags) \
+ } \
+}
+
+#define CCU_FACTOR_DEFINE(_id, _var, _name, _parent, _div, _mul) \
+static struct ccu_mix _var = { \
+ .factor = CCU_FACTOR_INIT(_div, _mul), \
+ .common = { \
+ CCU_COMMON(_id, _name, _parent, spacemit_factor_init, \
+ 0) \
+ } \
+}
+
+#define CCU_MUX_DEFINE(_id, _var, _name, _parents, _num_p, _reg_ctrl, \
+ _shift, _width, _flags) \
+static struct ccu_mix _var = { \
+ .mux = CCU_MUX_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_init, _flags) \
+ } \
+}
+
+#define CCU_DIV_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _shift, \
+ _width, _flags) \
+static struct ccu_mix _var = { \
+ .div = CCU_DIV_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, spacemit_div_init, \
+ _flags) \
+ } \
+}
+
+#define CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent, \
+ _reg_ctrl, _mask_gate, _div, _mul, \
+ _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .factor = CCU_FACTOR_INIT(_div, _mul), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, \
+ spacemit_factor_gate_init, _flags) \
+ } \
+}
+
+#define CCU_FACTOR_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \
+ _mask_gate, _div, _mul) \
+ CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent, \
+ _reg_ctrl, _mask_gate, _div, _mul, \
+ 0)
+
+#define CCU_MUX_GATE_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _shift, _width, _mask_gate, \
+ _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .mux = CCU_MUX_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_gate_init, _flags) \
+ } \
+}
+
+#define CCU_DIV_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \
+ _shift, _width, _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .div = CCU_DIV_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, \
+ spacemit_div_gate_init, _flags) \
+ } \
+}
+
+#define CCU_MUX_DIV_GATE_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _mshift, _mwidth, _muxshift, \
+ _muxwidth, _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .div = CCU_DIV_INIT(_mshift, _mwidth), \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_div_gate_init, _flags) \
+ }, \
+}
+
+#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_id, _var, _name, _parents, \
+ _num_p, _reg_ctrl, _reg_fc, \
+ _mshift, _mwidth, _mask_fc, \
+ _muxshift, _muxwidth, \
+ _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .div = CCU_DIV_INIT(_mshift, _mwidth), \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ .reg_fc = _reg_fc, \
+ .mask_fc = _mask_fc, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_div_gate_init, _flags) \
+ }, \
+}
+
+#define CCU_MUX_DIV_FC_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _reg_fc, _mshift, _mwidth, \
+ _mask_fc, _muxshift, _muxwidth, _flags) \
+static struct ccu_mix _var = { \
+ .div = CCU_DIV_INIT(_mshift, _mwidth), \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ .reg_fc = _reg_fc, \
+ .mask_fc = _mask_fc, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_div_init, _flags) \
+ }, \
+}
+
+#define CCU_MUX_FC_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _reg_fc, _mask_fc, _muxshift, \
+ _muxwidth, _flags) \
+static struct ccu_mix _var = { \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ .reg_fc = _reg_fc, \
+ .mask_fc = _mask_fc, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_init, \
+ _flags) \
+ }, \
+}
+
+static inline struct ccu_mix *clk_to_ccu_mix(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ return container_of(common, struct ccu_mix, common);
+}
+
+int ccu_gate_enable(struct clk *clk);
+int ccu_gate_disable(struct clk *clk);
+
+int spacemit_gate_init(struct ccu_common *common);
+int spacemit_factor_init(struct ccu_common *common);
+int spacemit_mux_init(struct ccu_common *common);
+int spacemit_div_init(struct ccu_common *common);
+int spacemit_factor_gate_init(struct ccu_common *common);
+int spacemit_div_gate_init(struct ccu_common *common);
+int spacemit_mux_gate_init(struct ccu_common *common);
+int spacemit_mux_div_init(struct ccu_common *common);
+int spacemit_mux_div_gate_init(struct ccu_common *common);
+
+#endif /* _CLK_MIX_H_ */
diff --git a/drivers/clk/spacemit/clk_pll.c b/drivers/clk/spacemit/clk_pll.c
new file mode 100644
index 00000000000..56da70af58a
--- /dev/null
+++ b/drivers/clk/spacemit/clk_pll.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#include <dm/device.h>
+#include <regmap.h>
+#include <linux/bug.h>
+#include <linux/clk-provider.h>
+
+#include "clk_pll.h"
+
+#define UBOOT_DM_SPACEMIT_CLK_PLL "spacemit_clk_pll"
+
+#define PLL_TIMEOUT_US 3000
+#define PLL_DELAY_US 5
+
+#define PLL_SWCR3_EN ((u32)BIT(31))
+#define PLL_SWCR3_MASK GENMASK(30, 0)
+
+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll,
+ unsigned long rate)
+{
+ struct ccu_pll_config *config = &pll->config;
+ const struct ccu_pll_rate_tbl *best_entry;
+ unsigned long best_delta = ULONG_MAX;
+ int i;
+
+ for (i = 0; i < config->tbl_num; i++) {
+ const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];
+ unsigned long delta = abs(entry->rate - rate);
+
+ if (delta < best_delta) {
+ best_delta = delta;
+ best_entry = entry;
+ }
+ }
+
+ return best_entry;
+}
+
+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct ccu_pll *pll)
+{
+ struct ccu_pll_config *config = &pll->config;
+ u32 swcr1, swcr3;
+ int i;
+
+ swcr1 = ccu_read(&pll->common, swcr1);
+ swcr3 = ccu_read(&pll->common, swcr3);
+ swcr3 &= PLL_SWCR3_MASK;
+
+ for (i = 0; i < config->tbl_num; i++) {
+ const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];
+
+ if (swcr1 == entry->swcr1 && swcr3 == entry->swcr3)
+ return entry;
+ }
+
+ return NULL;
+}
+
+static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry)
+{
+ struct ccu_common *common = &pll->common;
+
+ regmap_write(common->regmap, common->reg_swcr1, entry->swcr1);
+ ccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3);
+}
+
+static int ccu_pll_enable(struct clk *clk)
+{
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ struct ccu_common *common = &pll->common;
+ unsigned int tmp;
+
+ ccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN);
+
+ /* check lock status */
+ return regmap_read_poll_timeout(common->lock_regmap,
+ pll->config.reg_lock,
+ tmp,
+ tmp & pll->config.mask_lock,
+ PLL_DELAY_US, PLL_TIMEOUT_US);
+}
+
+static int ccu_pll_disable(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ ccu_update(common, swcr3, PLL_SWCR3_EN, 0);
+
+ return 0;
+}
+
+/*
+ * PLLs must be gated before changing rate, which is ensured by
+ * flag CLK_SET_RATE_GATE.
+ */
+static unsigned long ccu_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ const struct ccu_pll_rate_tbl *entry;
+
+ entry = ccu_pll_lookup_best_rate(pll, rate);
+ ccu_pll_update_param(pll, entry);
+
+ return 0;
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk *clk)
+{
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ const struct ccu_pll_rate_tbl *entry;
+
+ entry = ccu_pll_lookup_matched_entry(pll);
+
+ WARN_ON_ONCE(!entry);
+
+ return entry ? entry->rate : 0;
+}
+
+static const struct clk_ops spacemit_clk_pll_ops = {
+ .enable = ccu_pll_enable,
+ .disable = ccu_pll_disable,
+ .set_rate = ccu_pll_set_rate,
+ .get_rate = ccu_pll_recalc_rate,
+};
+
+int spacemit_pll_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ int ret;
+
+ ret = clk_register(clk, UBOOT_DM_SPACEMIT_CLK_PLL,
+ common->name, common->parents[0]);
+ if (ret)
+ return ret;
+
+ if (ccu_pll_lookup_matched_entry(pll))
+ return 0;
+
+ ccu_pll_disable(clk);
+ ccu_pll_update_param(pll, &pll->config.rate_tbl[0]);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(spacemit_clk_pll) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_PLL,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_pll_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_pll.h b/drivers/clk/spacemit/clk_pll.h
new file mode 100644
index 00000000000..3987cc1141b
--- /dev/null
+++ b/drivers/clk/spacemit/clk_pll.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_PLL_H_
+#define _CLK_PLL_H_
+
+#include <linux/clk-provider.h>
+
+#include "clk_common.h"
+
+/**
+ * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and register
+ * configuration.
+ *
+ * @rate: PLL rate
+ * @swcr1: Register value of PLLX_SW1_CTRL (PLLx_SWCR1).
+ * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of
+ * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling
+ * the PLL and not contained in this field.
+ */
+struct ccu_pll_rate_tbl {
+ unsigned long rate;
+ u32 swcr1;
+ u32 swcr3;
+};
+
+#define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \
+ { \
+ .rate = _rate, \
+ .swcr1 = _swcr1, \
+ .swcr3 = _swcr3, \
+ }
+
+struct ccu_pll_config {
+ const struct ccu_pll_rate_tbl *rate_tbl;
+ u32 tbl_num;
+ u32 reg_lock;
+ u32 mask_lock;
+};
+
+struct ccu_pll {
+ struct ccu_common common;
+ struct ccu_pll_config config;
+};
+
+#define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \
+ { \
+ .rate_tbl = (_table), \
+ .tbl_num = sizeof(_table) / sizeof((_table)[0]), \
+ .reg_lock = (_reg_lock), \
+ .mask_lock = (_mask_lock), \
+ }
+
+#define CCU_PLL_DEFINE(_id, _var, _name, _parent, _table, _reg_swcr1, \
+ _reg_swcr3, _reg_lock, _mask_lock, _flags) \
+static struct ccu_pll _var = { \
+ .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \
+ .common = { \
+ .reg_swcr1 = _reg_swcr1, \
+ .reg_swcr3 = _reg_swcr3, \
+ CCU_COMMON(_id, _name, _parent, spacemit_pll_init, _flags) \
+ } \
+}
+
+static inline struct ccu_pll *clk_to_ccu_pll(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ return container_of(common, struct ccu_pll, common);
+}
+
+int spacemit_pll_init(struct ccu_common *common);
+
+#endif /* _CLK_PLL_H_ */
diff --git a/drivers/clk/sunxi/clk_a523.c b/drivers/clk/sunxi/clk_a523.c
index 1de95fbaf2f..494ee195599 100644
--- a/drivers/clk/sunxi/clk_a523.c
+++ b/drivers/clk/sunxi/clk_a523.c
@@ -16,6 +16,7 @@ static struct ccu_clk_gate a523_gates[] = {
[CLK_PLL_PERIPH0_200M] = GATE_DUMMY,
[CLK_APB1] = GATE_DUMMY,
+ [CLK_MBUS_EMAC1] = GATE(0x804, BIT(12)),
[CLK_BUS_MMC0] = GATE(0x84c, BIT(0)),
[CLK_BUS_MMC1] = GATE(0x84c, BIT(1)),
[CLK_BUS_MMC2] = GATE(0x84c, BIT(2)),