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

