Message ID | 20230403193250.108693-2-sebastian.reichel@collabora.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Improve RK3588 clocks and power domains support | expand |
Hi Sebastian, On Tue, 4 Apr 2023 at 01:03, Sebastian Reichel <sebastian.reichel@collabora.com> wrote: > > RK3588 has a couple of hardware blocks called Native Interface Unit > (NIU) that gate the clocks to devices behind them. Effectively this > means that some clocks require two parent clocks being enabled. > Downstream implemented this by using a separate clock driver > ("clk-link") for them, which enables the second clock using PM > framework. > > In the upstream kernel we are currently missing support for the second > parent. The information about it is in the GATE_LINK() macro as > linkname, but that is not used. Thus the second parent clock is not > properly enabled. So far this did not really matter, since these clocks > are mostly required for the more advanced IP blocks, that are not yet > supported upstream. As this is about to change we need a fix. There > are three options available: > > 1. Properly implement support for having two parent clocks in the > clock framework. > 2. Mark the affected clocks CLK_IGNORE_UNUSED, so that they are not > disabled. This wastes some power, but keeps the hack contained > within the clock driver. Going from this to the first solution > is easy once that has been implemented. > 3. Enabling the extra clock in the consumer driver. This leaks some > implementation details into DT. > > This patch implements the second option as an intermediate solution > until the first one is available. I used an alias for CLK_IS_CRITICAL, > so that it's easy to see which clocks are not really critical once > the clock framework supports a better way to implement this. > > Tested-by: Vincent Legoll <vincent.legoll@gmail.com> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> > --- > drivers/clk/rockchip/clk-rk3588.c | 42 +++++++++++++++++++------------ > 1 file changed, 26 insertions(+), 16 deletions(-) > > diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c > index b7ce3fbd6fa6..6994165e0395 100644 > --- a/drivers/clk/rockchip/clk-rk3588.c > +++ b/drivers/clk/rockchip/clk-rk3588.c > @@ -13,15 +13,25 @@ > #include "clk.h" > > /* > - * GATE with additional linked clock. Downstream enables the linked clock > - * (via runtime PM) whenever the gate is enabled. The downstream implementation > - * does this via separate clock nodes for each of the linked gate clocks, > - * which leaks parts of the clock tree into DT. It is unclear why this is > - * actually needed and things work without it for simple use cases. Thus > - * the linked clock is ignored for now. > + * 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. > */ Does it mean the clk-link topology in the downstream kernel can be reused the same as normal clock notation? For example, I'm trying to add HCLK_VO1 directly to VO1 syscon instead of routing to pclk_vo1_grf(done downstream) vo1_grf: syscon@fd5a8000 { compatible = "rockchip,rk3588-vo-grf", "syscon"; reg = <0x0 0xfd5a8000 0x0 0x100>; clocks = <&cru HCLK_VO1>; }; This seems breaking syscon for vo1_grf and observed a bus error while accessing regmap. I remember in one of the RKDC discussion that the double parenting of these clocks is mandatory while accessing associated IP blocks. Any thoughts? Thanks, Jagan.
Hello Jagan, On Thu, Jul 13, 2023 at 08:25:03PM +0530, Jagan Teki wrote: > On Tue, 4 Apr 2023 at 01:03, Sebastian Reichel > <sebastian.reichel@collabora.com> wrote: > [...] > > + * 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. > > */ > > Does it mean the clk-link topology in the downstream kernel can be > reused the same as normal clock notation? Yes. > For example, I'm trying to add HCLK_VO1 directly to VO1 syscon instead > of routing to pclk_vo1_grf(done downstream) > vo1_grf: syscon@fd5a8000 { > compatible = "rockchip,rk3588-vo-grf", "syscon"; > reg = <0x0 0xfd5a8000 0x0 0x100>; > clocks = <&cru HCLK_VO1>; You need PCLK_VO1 (which is currently not exposed; I somehow missed it). > }; > > This seems breaking syscon for vo1_grf and observed a bus error > while accessing regmap. I investigated the issue you are seeing some weeks ago when my co-workers started to work on HDMI RX and TX. You are probably just missing this patch: https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commit/ecc6415344957fa88356cec10f8b75a9da603a7b > I remember in one of the RKDC discussion that the double parenting > of these clocks is mandatory while accessing associated IP blocks. Yes, it is necessary. > Any thoughts? The upstream workaround/hack is to have the second parent always enabled. This obviously wastes power, but means that the hardware description in the DT is correct. Once the clock framework supports two parents the kernel can be updated without touching the DT, which is considered ABI. Greetings, -- Sebastian
Hi, On Fri, 14 Jul 2023 at 06:44, zhangqing@rock-chips.com <zhangqing@rock-chips.com> wrote: > > Hi Sebastian, > > The clock needs to rely on two parent clocks, which is required by design.Refer to the attachment for details. > Our internal branch is implemented using clk-link.c. Recently, I will implement the real GATE_LINK API according to upstream, without modifying DT. Do you have a solution to share or any pointers? I tried to use clk-link by dropping GATE_LINK from clk-rk3588.c however the issue remains still as double-parenting is unsupportive. Did you add double-parenting to the mainline clk tree? Other than that, I have used existing clk and try to attach the link clock in conventional clock way like vo1_grf: syscon@fd5a8000 { compatible = "rockchip,rk3588-vo-grf", "syscon"; reg = <0x0 0xfd5a8000 0x0 0x100>; clocks = <&cru PCLK_VO1GRF>; }; This also seems similar issue. Thanks, Jagan.
Hi Sebastian, On Fri, 14 Jul 2023 at 01:08, Sebastian Reichel <sebastian.reichel@collabora.com> wrote: > > Hello Jagan, > > On Thu, Jul 13, 2023 at 08:25:03PM +0530, Jagan Teki wrote: > > On Tue, 4 Apr 2023 at 01:03, Sebastian Reichel > > <sebastian.reichel@collabora.com> wrote: > > [...] > > > + * 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. > > > */ > > > > Does it mean the clk-link topology in the downstream kernel can be > > reused the same as normal clock notation? > > Yes. > > > For example, I'm trying to add HCLK_VO1 directly to VO1 syscon instead > > of routing to pclk_vo1_grf(done downstream) > > vo1_grf: syscon@fd5a8000 { > > compatible = "rockchip,rk3588-vo-grf", "syscon"; > > reg = <0x0 0xfd5a8000 0x0 0x100>; > > clocks = <&cru HCLK_VO1>; > > You need PCLK_VO1 (which is currently not exposed; I somehow missed > it). > > > }; > > > > This seems breaking syscon for vo1_grf and observed a bus error > > while accessing regmap. > > I investigated the issue you are seeing some weeks ago when my > co-workers started to work on HDMI RX and TX. You are probably > just missing this patch: > > https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commit/ecc6415344957fa88356cec10f8b75a9da603a7b In fact, I tried this solution as well, by connecting the PCLK_VO1GRF. vo1_grf: syscon@fd5a8000 { compatible = "rockchip,rk3588-vo-grf", "syscon"; reg = <0x0 0xfd5a8000 0x0 0x100>; clocks = <&cru PCLK_VO1GRF>; }; But the result seems the same, accessing vo1_grf triggers an abort [1] [1] https://gist.github.com/openedev/e241da8180341ffbf4dc6a26de7efa31 Thanks, Jagan.
在 2023/7/14 13:33, Jagan Teki 写道: > Hi Sebastian, > > On Fri, 14 Jul 2023 at 01:08, Sebastian Reichel > <sebastian.reichel@collabora.com> wrote: >> Hello Jagan, >> >> On Thu, Jul 13, 2023 at 08:25:03PM +0530, Jagan Teki wrote: >>> On Tue, 4 Apr 2023 at 01:03, Sebastian Reichel >>> <sebastian.reichel@collabora.com> wrote: >>> [...] >>>> + * 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. >>>> */ >>> Does it mean the clk-link topology in the downstream kernel can be >>> reused the same as normal clock notation? >> Yes. >> >>> For example, I'm trying to add HCLK_VO1 directly to VO1 syscon instead >>> of routing to pclk_vo1_grf(done downstream) >>> vo1_grf: syscon@fd5a8000 { >>> compatible = "rockchip,rk3588-vo-grf", "syscon"; >>> reg = <0x0 0xfd5a8000 0x0 0x100>; >>> clocks = <&cru HCLK_VO1>; >> You need PCLK_VO1 (which is currently not exposed; I somehow missed >> it). Maybe this submission is helpful The true GATE_LINK callback is implemented. https://patchwork.kernel.org/project/linux-clk/patch/20230728020810.29732-4-zhangqing@rock-chips.com/ vo1_grf: syscon@fd5a8000 { compatible = "rockchip,rk3588-vo-grf", "syscon"; reg = <0x0 0xfd5a8000 0x0 0x100>; clocks = <&cru PCLK_VO1GRF>; When enable pclk_vo1grf,will enable pclk_vo1_root and hclk_vo1. >>> }; >>> >>> This seems breaking syscon for vo1_grf and observed a bus error >>> while accessing regmap. >> I investigated the issue you are seeing some weeks ago when my >> co-workers started to work on HDMI RX and TX. You are probably >> just missing this patch: >> >> https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commit/ecc6415344957fa88356cec10f8b75a9da603a7b > In fact, I tried this solution as well, by connecting the PCLK_VO1GRF. > > vo1_grf: syscon@fd5a8000 { > compatible = "rockchip,rk3588-vo-grf", "syscon"; > reg = <0x0 0xfd5a8000 0x0 0x100>; > clocks = <&cru PCLK_VO1GRF>; > }; > > But the result seems the same, accessing vo1_grf triggers an abort [1] > > [1] https://gist.github.com/openedev/e241da8180341ffbf4dc6a26de7efa31 > > Thanks, > Jagan.
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c index b7ce3fbd6fa6..6994165e0395 100644 --- a/drivers/clk/rockchip/clk-rk3588.c +++ b/drivers/clk/rockchip/clk-rk3588.c @@ -13,15 +13,25 @@ #include "clk.h" /* - * GATE with additional linked clock. Downstream enables the linked clock - * (via runtime PM) whenever the gate is enabled. The downstream implementation - * does this via separate clock nodes for each of the linked gate clocks, - * which leaks parts of the clock tree into DT. It is unclear why this is - * actually needed and things work without it for simple use cases. Thus - * the linked clock is ignored for now. + * 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, linkname, 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 @@ -1446,7 +1456,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, 0, + COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RK3588_LINKED_CLK, 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, @@ -1675,13 +1685,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, 0, + COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, RK3588_LINKED_CLK, 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, 0, + COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, 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, @@ -1732,9 +1742,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", 0, + GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(47), 4, GFLAGS), - GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0, + GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", RK3588_LINKED_CLK, 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, @@ -1744,10 +1754,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, 0, + COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, RK3588_LINKED_CLK, 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, 0, + COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, 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, @@ -1919,10 +1929,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, 0, + COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, RK3588_LINKED_CLK, 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, 0, + COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RK3588_LINKED_CLK, 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, @@ -2425,7 +2435,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = { 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", 0, RK3588_CLKGATE_CON(31), 2, GFLAGS), + GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", "aclk_nvm_root", RK3588_LINKED_CLK, 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),