From: Sebastian Reichel <sebastian.reichel@collabora.com> To: Elaine Zhang <zhangqing@rock-chips.com>, Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>, linux-clk@vger.kernel.org Cc: Kever Yang <kever.yang@rock-chips.com>, Heiko Stuebner <heiko@sntech.de>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Conor Dooley <conor+dt@kernel.org>, huangtao@rock-chips.com, andy.yan@rock-chips.com, devicetree@vger.kernel.org, linux-rockchip@lists.infradead.org, Sebastian Reichel <sebastian.reichel@collabora.com>, kernel@collabora.com Subject: [PATCH v7 7/7] clk: rockchip: implement proper GATE_LINK support Date: Wed, 13 Dec 2023 19:46:52 +0100 [thread overview] Message-ID: <20231213185114.47565-8-sebastian.reichel@collabora.com> (raw) In-Reply-To: <20231213185114.47565-1-sebastian.reichel@collabora.com> 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. GATE_LINK type clocks handle the second parent via 'linkedclk' by using runtime PM clocks. To make that possible a new platform device is created for every clock handled in this way. Note, that before this patch clk_rk3588_probe() has never been called, because CLK_OF_DECLARE marks the DT node as processed. This patch replaces that with CLK_OF_DECLARE_DRIVER and thus the probe function is used now. This is necessary to have 'struct device' available. Also instead of builtin_platform_driver_probe, the driver has been switched to use core_initcall, since it should be fully probed before the Rockchip PM domain driver (and that is using postcore_initcall). Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> --- drivers/clk/rockchip/clk-rk3588.c | 122 +++++++++++++----------------- drivers/clk/rockchip/clk.c | 68 ++++++++++++++++- drivers/clk/rockchip/clk.h | 16 ++++ 3 files changed, 137 insertions(+), 69 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c index b30279a96dc8..f0eb380b727c 100644 --- a/drivers/clk/rockchip/clk-rk3588.c +++ b/drivers/clk/rockchip/clk-rk3588.c @@ -12,28 +12,6 @@ #include <dt-bindings/clock/rockchip,rk3588-cru.h> #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 - - #define RK3588_GRF_SOC_STATUS0 0x600 #define RK3588_PHYREF_ALT_GATE 0xc38 @@ -266,6 +244,8 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { }, \ } +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 +674,7 @@ static struct rockchip_pll_clock rk3588_pll_clks[] __initdata = { 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 */ @@ -1456,7 +1436,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1685,13 +1665,13 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1742,9 +1722,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1754,10 +1734,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1927,10 +1907,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -2428,10 +2408,12 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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), + 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), @@ -2443,9 +2425,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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), @@ -2453,14 +2435,18 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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__); @@ -2473,6 +2459,7 @@ static void __init rk3588_clk_init(struct device_node *np) iounmap(reg_base); return; } + early_ctx = ctx; rockchip_clk_register_plls(ctx, rk3588_pll_clks, ARRAY_SIZE(rk3588_pll_clks), @@ -2491,54 +2478,53 @@ static void __init rk3588_clk_init(struct device_node *np) &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); - + 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); -} -CLK_OF_DECLARE(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_init); - -struct clk_rk3588_inits { - void (*inits)(struct device_node *np); -}; - -static const struct clk_rk3588_inits clk_3588_cru_init = { - .inits = rk3588_clk_init, -}; + return 0; +} static const struct of_device_id clk_rk3588_match_table[] = { { .compatible = "rockchip,rk3588-cru", - .data = &clk_3588_cru_init, }, { } }; -static int __init clk_rk3588_probe(struct platform_device *pdev) -{ - const struct clk_rk3588_inits *init_data; - struct device *dev = &pdev->dev; - - init_data = device_get_match_data(dev); - if (!init_data) - return -EINVAL; - - if (init_data->inits) - init_data->inits(dev->of_node); - - return 0; -} - 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, }, }; -builtin_platform_driver_probe(clk_rk3588_driver, clk_rk3588_probe); + +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/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 043458b7c579..0de52115271b 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -19,6 +19,9 @@ #include <linux/clk-provider.h> #include <linux/io.h> #include <linux/mfd/syscon.h> +#include <linux/of_platform.h> +#include <linux/pm_clock.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/reboot.h> @@ -376,7 +379,7 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, goto err_free; for (i = 0; i < nr_clks; ++i) - clk_table[i] = ERR_PTR(-ENOENT); + clk_table[i] = ERR_PTR(-EPROBE_DEFER); ctx->reg_base = base; ctx->clk_data.clks = clk_table; @@ -446,6 +449,66 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, } EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id); +static struct platform_device *rockchip_clk_register_pdev( + struct platform_device *parent, + const char *name, + struct device_node *np) +{ + struct platform_device_info pdevinfo = { + .parent = &parent->dev, + .name = name, + .fwnode = of_fwnode_handle(np), + .of_node_reused = true, + }; + + return platform_device_register_full(&pdevinfo); +} + +static struct clk *rockchip_clk_register_linked_gate( + struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *clkbr) +{ + struct clk *linked_clk = ctx->clk_data.clks[clkbr->linked_clk_id]; + unsigned long flags = clkbr->flags | CLK_SET_RATE_PARENT; + struct device_node *np = ctx->cru_node; + struct platform_device *parent, *pdev; + struct device *dev = NULL; + int ret; + + parent = of_find_device_by_node(np); + if (!parent) { + pr_err("failed to find device for %pOF\n", np); + goto exit; + } + + pdev = rockchip_clk_register_pdev(parent, clkbr->name, np); + put_device(&parent->dev); + if (!pdev) { + pr_err("failed to register device for clock %s\n", clkbr->name); + goto exit; + } + + dev = &pdev->dev; + pm_runtime_enable(dev); + ret = pm_clk_create(dev); + if (ret) { + pr_err("failed to create PM clock list for %s\n", clkbr->name); + goto exit; + } + + ret = pm_clk_add_clk(dev, linked_clk); + if (ret) { + pr_err("failed to setup linked clock for %s\n", clkbr->name); + } + +exit: + return 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); +} + void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, struct rockchip_clk_branch *list, unsigned int nr_clk) @@ -526,6 +589,9 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, ctx->reg_base + list->gate_offset, list->gate_shift, list->gate_flags, &ctx->lock); break; + case branch_linked_gate: + clk = rockchip_clk_register_linked_gate(ctx, list); + break; case branch_composite: clk = rockchip_clk_register_branch(list->name, list->parent_names, list->num_parents, diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index fd3b476dedda..0d8e729fe332 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -517,6 +517,7 @@ enum rockchip_clk_branch_type { branch_divider, branch_fraction_divider, branch_gate, + branch_linked_gate, branch_mmc, branch_inverter, branch_factor, @@ -544,6 +545,7 @@ struct rockchip_clk_branch { int gate_offset; u8 gate_shift; u8 gate_flags; + unsigned int linked_clk_id; struct rockchip_clk_branch *child; }; @@ -842,6 +844,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, \ -- 2.43.0 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip
WARNING: multiple messages have this Message-ID (diff)
From: Sebastian Reichel <sebastian.reichel@collabora.com> To: Elaine Zhang <zhangqing@rock-chips.com>, Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>, linux-clk@vger.kernel.org Cc: Kever Yang <kever.yang@rock-chips.com>, Heiko Stuebner <heiko@sntech.de>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Conor Dooley <conor+dt@kernel.org>, huangtao@rock-chips.com, andy.yan@rock-chips.com, devicetree@vger.kernel.org, linux-rockchip@lists.infradead.org, Sebastian Reichel <sebastian.reichel@collabora.com>, kernel@collabora.com Subject: [PATCH v7 7/7] clk: rockchip: implement proper GATE_LINK support Date: Wed, 13 Dec 2023 19:46:52 +0100 [thread overview] Message-ID: <20231213185114.47565-8-sebastian.reichel@collabora.com> (raw) In-Reply-To: <20231213185114.47565-1-sebastian.reichel@collabora.com> 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. GATE_LINK type clocks handle the second parent via 'linkedclk' by using runtime PM clocks. To make that possible a new platform device is created for every clock handled in this way. Note, that before this patch clk_rk3588_probe() has never been called, because CLK_OF_DECLARE marks the DT node as processed. This patch replaces that with CLK_OF_DECLARE_DRIVER and thus the probe function is used now. This is necessary to have 'struct device' available. Also instead of builtin_platform_driver_probe, the driver has been switched to use core_initcall, since it should be fully probed before the Rockchip PM domain driver (and that is using postcore_initcall). Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> --- drivers/clk/rockchip/clk-rk3588.c | 122 +++++++++++++----------------- drivers/clk/rockchip/clk.c | 68 ++++++++++++++++- drivers/clk/rockchip/clk.h | 16 ++++ 3 files changed, 137 insertions(+), 69 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c index b30279a96dc8..f0eb380b727c 100644 --- a/drivers/clk/rockchip/clk-rk3588.c +++ b/drivers/clk/rockchip/clk-rk3588.c @@ -12,28 +12,6 @@ #include <dt-bindings/clock/rockchip,rk3588-cru.h> #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 - - #define RK3588_GRF_SOC_STATUS0 0x600 #define RK3588_PHYREF_ALT_GATE 0xc38 @@ -266,6 +244,8 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { }, \ } +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 +674,7 @@ static struct rockchip_pll_clock rk3588_pll_clks[] __initdata = { 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 */ @@ -1456,7 +1436,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1685,13 +1665,13 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1742,9 +1722,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1754,10 +1734,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -1927,10 +1907,10 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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, @@ -2428,10 +2408,12 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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), + 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), @@ -2443,9 +2425,9 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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), @@ -2453,14 +2435,18 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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__); @@ -2473,6 +2459,7 @@ static void __init rk3588_clk_init(struct device_node *np) iounmap(reg_base); return; } + early_ctx = ctx; rockchip_clk_register_plls(ctx, rk3588_pll_clks, ARRAY_SIZE(rk3588_pll_clks), @@ -2491,54 +2478,53 @@ static void __init rk3588_clk_init(struct device_node *np) &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); - + 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); -} -CLK_OF_DECLARE(rk3588_cru, "rockchip,rk3588-cru", rk3588_clk_init); - -struct clk_rk3588_inits { - void (*inits)(struct device_node *np); -}; - -static const struct clk_rk3588_inits clk_3588_cru_init = { - .inits = rk3588_clk_init, -}; + return 0; +} static const struct of_device_id clk_rk3588_match_table[] = { { .compatible = "rockchip,rk3588-cru", - .data = &clk_3588_cru_init, }, { } }; -static int __init clk_rk3588_probe(struct platform_device *pdev) -{ - const struct clk_rk3588_inits *init_data; - struct device *dev = &pdev->dev; - - init_data = device_get_match_data(dev); - if (!init_data) - return -EINVAL; - - if (init_data->inits) - init_data->inits(dev->of_node); - - return 0; -} - 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, }, }; -builtin_platform_driver_probe(clk_rk3588_driver, clk_rk3588_probe); + +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/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 043458b7c579..0de52115271b 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -19,6 +19,9 @@ #include <linux/clk-provider.h> #include <linux/io.h> #include <linux/mfd/syscon.h> +#include <linux/of_platform.h> +#include <linux/pm_clock.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/reboot.h> @@ -376,7 +379,7 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, goto err_free; for (i = 0; i < nr_clks; ++i) - clk_table[i] = ERR_PTR(-ENOENT); + clk_table[i] = ERR_PTR(-EPROBE_DEFER); ctx->reg_base = base; ctx->clk_data.clks = clk_table; @@ -446,6 +449,66 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, } EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id); +static struct platform_device *rockchip_clk_register_pdev( + struct platform_device *parent, + const char *name, + struct device_node *np) +{ + struct platform_device_info pdevinfo = { + .parent = &parent->dev, + .name = name, + .fwnode = of_fwnode_handle(np), + .of_node_reused = true, + }; + + return platform_device_register_full(&pdevinfo); +} + +static struct clk *rockchip_clk_register_linked_gate( + struct rockchip_clk_provider *ctx, + struct rockchip_clk_branch *clkbr) +{ + struct clk *linked_clk = ctx->clk_data.clks[clkbr->linked_clk_id]; + unsigned long flags = clkbr->flags | CLK_SET_RATE_PARENT; + struct device_node *np = ctx->cru_node; + struct platform_device *parent, *pdev; + struct device *dev = NULL; + int ret; + + parent = of_find_device_by_node(np); + if (!parent) { + pr_err("failed to find device for %pOF\n", np); + goto exit; + } + + pdev = rockchip_clk_register_pdev(parent, clkbr->name, np); + put_device(&parent->dev); + if (!pdev) { + pr_err("failed to register device for clock %s\n", clkbr->name); + goto exit; + } + + dev = &pdev->dev; + pm_runtime_enable(dev); + ret = pm_clk_create(dev); + if (ret) { + pr_err("failed to create PM clock list for %s\n", clkbr->name); + goto exit; + } + + ret = pm_clk_add_clk(dev, linked_clk); + if (ret) { + pr_err("failed to setup linked clock for %s\n", clkbr->name); + } + +exit: + return 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); +} + void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, struct rockchip_clk_branch *list, unsigned int nr_clk) @@ -526,6 +589,9 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, ctx->reg_base + list->gate_offset, list->gate_shift, list->gate_flags, &ctx->lock); break; + case branch_linked_gate: + clk = rockchip_clk_register_linked_gate(ctx, list); + break; case branch_composite: clk = rockchip_clk_register_branch(list->name, list->parent_names, list->num_parents, diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index fd3b476dedda..0d8e729fe332 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -517,6 +517,7 @@ enum rockchip_clk_branch_type { branch_divider, branch_fraction_divider, branch_gate, + branch_linked_gate, branch_mmc, branch_inverter, branch_factor, @@ -544,6 +545,7 @@ struct rockchip_clk_branch { int gate_offset; u8 gate_shift; u8 gate_flags; + unsigned int linked_clk_id; struct rockchip_clk_branch *child; }; @@ -842,6 +844,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, \ -- 2.43.0
next prev parent reply other threads:[~2023-12-13 18:51 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-13 18:46 ` [PATCH v7 1/7] clk: rockchip: rk3588: fix CLK_NR_CLKS usage Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-14 8:42 ` Tao Huang 2023-12-14 8:42 ` Tao Huang 2023-12-13 18:46 ` [PATCH v7 2/7] dt-bindings: clock: rk3588: drop CLK_NR_CLKS Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-14 8:01 ` Krzysztof Kozlowski 2023-12-14 8:01 ` Krzysztof Kozlowski 2023-12-13 18:46 ` [PATCH v7 3/7] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-14 8:01 ` Krzysztof Kozlowski 2023-12-14 8:01 ` Krzysztof Kozlowski 2023-12-13 18:46 ` [PATCH v7 4/7] clk: rockchip: rk3588: fix pclk_vo0grf and pclk_vo1grf Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-13 18:46 ` [PATCH v7 5/7] clk: rockchip: rk3588: fix indent Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-13 18:46 ` [PATCH v7 6/7] clk: rockchip: rk3588: use linked clock ID for GATE_LINK Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel 2023-12-13 18:46 ` Sebastian Reichel [this message] 2023-12-13 18:46 ` [PATCH v7 7/7] clk: rockchip: implement proper GATE_LINK support Sebastian Reichel
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20231213185114.47565-8-sebastian.reichel@collabora.com \ --to=sebastian.reichel@collabora.com \ --cc=andy.yan@rock-chips.com \ --cc=conor+dt@kernel.org \ --cc=devicetree@vger.kernel.org \ --cc=heiko@sntech.de \ --cc=huangtao@rock-chips.com \ --cc=kernel@collabora.com \ --cc=kever.yang@rock-chips.com \ --cc=krzysztof.kozlowski+dt@linaro.org \ --cc=linux-clk@vger.kernel.org \ --cc=linux-rockchip@lists.infradead.org \ --cc=mturquette@baylibre.com \ --cc=robh+dt@kernel.org \ --cc=sboyd@kernel.org \ --cc=zhangqing@rock-chips.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.