From 13db7a0708ae057096f32e394bc4caab11be9dcc Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Mon, 1 Sep 2025 17:53:18 +0800 Subject: [PATCH] rockchip: backport GATE_LINK support for RK3588 Apart from improved power consumption, this fixes the runtime errors from the pmdomain driver (failed to set idle on domain '%s') Backport four clk fixes while at it. Signed-off-by: Tianling Shen Link: https://github.com/openwrt/openwrt/pull/19925 Signed-off-by: Hauke Mehrtens --- ...kchip-support-clocks-registered-late.patch | 106 ++++++ ...chip-rk3588-register-GATE_LINK-later.patch | 150 +++++++++ ...kchip-expose-rockchip_clk_set_lookup.patch | 90 +++++ ...-implement-linked-gate-clock-support.patch | 314 ++++++++++++++++++ ...ckchip-rk3588-drop-RK3588_LINKED_CLK.patch | 112 +++++++ ...rk3588-make-refclko25m_ethX-critical.patch | 54 +++ ...chip-rk3568-mark-hclk_vi-as-critical.patch | 31 ++ ...hip-rk3588-Add-PLL-rate-for-1500-MHz.patch | 25 ++ ...ty-init-callback-for-rk3588-PLL-type.patch | 44 +++ 9 files changed, 926 insertions(+) create mode 100644 target/linux/rockchip/patches-6.12/032-01-v6.14-clk-rockchip-support-clocks-registered-late.patch create mode 100644 target/linux/rockchip/patches-6.12/032-02-v6.14-clk-rockchip-rk3588-register-GATE_LINK-later.patch create mode 100644 target/linux/rockchip/patches-6.12/032-03-v6.14-clk-rockchip-expose-rockchip_clk_set_lookup.patch create mode 100644 target/linux/rockchip/patches-6.12/032-04-v6.14-clk-rockchip-implement-linked-gate-clock-support.patch create mode 100644 target/linux/rockchip/patches-6.12/032-05-v6.14-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch create mode 100644 target/linux/rockchip/patches-6.12/032-06-v6.14-clk-rockchip-rk3588-make-refclko25m_ethX-critical.patch create mode 100644 target/linux/rockchip/patches-6.12/032-07-v6.15-clk-rockchip-rk3568-mark-hclk_vi-as-critical.patch create mode 100644 target/linux/rockchip/patches-6.12/032-08-v6.16-clk-rockchip-rk3588-Add-PLL-rate-for-1500-MHz.patch create mode 100644 target/linux/rockchip/patches-6.12/032-09-v6.16-clk-rockchip-Drop-empty-init-callback-for-rk3588-PLL-type.patch diff --git a/target/linux/rockchip/patches-6.12/032-01-v6.14-clk-rockchip-support-clocks-registered-late.patch b/target/linux/rockchip/patches-6.12/032-01-v6.14-clk-rockchip-support-clocks-registered-late.patch new file mode 100644 index 00000000000..62517313c64 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-01-v6.14-clk-rockchip-support-clocks-registered-late.patch @@ -0,0 +1,106 @@ +From 9e89f02da718bc912f7f253b58804d4a52efed30 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 11 Dec 2024 17:58:50 +0100 +Subject: [PATCH] clk: rockchip: support clocks registered late + +When some clocks are registered late and some clocks are registered +early we need to make sure the late registered clocks report probe defer +until the final registration has happened. + +But we do not want to keep reporting probe defer after the late +registration has happened. Also not all Rockchip SoCs have late +registered clocks and may not need to report probe defer at all. + +This restructures code a bit, so that there is a new function +rockchip_clk_init_early(), which should be used for initializing the CRU +structure on SoCs making use of late initialization in addition to the +early init. These platforms should call rockchip_clk_finalize() +once all clocks have been registered. + +Signed-off-by: Sebastian Reichel +[added EXPORT_SYMBOL_GPL(rockchip_clk_finalize) to match the early function] +Link: https://lore.kernel.org/r/20241211165957.94922-2-sebastian.reichel@collabora.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk.c | 36 ++++++++++++++++++++++++++++++++---- + drivers/clk/rockchip/clk.h | 3 +++ + 2 files changed, 35 insertions(+), 4 deletions(-) + +--- a/drivers/clk/rockchip/clk.c ++++ b/drivers/clk/rockchip/clk.c +@@ -359,14 +359,17 @@ static struct clk *rockchip_clk_register + return hw->clk; + } + +-struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, +- void __iomem *base, +- unsigned long nr_clks) ++static struct rockchip_clk_provider *rockchip_clk_init_base( ++ struct device_node *np, void __iomem *base, ++ unsigned long nr_clks, bool has_late_clocks) + { + struct rockchip_clk_provider *ctx; + struct clk **clk_table; ++ struct clk *default_clk_val; + int i; + ++ default_clk_val = ERR_PTR(has_late_clocks ? -EPROBE_DEFER : -ENOENT); ++ + ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); + if (!ctx) + return ERR_PTR(-ENOMEM); +@@ -376,7 +379,7 @@ struct rockchip_clk_provider *rockchip_c + goto err_free; + + for (i = 0; i < nr_clks; ++i) +- clk_table[i] = ERR_PTR(-ENOENT); ++ clk_table[i] = default_clk_val; + + ctx->reg_base = base; + ctx->clk_data.clks = clk_table; +@@ -393,8 +396,33 @@ err_free: + kfree(ctx); + return ERR_PTR(-ENOMEM); + } ++ ++struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, ++ void __iomem *base, ++ unsigned long nr_clks) ++{ ++ return rockchip_clk_init_base(np, base, nr_clks, false); ++} + EXPORT_SYMBOL_GPL(rockchip_clk_init); + ++struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, ++ void __iomem *base, ++ unsigned long nr_clks) ++{ ++ return rockchip_clk_init_base(np, base, nr_clks, true); ++} ++EXPORT_SYMBOL_GPL(rockchip_clk_init_early); ++ ++void rockchip_clk_finalize(struct rockchip_clk_provider *ctx) ++{ ++ int i; ++ ++ for (i = 0; i < ctx->clk_data.clk_num; ++i) ++ if (ctx->clk_data.clks[i] == ERR_PTR(-EPROBE_DEFER)) ++ ctx->clk_data.clks[i] = ERR_PTR(-ENOENT); ++} ++EXPORT_SYMBOL_GPL(rockchip_clk_finalize); ++ + void rockchip_clk_of_add_provider(struct device_node *np, + struct rockchip_clk_provider *ctx) + { +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -1024,6 +1024,9 @@ struct rockchip_clk_branch { + + struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks); ++struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, ++ void __iomem *base, unsigned long nr_clks); ++void rockchip_clk_finalize(struct rockchip_clk_provider *ctx); + void rockchip_clk_of_add_provider(struct device_node *np, + struct rockchip_clk_provider *ctx); + unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, diff --git a/target/linux/rockchip/patches-6.12/032-02-v6.14-clk-rockchip-rk3588-register-GATE_LINK-later.patch b/target/linux/rockchip/patches-6.12/032-02-v6.14-clk-rockchip-rk3588-register-GATE_LINK-later.patch new file mode 100644 index 00000000000..5e47d89a8f2 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-02-v6.14-clk-rockchip-rk3588-register-GATE_LINK-later.patch @@ -0,0 +1,150 @@ +From 33af96244a66f855baa43d424844bb437c79c30c Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 11 Dec 2024 17:58:51 +0100 +Subject: [PATCH] clk: rockchip: rk3588: register GATE_LINK later + +The proper GATE_LINK implementation will use runtime PM to handle the +linked gate clocks, which requires device context. Currently all clocks +are registered early via CLK_OF_DECLARE, which is before the kernel +knows about devices. + +Moving the full clocks registration to the probe routine does not work, +since the clocks needed for timers must be registered early. + +To work around this issue, most of the clock tree is registered early, +but GATE_LINK clocks are handled in the probe routine. Since the resets +are not needed early either, they have also been moved to the probe +routine. + +Signed-off-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20241211165957.94922-3-sebastian.reichel@collabora.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3588.c | 66 +++++++++++++++++++++++++++---- + 1 file changed, 58 insertions(+), 8 deletions(-) + +--- a/drivers/clk/rockchip/clk-rk3588.c ++++ b/drivers/clk/rockchip/clk-rk3588.c +@@ -266,6 +266,8 @@ static struct rockchip_pll_rate_table rk + }, \ + } + ++static struct rockchip_clk_provider *early_ctx; ++ + static struct rockchip_cpuclk_rate_table rk3588_cpub0clk_rates[] __initdata = { + RK3588_CPUB01CLK_RATE(2496000000, 1), + RK3588_CPUB01CLK_RATE(2400000000, 1), +@@ -694,7 +696,7 @@ static struct rockchip_pll_clock rk3588_ + RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates), + }; + +-static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { ++static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = { + /* + * CRU Clock-Architecture + */ +@@ -2428,7 +2430,9 @@ static struct rockchip_clk_branch rk3588 + RK3588_CLKGATE_CON(68), 5, GFLAGS), + GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0, + RK3588_CLKGATE_CON(68), 2, GFLAGS), ++}; + ++static struct rockchip_clk_branch rk3588_clk_branches[] = { + GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS), + GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS), + GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS), +@@ -2453,26 +2457,31 @@ static struct rockchip_clk_branch rk3588 + GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", HCLK_VO1, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS), + }; + +-static void __init rk3588_clk_init(struct device_node *np) ++static void __init rk3588_clk_early_init(struct device_node *np) + { + struct rockchip_clk_provider *ctx; +- unsigned long clk_nr_clks; ++ unsigned long clk_nr_clks, max_clk_id1, max_clk_id2; + void __iomem *reg_base; + +- clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches, +- ARRAY_SIZE(rk3588_clk_branches)) + 1; ++ max_clk_id1 = rockchip_clk_find_max_clk_id(rk3588_clk_branches, ++ ARRAY_SIZE(rk3588_clk_branches)); ++ max_clk_id2 = rockchip_clk_find_max_clk_id(rk3588_early_clk_branches, ++ ARRAY_SIZE(rk3588_early_clk_branches)); ++ clk_nr_clks = max(max_clk_id1, max_clk_id2) + 1; ++ + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + +- ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); ++ ctx = rockchip_clk_init_early(np, reg_base, clk_nr_clks); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } ++ early_ctx = ctx; + + rockchip_clk_register_plls(ctx, rk3588_pll_clks, + ARRAY_SIZE(rk3588_pll_clks), +@@ -2491,14 +2500,55 @@ static void __init rk3588_clk_init(struc + &rk3588_cpub1clk_data, rk3588_cpub1clk_rates, + ARRAY_SIZE(rk3588_cpub1clk_rates)); + ++ rockchip_clk_register_branches(ctx, rk3588_early_clk_branches, ++ ARRAY_SIZE(rk3588_early_clk_branches)); ++ ++ rockchip_clk_of_add_provider(np, ctx); ++} ++CLK_OF_DECLARE_DRIVER(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_early_init); ++ ++static int clk_rk3588_probe(struct platform_device *pdev) ++{ ++ struct rockchip_clk_provider *ctx = early_ctx; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ + rockchip_clk_register_branches(ctx, rk3588_clk_branches, + ARRAY_SIZE(rk3588_clk_branches)); + +- rk3588_rst_init(np, reg_base); ++ rockchip_clk_finalize(ctx); + ++ rk3588_rst_init(np, ctx->reg_base); + rockchip_register_restart_notifier(ctx, RK3588_GLB_SRST_FST, NULL); + ++ /* ++ * Re-add clock provider, so that the newly added clocks are also ++ * re-parented and get their defaults configured. ++ */ ++ of_clk_del_provider(np); + rockchip_clk_of_add_provider(np, ctx); ++ ++ return 0; + } + +-CLK_OF_DECLARE(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_init); ++static const struct of_device_id clk_rk3588_match_table[] = { ++ { ++ .compatible = "rockchip,rk3588-cru", ++ }, ++ { } ++}; ++ ++static struct platform_driver clk_rk3588_driver = { ++ .probe = clk_rk3588_probe, ++ .driver = { ++ .name = "clk-rk3588", ++ .of_match_table = clk_rk3588_match_table, ++ .suppress_bind_attrs = true, ++ }, ++}; ++ ++static int __init rockchip_clk_rk3588_drv_register(void) ++{ ++ return platform_driver_register(&clk_rk3588_driver); ++} ++core_initcall(rockchip_clk_rk3588_drv_register); diff --git a/target/linux/rockchip/patches-6.12/032-03-v6.14-clk-rockchip-expose-rockchip_clk_set_lookup.patch b/target/linux/rockchip/patches-6.12/032-03-v6.14-clk-rockchip-expose-rockchip_clk_set_lookup.patch new file mode 100644 index 00000000000..ca05b2311bc --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-03-v6.14-clk-rockchip-expose-rockchip_clk_set_lookup.patch @@ -0,0 +1,90 @@ +From fe0fb6675fa48cade97d8bcd46226479c4a704df Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 11 Dec 2024 17:58:52 +0100 +Subject: [PATCH] clk: rockchip: expose rockchip_clk_set_lookup + +Move rockchip_clk_add_lookup to clk.h, so that it can be used +by sub-devices with their own driver. These might also have to +do a lookup, so rename the function to rockchip_clk_set_lookup +and add a matching rockchip_clk_get_lookup. + +Signed-off-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20241211165957.94922-4-sebastian.reichel@collabora.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk.c | 14 ++++---------- + drivers/clk/rockchip/clk.h | 12 ++++++++++++ + 2 files changed, 16 insertions(+), 10 deletions(-) + +--- a/drivers/clk/rockchip/clk.c ++++ b/drivers/clk/rockchip/clk.c +@@ -197,12 +197,6 @@ static void rockchip_fractional_approxim + clk_fractional_divider_general_approximation(hw, rate, parent_rate, m, n); + } + +-static void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, +- struct clk *clk, unsigned int id) +-{ +- ctx->clk_data.clks[id] = clk; +-} +- + static struct clk *rockchip_clk_register_frac_branch( + struct rockchip_clk_provider *ctx, const char *name, + const char *const *parent_names, u8 num_parents, +@@ -292,7 +286,7 @@ static struct clk *rockchip_clk_register + return mux_clk; + } + +- rockchip_clk_add_lookup(ctx, mux_clk, child->id); ++ rockchip_clk_set_lookup(ctx, mux_clk, child->id); + + /* notifier on the fraction divider to catch rate changes */ + if (frac->mux_frac_idx >= 0) { +@@ -452,7 +446,7 @@ void rockchip_clk_register_plls(struct r + continue; + } + +- rockchip_clk_add_lookup(ctx, clk, list->id); ++ rockchip_clk_set_lookup(ctx, clk, list->id); + } + } + EXPORT_SYMBOL_GPL(rockchip_clk_register_plls); +@@ -614,7 +608,7 @@ void rockchip_clk_register_branches(stru + continue; + } + +- rockchip_clk_add_lookup(ctx, clk, list->id); ++ rockchip_clk_set_lookup(ctx, clk, list->id); + } + } + EXPORT_SYMBOL_GPL(rockchip_clk_register_branches); +@@ -638,7 +632,7 @@ void rockchip_clk_register_armclk(struct + return; + } + +- rockchip_clk_add_lookup(ctx, clk, lookup_id); ++ rockchip_clk_set_lookup(ctx, clk, lookup_id); + } + EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk); + +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -1022,6 +1022,18 @@ struct rockchip_clk_branch { + #define SGRF_GATE(_id, cname, pname) \ + FACTOR(_id, cname, pname, 0, 1, 1) + ++static inline struct clk *rockchip_clk_get_lookup(struct rockchip_clk_provider *ctx, ++ unsigned int id) ++{ ++ return ctx->clk_data.clks[id]; ++} ++ ++static inline void rockchip_clk_set_lookup(struct rockchip_clk_provider *ctx, ++ struct clk *clk, unsigned int id) ++{ ++ ctx->clk_data.clks[id] = clk; ++} ++ + struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks); + struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, diff --git a/target/linux/rockchip/patches-6.12/032-04-v6.14-clk-rockchip-implement-linked-gate-clock-support.patch b/target/linux/rockchip/patches-6.12/032-04-v6.14-clk-rockchip-implement-linked-gate-clock-support.patch new file mode 100644 index 00000000000..30371a0c347 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-04-v6.14-clk-rockchip-implement-linked-gate-clock-support.patch @@ -0,0 +1,314 @@ +From c62fa612cfa66ab58ab215e5afc95c43c613b513 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 11 Dec 2024 17:58:53 +0100 +Subject: [PATCH] clk: rockchip: implement linked gate clock support + +Recent Rockchip SoCs have a new hardware block called Native Interface +Unit (NIU), which gates clocks to devices behind them. These clock +gates will only have a running output clock when all of the following +conditions are met: + +1. the parent clock is enabled +2. the enable bit is set correctly +3. the linked clock is enabled + +To handle them this code registers them as a normal gate type clock, +which takes care of condition 1 + 2. The linked clock is handled by +using runtime PM clocks. Handling it via runtime PM requires setting +up a struct device for each of these clocks with a driver attached +to use the correct runtime PM operations. Thus the complete handling +of these clocks has been moved into its own driver. + +Signed-off-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20241211165957.94922-5-sebastian.reichel@collabora.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/Makefile | 1 + + drivers/clk/rockchip/clk-rk3588.c | 23 +-------- + drivers/clk/rockchip/clk.c | 52 +++++++++++++++++++ + drivers/clk/rockchip/clk.h | 25 +++++++++ + drivers/clk/rockchip/gate-link.c | 85 +++++++++++++++++++++++++++++++ + 5 files changed, 165 insertions(+), 21 deletions(-) + create mode 100644 drivers/clk/rockchip/gate-link.c + +--- a/drivers/clk/rockchip/Makefile ++++ b/drivers/clk/rockchip/Makefile +@@ -13,6 +13,7 @@ clk-rockchip-y += clk-inverter.o + clk-rockchip-y += clk-mmc-phase.o + clk-rockchip-y += clk-muxgrf.o + clk-rockchip-y += clk-ddr.o ++clk-rockchip-y += gate-link.o + clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o + + obj-$(CONFIG_CLK_PX30) += clk-px30.o +--- a/drivers/clk/rockchip/clk-rk3588.c ++++ b/drivers/clk/rockchip/clk-rk3588.c +@@ -12,25 +12,6 @@ + #include + #include "clk.h" + +-/* +- * Recent Rockchip SoCs have a new hardware block called Native Interface +- * Unit (NIU), which gates clocks to devices behind them. These effectively +- * need two parent clocks. +- * +- * Downstream enables the linked clock via runtime PM whenever the gate is +- * enabled. This implementation uses separate clock nodes for each of the +- * linked gate clocks, which leaks parts of the clock tree into DT. +- * +- * The GATE_LINK macro instead takes the second parent via 'linkname', but +- * ignores the information. Once the clock framework is ready to handle it, the +- * information should be passed on here. But since these clocks are required to +- * access multiple relevant IP blocks, such as PCIe or USB, we mark all linked +- * clocks critical until a better solution is available. This will waste some +- * power, but avoids leaking implementation details into DT or hanging the +- * system. +- */ +-#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \ +- GATE(_id, cname, pname, f, o, b, gf) + #define RK3588_LINKED_CLK CLK_IS_CRITICAL + + +@@ -2513,8 +2494,8 @@ static int clk_rk3588_probe(struct platf + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + +- rockchip_clk_register_branches(ctx, rk3588_clk_branches, +- ARRAY_SIZE(rk3588_clk_branches)); ++ rockchip_clk_register_late_branches(dev, ctx, rk3588_clk_branches, ++ ARRAY_SIZE(rk3588_clk_branches)); + + rockchip_clk_finalize(ctx); + +--- a/drivers/clk/rockchip/clk.c ++++ b/drivers/clk/rockchip/clk.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -468,6 +469,29 @@ unsigned long rockchip_clk_find_max_clk_ + } + EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id); + ++static struct platform_device *rockchip_clk_register_gate_link( ++ struct device *parent_dev, ++ struct rockchip_clk_provider *ctx, ++ struct rockchip_clk_branch *clkbr) ++{ ++ struct rockchip_gate_link_platdata gate_link_pdata = { ++ .ctx = ctx, ++ .clkbr = clkbr, ++ }; ++ ++ struct platform_device_info pdevinfo = { ++ .parent = parent_dev, ++ .name = "rockchip-gate-link-clk", ++ .id = clkbr->id, ++ .fwnode = dev_fwnode(parent_dev), ++ .of_node_reused = true, ++ .data = &gate_link_pdata, ++ .size_data = sizeof(gate_link_pdata), ++ }; ++ ++ return platform_device_register_full(&pdevinfo); ++} ++ + void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, + unsigned int nr_clk) +@@ -593,6 +617,9 @@ void rockchip_clk_register_branches(stru + list->div_width, list->div_flags, + ctx->reg_base, &ctx->lock); + break; ++ case branch_linked_gate: ++ /* must be registered late, fall-through for error message */ ++ break; + } + + /* none of the cases above matched */ +@@ -613,6 +640,31 @@ void rockchip_clk_register_branches(stru + } + EXPORT_SYMBOL_GPL(rockchip_clk_register_branches); + ++void rockchip_clk_register_late_branches(struct device *dev, ++ struct rockchip_clk_provider *ctx, ++ struct rockchip_clk_branch *list, ++ unsigned int nr_clk) ++{ ++ unsigned int idx; ++ ++ for (idx = 0; idx < nr_clk; idx++, list++) { ++ struct platform_device *pdev = NULL; ++ ++ switch (list->branch_type) { ++ case branch_linked_gate: ++ pdev = rockchip_clk_register_gate_link(dev, ctx, list); ++ break; ++ default: ++ dev_err(dev, "unknown clock type %d\n", list->branch_type); ++ break; ++ } ++ ++ if (!pdev) ++ dev_err(dev, "failed to register device for clock %s\n", list->name); ++ } ++} ++EXPORT_SYMBOL_GPL(rockchip_clk_register_late_branches); ++ + void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, + unsigned int lookup_id, + const char *name, const char *const *parent_names, +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -570,6 +570,7 @@ enum rockchip_clk_branch_type { + branch_divider, + branch_fraction_divider, + branch_gate, ++ branch_linked_gate, + branch_mmc, + branch_inverter, + branch_factor, +@@ -597,6 +598,7 @@ struct rockchip_clk_branch { + int gate_offset; + u8 gate_shift; + u8 gate_flags; ++ unsigned int linked_clk_id; + struct rockchip_clk_branch *child; + }; + +@@ -895,6 +897,20 @@ struct rockchip_clk_branch { + .gate_flags = gf, \ + } + ++#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \ ++ { \ ++ .id = _id, \ ++ .branch_type = branch_linked_gate, \ ++ .name = cname, \ ++ .parent_names = (const char *[]){ pname }, \ ++ .linked_clk_id = linkedclk, \ ++ .num_parents = 1, \ ++ .flags = f, \ ++ .gate_offset = o, \ ++ .gate_shift = b, \ ++ .gate_flags = gf, \ ++ } ++ + #define MMC(_id, cname, pname, offset, shift) \ + { \ + .id = _id, \ +@@ -1034,6 +1050,11 @@ static inline void rockchip_clk_set_look + ctx->clk_data.clks[id] = clk; + } + ++struct rockchip_gate_link_platdata { ++ struct rockchip_clk_provider *ctx; ++ struct rockchip_clk_branch *clkbr; ++}; ++ + struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks); + struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, +@@ -1046,6 +1067,10 @@ unsigned long rockchip_clk_find_max_clk_ + void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *list, + unsigned int nr_clk); ++void rockchip_clk_register_late_branches(struct device *dev, ++ struct rockchip_clk_provider *ctx, ++ struct rockchip_clk_branch *list, ++ unsigned int nr_clk); + void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, + struct rockchip_pll_clock *pll_list, + unsigned int nr_pll, int grf_lock_offset); +--- /dev/null ++++ b/drivers/clk/rockchip/gate-link.c +@@ -0,0 +1,85 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (c) 2024 Collabora Ltd. ++ * Author: Sebastian Reichel ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk.h" ++ ++static int rk_clk_gate_link_register(struct device *dev, ++ struct rockchip_clk_provider *ctx, ++ struct rockchip_clk_branch *clkbr) ++{ ++ unsigned long flags = clkbr->flags | CLK_SET_RATE_PARENT; ++ struct clk *clk; ++ ++ clk = clk_register_gate(dev, clkbr->name, clkbr->parent_names[0], ++ flags, ctx->reg_base + clkbr->gate_offset, ++ clkbr->gate_shift, clkbr->gate_flags, ++ &ctx->lock); ++ ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ rockchip_clk_set_lookup(ctx, clk, clkbr->id); ++ return 0; ++} ++ ++static int rk_clk_gate_link_probe(struct platform_device *pdev) ++{ ++ struct rockchip_gate_link_platdata *pdata; ++ struct device *dev = &pdev->dev; ++ struct clk *linked_clk; ++ int ret; ++ ++ pdata = dev_get_platdata(dev); ++ if (!pdata) ++ return dev_err_probe(dev, -ENODEV, "missing platform data"); ++ ++ ret = devm_pm_runtime_enable(dev); ++ if (ret) ++ return ret; ++ ++ ret = devm_pm_clk_create(dev); ++ if (ret) ++ return ret; ++ ++ linked_clk = rockchip_clk_get_lookup(pdata->ctx, pdata->clkbr->linked_clk_id); ++ ret = pm_clk_add_clk(dev, linked_clk); ++ if (ret) ++ return ret; ++ ++ ret = rk_clk_gate_link_register(dev, pdata->ctx, pdata->clkbr); ++ if (ret) ++ goto err; ++ ++ return 0; ++ ++err: ++ pm_clk_remove_clk(dev, linked_clk); ++ return ret; ++} ++ ++static const struct dev_pm_ops rk_clk_gate_link_pm_ops = { ++ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) ++}; ++ ++static struct platform_driver rk_clk_gate_link_driver = { ++ .probe = rk_clk_gate_link_probe, ++ .driver = { ++ .name = "rockchip-gate-link-clk", ++ .pm = &rk_clk_gate_link_pm_ops, ++ .suppress_bind_attrs = true, ++ }, ++}; ++ ++static int __init rk_clk_gate_link_drv_register(void) ++{ ++ return platform_driver_register(&rk_clk_gate_link_driver); ++} ++core_initcall(rk_clk_gate_link_drv_register); diff --git a/target/linux/rockchip/patches-6.12/032-05-v6.14-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch b/target/linux/rockchip/patches-6.12/032-05-v6.14-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch new file mode 100644 index 00000000000..0e487f9b48c --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-05-v6.14-clk-rockchip-rk3588-drop-RK3588_LINKED_CLK.patch @@ -0,0 +1,112 @@ +From e9cdd7d6cf2a5031a968dc21f4f566101b602150 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Wed, 11 Dec 2024 17:58:54 +0100 +Subject: [PATCH] clk: rockchip: rk3588: drop RK3588_LINKED_CLK + +With the proper GATE_LINK support, we no longer need to keep the +linked clocks always on. Thus it's time to drop the CLK_IS_CRITICAL +flag for them. + +Signed-off-by: Sebastian Reichel +Link: https://lore.kernel.org/r/20241211165957.94922-6-sebastian.reichel@collabora.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3588.c | 27 ++++++++++++--------------- + 1 file changed, 12 insertions(+), 15 deletions(-) + +--- a/drivers/clk/rockchip/clk-rk3588.c ++++ b/drivers/clk/rockchip/clk-rk3588.c +@@ -12,9 +12,6 @@ + #include + #include "clk.h" + +-#define RK3588_LINKED_CLK CLK_IS_CRITICAL +- +- + #define RK3588_GRF_SOC_STATUS0 0x600 + #define RK3588_PHYREF_ALT_GATE 0xc38 + +@@ -1439,7 +1436,7 @@ static struct rockchip_clk_branch rk3588 + COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(77), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(31), 0, GFLAGS), +- COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RK3588_LINKED_CLK, ++ COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(77), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(31), 1, GFLAGS), + GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0, +@@ -1668,13 +1665,13 @@ static struct rockchip_clk_branch rk3588 + RK3588_CLKGATE_CON(42), 9, GFLAGS), + + /* vdpu */ +- COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, RK3588_LINKED_CLK, ++ COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(98), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(44), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_VDPU_LOW_ROOT, "aclk_vdpu_low_root", mux_400m_200m_100m_24m_p, 0, + RK3588_CLKSEL_CON(98), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(44), 1, GFLAGS), +- COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, ++ COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(98), 9, 2, MFLAGS, + RK3588_CLKGATE_CON(44), 2, GFLAGS), + COMPOSITE(ACLK_JPEG_DECODER_ROOT, "aclk_jpeg_decoder_root", gpll_cpll_aupll_spll_p, 0, +@@ -1725,9 +1722,9 @@ static struct rockchip_clk_branch rk3588 + COMPOSITE(ACLK_RKVENC0_ROOT, "aclk_rkvenc0_root", gpll_cpll_npll_p, 0, + RK3588_CLKSEL_CON(102), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(47), 1, GFLAGS), +- GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", RK3588_LINKED_CLK, ++ GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", 0, + RK3588_CLKGATE_CON(47), 4, GFLAGS), +- GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", RK3588_LINKED_CLK, ++ GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0, + RK3588_CLKGATE_CON(47), 5, GFLAGS), + COMPOSITE(CLK_RKVENC0_CORE, "clk_rkvenc0_core", gpll_cpll_aupll_npll_p, 0, + RK3588_CLKSEL_CON(102), 14, 2, MFLAGS, 9, 5, DFLAGS, +@@ -1737,10 +1734,10 @@ static struct rockchip_clk_branch rk3588 + RK3588_CLKGATE_CON(48), 6, GFLAGS), + + /* vi */ +- COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, RK3588_LINKED_CLK, ++ COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(106), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(49), 0, GFLAGS), +- COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, ++ COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(106), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(49), 1, GFLAGS), + COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0, +@@ -1910,10 +1907,10 @@ static struct rockchip_clk_branch rk3588 + COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_dmyaupll_npll_spll_p, 0, + RK3588_CLKSEL_CON(110), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(52), 0, GFLAGS), +- COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, RK3588_LINKED_CLK, ++ COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, 0, + RK3588_CLKSEL_CON(110), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(52), 1, GFLAGS), +- COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, ++ COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(110), 10, 2, MFLAGS, + RK3588_CLKGATE_CON(52), 2, GFLAGS), + COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0, +@@ -2416,7 +2413,7 @@ static struct rockchip_clk_branch rk3588 + static struct rockchip_clk_branch rk3588_clk_branches[] = { + GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS), + GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS), +- GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS), ++ GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, 0, RK3588_CLKGATE_CON(31), 2, GFLAGS), + GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 2, GFLAGS), + GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 3, GFLAGS), + GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 7, GFLAGS), +@@ -2428,9 +2425,9 @@ static struct rockchip_clk_branch rk3588 + GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 4, GFLAGS), + GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 5, GFLAGS), + GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", ACLK_VOP_LOW_ROOT, 0, RK3588_CLKGATE_CON(55), 9, GFLAGS), +- GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS), ++ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, 0, RK3588_CLKGATE_CON(55), 5, GFLAGS), + GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 6, GFLAGS), +- GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS), ++ GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 9, GFLAGS), + GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 1, GFLAGS), + GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 4, GFLAGS), + GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", HCLK_NVM, 0, RK3588_CLKGATE_CON(75), 1, GFLAGS), diff --git a/target/linux/rockchip/patches-6.12/032-06-v6.14-clk-rockchip-rk3588-make-refclko25m_ethX-critical.patch b/target/linux/rockchip/patches-6.12/032-06-v6.14-clk-rockchip-rk3588-make-refclko25m_ethX-critical.patch new file mode 100644 index 00000000000..76425559ad9 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-06-v6.14-clk-rockchip-rk3588-make-refclko25m_ethX-critical.patch @@ -0,0 +1,54 @@ +From cd8b5366636bdff0449b789fb2d33abb20804255 Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Sat, 14 Dec 2024 23:48:19 +0100 +Subject: [PATCH] clk: rockchip: rk3588: make refclko25m_ethX critical + +Ethernet phys normally need a 25MHz refclk input. On a lot of boards +this is done with a dedicated 25MHz crystal. But the rk3588 CRU also +provides a means for that via the refclko25m_ethX clock outputs that +can be used for that function. + +The mdio bus normally probes devices on the bus at runtime, by reading +specific phy registers. This requires the phy to be running and thus +also being supplied by its reference clock. + +While there exist the possibility and dt-binding to declare these +input clocks for each phy in the phy-dt-node, this is only relevant +_after_ the phy has been detected and during the drivers probe-run. + +This results in a chicken-and-egg-problem. The refclks in the CRU are +running on boot of course, but phy-probing can very well happen after +clk_disable_unused has run. + +In the past I tried to make clock-handling part of the mdio bus code [0] +but that wasn't very well received, due to it being specific to OF and +clocks with the consensus being that resources needed for detection +need to be enabled before. + +So to make probing ethernet phys using the internal refclks possible, +make those 2 clocks critical. + +[0] https://lore.kernel.org/netdev/13590315.F0gNSz5aLb@diego/T/ + +Signed-off-by: Heiko Stuebner +Link: https://lore.kernel.org/r/20241214224820.200665-1-heiko@sntech.de +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3588.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/clk/rockchip/clk-rk3588.c ++++ b/drivers/clk/rockchip/clk-rk3588.c +@@ -772,10 +772,10 @@ static struct rockchip_clk_branch rk3588 + COMPOSITE(MCLK_GMAC0_OUT, "mclk_gmac0_out", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(15), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(5), 3, GFLAGS), +- COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, 0, ++ COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, CLK_IS_CRITICAL, + RK3588_CLKSEL_CON(15), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3588_CLKGATE_CON(5), 4, GFLAGS), +- COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, 0, ++ COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, CLK_IS_CRITICAL, + RK3588_CLKSEL_CON(16), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(5), 5, GFLAGS), + COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0, diff --git a/target/linux/rockchip/patches-6.12/032-07-v6.15-clk-rockchip-rk3568-mark-hclk_vi-as-critical.patch b/target/linux/rockchip/patches-6.12/032-07-v6.15-clk-rockchip-rk3568-mark-hclk_vi-as-critical.patch new file mode 100644 index 00000000000..dd258981302 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-07-v6.15-clk-rockchip-rk3568-mark-hclk_vi-as-critical.patch @@ -0,0 +1,31 @@ +From 83dbeca33f7422f4a30c8a91a79d6c0dba4fb6af Mon Sep 17 00:00:00 2001 +From: Michael Riesch +Date: Mon, 10 Feb 2025 09:29:02 +0100 +Subject: [PATCH] clk: rockchip: rk3568: mark hclk_vi as critical + +The clock 'pclk_vi_niu' has a dependency on 'hclk_vi_niu' according +to the Technical Reference Manual section '2.8.6 NIU Clock gating +reliance'. However, this kind of dependency cannot be addressed +properly at the moment (until the support for linked clocks is +implemented for the RK3568). +As an intermediate solution, mark the hclk_vi as critical on the +Rockchip RK3568. + +Suggested-by: Nicolas Frattaroli +Signed-off-by: Michael Riesch +Link: https://lore.kernel.org/r/20250210-rk3568-hclk-vi-v1-1-9ade2626f638@wolfvision.net +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3568.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/rockchip/clk-rk3568.c ++++ b/drivers/clk/rockchip/clk-rk3568.c +@@ -1602,6 +1602,7 @@ static const char *const rk3568_cru_crit + "pclk_php", + "hclk_usb", + "pclk_usb", ++ "hclk_vi", + "hclk_vo", + }; + diff --git a/target/linux/rockchip/patches-6.12/032-08-v6.16-clk-rockchip-rk3588-Add-PLL-rate-for-1500-MHz.patch b/target/linux/rockchip/patches-6.12/032-08-v6.16-clk-rockchip-rk3588-Add-PLL-rate-for-1500-MHz.patch new file mode 100644 index 00000000000..ba4df3d9be2 --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-08-v6.16-clk-rockchip-rk3588-Add-PLL-rate-for-1500-MHz.patch @@ -0,0 +1,25 @@ +From 831a8ac72264426ccd0ee5d2b0d74491ea7d2bfb Mon Sep 17 00:00:00 2001 +From: Alexander Shiyan +Date: Tue, 8 Apr 2025 09:46:12 +0300 +Subject: [PATCH] clk: rockchip: rk3588: Add PLL rate for 1500 MHz + +At least one RK3588 clock (CPLL) uses 1.5 GHz, so let's add +that frequency to the PLL table. + +Signed-off-by: Alexander Shiyan +Link: https://lore.kernel.org/r/20250408064612.41359-1-eagle.alexander923@gmail.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3588.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/rockchip/clk-rk3588.c ++++ b/drivers/clk/rockchip/clk-rk3588.c +@@ -64,6 +64,7 @@ static struct rockchip_pll_rate_table rk + RK3588_PLL_RATE(1560000000, 2, 260, 1, 0), + RK3588_PLL_RATE(1536000000, 2, 256, 1, 0), + RK3588_PLL_RATE(1512000000, 2, 252, 1, 0), ++ RK3588_PLL_RATE(1500000000, 2, 250, 1, 0), + RK3588_PLL_RATE(1488000000, 2, 248, 1, 0), + RK3588_PLL_RATE(1464000000, 2, 244, 1, 0), + RK3588_PLL_RATE(1440000000, 2, 240, 1, 0), diff --git a/target/linux/rockchip/patches-6.12/032-09-v6.16-clk-rockchip-Drop-empty-init-callback-for-rk3588-PLL-type.patch b/target/linux/rockchip/patches-6.12/032-09-v6.16-clk-rockchip-Drop-empty-init-callback-for-rk3588-PLL-type.patch new file mode 100644 index 00000000000..61341a8e95d --- /dev/null +++ b/target/linux/rockchip/patches-6.12/032-09-v6.16-clk-rockchip-Drop-empty-init-callback-for-rk3588-PLL-type.patch @@ -0,0 +1,44 @@ +From 646bfc52bbe184c0579060c3919e5d70885b0dcc Mon Sep 17 00:00:00 2001 +From: Yao Zi +Date: Wed, 26 Mar 2025 11:35:56 +0000 +Subject: [PATCH] clk: rockchip: Drop empty init callback for rk3588 PLL type + +Unlike PLLs in previous geneation of SoCs, PLLs in RK3588 type don't +require any platform-specific initialization. Drop callback +rockchip_rk3588_pll_init() that does nothing in fact to clean the +driver up. + +Signed-off-by: Yao Zi +Link: https://lore.kernel.org/r/20250326113556.21039-1-ziyao@disroot.org +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-pll.c | 11 ----------- + 1 file changed, 11 deletions(-) + +--- a/drivers/clk/rockchip/clk-pll.c ++++ b/drivers/clk/rockchip/clk-pll.c +@@ -1025,16 +1025,6 @@ static int rockchip_rk3588_pll_is_enable + return !(pllcon & RK3588_PLLCON1_PWRDOWN); + } + +-static int rockchip_rk3588_pll_init(struct clk_hw *hw) +-{ +- struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); +- +- if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) +- return 0; +- +- return 0; +-} +- + static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = { + .recalc_rate = rockchip_rk3588_pll_recalc_rate, + .enable = rockchip_rk3588_pll_enable, +@@ -1049,7 +1039,6 @@ static const struct clk_ops rockchip_rk3 + .enable = rockchip_rk3588_pll_enable, + .disable = rockchip_rk3588_pll_disable, + .is_enabled = rockchip_rk3588_pll_is_enabled, +- .init = rockchip_rk3588_pll_init, + }; + + /* -- 2.47.3