K1 SPL runs from on-chip SRAM with a small pre-relocation malloc heap.
Registering the full K1 clock tree would not fit, so split the tree on
CONFIG_SPL_BUILD: the SPL build registers only the subset SPL needs
(currently UART, SDHCI, I2C (TWSI), and their PLL/MPMU/APMU/APBC
ancestors); the non-SPL build keeps the full tree.

Where surviving SPL CCU definitions reference parent clocks outside
that subset, use "clock-dummy", so framework parent lookups still resolve.

Signed-off-by: Guodong Xu <[email protected]>

---
v4:
- New patch. Prune SPL clock tree to the UART/SDHCI/I2C subset.
---
 drivers/clk/spacemit/clk-k1.c | 128 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/drivers/clk/spacemit/clk-k1.c b/drivers/clk/spacemit/clk-k1.c
index 80eede251b8..6695c4379e1 100644
--- a/drivers/clk/spacemit/clk-k1.c
+++ b/drivers/clk/spacemit/clk-k1.c
@@ -44,6 +44,18 @@ 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),
 };
@@ -131,9 +143,23 @@ CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D8, pll3_d8, pll3_d8, 
"pll3", APBS_PLL3_SWCR2,
 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);
 
@@ -251,9 +277,37 @@ 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",
@@ -598,9 +652,44 @@ CCU_GATE_DEFINE(CLK_TSEN_BUS, tsen_bus_clk, tsen_bus_clk, 
"apb_clk",
 
 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",
@@ -1082,8 +1171,17 @@ CCU_GATE_DEFINE(CLK_EMAC1_BUS, emac1_bus_clk, 
emac1_bus_clk, "pmua_aclk",
 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,
@@ -1121,6 +1219,7 @@ static struct clk *k1_ccu_pll_clks[] = {
        &pll3_40.common.clk,
        &pll3_20.common.clk,
 };
+#endif
 
 static const struct spacemit_ccu_data k1_ccu_pll_data = {
        .clks           = k1_ccu_pll_clks,
@@ -1128,6 +1227,15 @@ static const struct spacemit_ccu_data k1_ccu_pll_data = {
        .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,
@@ -1167,6 +1275,7 @@ static struct clk *k1_ccu_mpmu_clks[] = {
        &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,
@@ -1174,6 +1283,13 @@ static const struct spacemit_ccu_data k1_ccu_mpmu_data = 
{
        .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,
@@ -1278,6 +1394,7 @@ static struct clk *k1_ccu_apbc_clks[] = {
        &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,
@@ -1285,6 +1402,14 @@ static const struct spacemit_ccu_data k1_ccu_apbc_data = 
{
        .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,
@@ -1349,6 +1474,7 @@ static struct clk *k1_ccu_apmu_clks[] = {
        &v2d_clk.common.clk,
        &emmc_bus_clk.common.clk,
 };
+#endif
 
 static int clk_k1_enable(struct clk *clk)
 {
@@ -1486,6 +1612,8 @@ static int k1_pll_clk_probe(struct udevice *dev)
        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;

-- 
2.43.0

Reply via email to