* [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support
@ 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
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
Hi,
I've send this as v7 for the series from Elaine [0], since it kinds of is. These
patches are written from scratch, though. There are two parts:
part 1:
Elaine's series used to contain patches for the VO1GRF handling, but they were
dropped at some point because of the CLK_NR_CLKS feedback from the DT
maintainers. I added some code, that should hopefully fix everyones concerns by
figuring out the right number at runtime. I also moved the correct handling of
pclk_vo0grf/pclk_vo1grf before proper handling of GATE_LINK clocks, so that it
can be merged ASAP. These patches are needed for HDMI RX/TX support on RK3588
and should not be blocked by the GATE_LINK discussion.
part 2:
For proper GATE_LINK support I tried implementing the suggestion from Stephen
Boyd to use clk PM operations by creating MFD dynamically. This required some
restructuring, since CLK_OF_DECLARE() is called before devices are available.
All of this can be found in the last patch of this series.
[0] https://lore.kernel.org/linux-clk/20231110020358.12840-1-zhangqing@rock-chips.com/
Greetings,
-- Sebstian
Sebastian Reichel (7):
clk: rockchip: rk3588: fix CLK_NR_CLKS usage
dt-bindings: clock: rk3588: drop CLK_NR_CLKS
dt-bindings: clock: rk3588: add missing PCLK_VO1GRF
clk: rockchip: rk3588: fix pclk_vo0grf and pclk_vo1grf
clk: rockchip: rk3588: fix indent
clk: rockchip: rk3588: use linked clock ID for GATE_LINK
clk: rockchip: implement proper GATE_LINK support
drivers/clk/rockchip/clk-rk3588.c | 163 ++++++++----------
drivers/clk/rockchip/clk.c | 85 ++++++++-
drivers/clk/rockchip/clk.h | 18 ++
.../dt-bindings/clock/rockchip,rk3588-cru.h | 3 +-
4 files changed, 178 insertions(+), 91 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v7 1/7] clk: rockchip: rk3588: fix CLK_NR_CLKS usage
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-14 8:42 ` Tao Huang
2023-12-13 18:46 ` [PATCH v7 2/7] dt-bindings: clock: rk3588: drop CLK_NR_CLKS Sebastian Reichel
` (5 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
CLK_NR_CLKS is not part of the DT bindings and needs to be removed
from it, just like it recently happened for other platforms. This
takes care of it by introducing a new function identifying the
maximum used clock ID at runtime.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/clk/rockchip/clk-rk3588.c | 5 ++++-
drivers/clk/rockchip/clk.c | 17 +++++++++++++++++
drivers/clk/rockchip/clk.h | 2 ++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 6994165e0395..0b60ae78f9d8 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -2458,15 +2458,18 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
static void __init rk3588_clk_init(struct device_node *np)
{
struct rockchip_clk_provider *ctx;
+ unsigned long clk_nr_clks;
void __iomem *reg_base;
+ clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
+ ARRAY_SIZE(rk3588_clk_branches)) + 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(np, reg_base, clk_nr_clks);
if (IS_ERR(ctx)) {
pr_err("%s: rockchip clk init failed\n", __func__);
iounmap(reg_base);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 4059d9365ae6..043458b7c579 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -429,6 +429,23 @@ void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
}
EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
+unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
+ unsigned int nr_clk)
+{
+ unsigned int idx;
+ unsigned long max;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ if (list->id > max)
+ max = list->id;
+ if (list->child && list->child->id > max)
+ max = list->id;
+ }
+
+ return max;
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id);
+
void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
struct rockchip_clk_branch *list,
unsigned int nr_clk)
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 758ebaf2236b..fd3b476dedda 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -973,6 +973,8 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
void __iomem *base, unsigned long nr_clks);
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,
+ unsigned int nr_clk);
void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
struct rockchip_clk_branch *list,
unsigned int nr_clk);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 2/7] dt-bindings: clock: rk3588: drop CLK_NR_CLKS
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support 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:01 ` Krzysztof Kozlowski
2023-12-13 18:46 ` [PATCH v7 3/7] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF Sebastian Reichel
` (4 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
CLK_NR_CLKS should not be part of the binding. Let's drop it, since
the kernel code no longer uses it either.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
include/dt-bindings/clock/rockchip,rk3588-cru.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/include/dt-bindings/clock/rockchip,rk3588-cru.h b/include/dt-bindings/clock/rockchip,rk3588-cru.h
index 5790b1391201..7c6f0ec7c979 100644
--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
+++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
@@ -734,8 +734,6 @@
#define PCLK_AV1_PRE 719
#define HCLK_SDIO_PRE 720
-#define CLK_NR_CLKS (HCLK_SDIO_PRE + 1)
-
/* scmi-clocks indices */
#define SCMI_CLK_CPUL 0
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 3/7] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support 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 ` [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-13 18:46 ` [PATCH v7 4/7] clk: rockchip: rk3588: fix pclk_vo0grf and pclk_vo1grf Sebastian Reichel
` (3 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
Add PCLK_VO1GRF to complement PCLK_VO0GRF. This will be needed
for HDMI support.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
include/dt-bindings/clock/rockchip,rk3588-cru.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/clock/rockchip,rk3588-cru.h b/include/dt-bindings/clock/rockchip,rk3588-cru.h
index 7c6f0ec7c979..0c7d3ca2d5bc 100644
--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
+++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
@@ -733,6 +733,7 @@
#define ACLK_AV1_PRE 718
#define PCLK_AV1_PRE 719
#define HCLK_SDIO_PRE 720
+#define PCLK_VO1GRF 721
/* scmi-clocks indices */
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 4/7] clk: rockchip: rk3588: fix pclk_vo0grf and pclk_vo1grf
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support Sebastian Reichel
` (2 preceding siblings ...)
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-13 18:46 ` [PATCH v7 5/7] clk: rockchip: rk3588: fix indent Sebastian Reichel
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
Currently pclk_vo1grf is not exposed, but it should be referenced
from the vo1_grf syscon, which needs it enabled. That syscon is
required for HDMI RX and TX functionality among other things.
Apart from that pclk_vo0grf and pclk_vo1grf are both linked gates
and need the VO's hclk enabled in addition to their parent clock.
No Fixes tag has been added, since the logic requiring these clocks
is not yet upstream anyways.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/clk/rockchip/clk-rk3588.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 0b60ae78f9d8..26330d655159 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -1851,8 +1851,6 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
RK3588_CLKGATE_CON(56), 0, GFLAGS),
GATE(PCLK_TRNG0, "pclk_trng0", "pclk_vo0_root", 0,
RK3588_CLKGATE_CON(56), 1, GFLAGS),
- GATE(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", CLK_IGNORE_UNUSED,
- RK3588_CLKGATE_CON(55), 10, GFLAGS),
COMPOSITE(CLK_I2S4_8CH_TX_SRC, "clk_i2s4_8ch_tx_src", gpll_aupll_p, 0,
RK3588_CLKSEL_CON(118), 5, 1, MFLAGS, 0, 5, DFLAGS,
RK3588_CLKGATE_CON(56), 11, GFLAGS),
@@ -1998,8 +1996,6 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
RK3588_CLKGATE_CON(60), 9, GFLAGS),
GATE(PCLK_TRNG1, "pclk_trng1", "pclk_vo1_root", 0,
RK3588_CLKGATE_CON(60), 10, GFLAGS),
- GATE(0, "pclk_vo1grf", "pclk_vo1_root", CLK_IGNORE_UNUSED,
- RK3588_CLKGATE_CON(59), 12, GFLAGS),
GATE(PCLK_S_EDP0, "pclk_s_edp0", "pclk_vo1_s_root", 0,
RK3588_CLKGATE_CON(59), 14, GFLAGS),
GATE(PCLK_S_EDP1, "pclk_s_edp1", "pclk_vo1_s_root", 0,
@@ -2447,12 +2443,14 @@ 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", 0, RK3588_CLKGATE_CON(55), 5, GFLAGS),
+ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", RK3588_LINKED_CLK, 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", 0, RK3588_CLKGATE_CON(59), 9, 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(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),
+ GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", "hclk_vo0", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
+ 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)
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 5/7] clk: rockchip: rk3588: fix indent
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support Sebastian Reichel
` (3 preceding siblings ...)
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 6/7] clk: rockchip: rk3588: use linked clock ID for GATE_LINK Sebastian Reichel
2023-12-13 18:46 ` [PATCH v7 7/7] clk: rockchip: implement proper GATE_LINK support Sebastian Reichel
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
pclk_mailbox2 is the only RK3588 clock indented with one tab instead of
two tabs. Let's fix this.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/clk/rockchip/clk-rk3588.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 26330d655159..2e8bdd93c625 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -1004,7 +1004,7 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
GATE(PCLK_MAILBOX1, "pclk_mailbox1", "pclk_top_root", 0,
RK3588_CLKGATE_CON(16), 12, GFLAGS),
GATE(PCLK_MAILBOX2, "pclk_mailbox2", "pclk_top_root", 0,
- RK3588_CLKGATE_CON(16), 13, GFLAGS),
+ RK3588_CLKGATE_CON(16), 13, GFLAGS),
GATE(PCLK_PMU2, "pclk_pmu2", "pclk_top_root", CLK_IS_CRITICAL,
RK3588_CLKGATE_CON(19), 3, GFLAGS),
GATE(PCLK_PMUCM0_INTMUX, "pclk_pmucm0_intmux", "pclk_top_root", CLK_IS_CRITICAL,
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 6/7] clk: rockchip: rk3588: use linked clock ID for GATE_LINK
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support Sebastian Reichel
` (4 preceding siblings ...)
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 7/7] clk: rockchip: implement proper GATE_LINK support Sebastian Reichel
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
In preparation for properly supporting GATE_LINK switch the unused
linked clock argument from the clock's name to its ID. This allows
easy and fast lookup of the 'struct clk'.
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/clk/rockchip/clk-rk3588.c | 46 +++++++++++++++----------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 2e8bdd93c625..b30279a96dc8 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -29,7 +29,7 @@
* power, but avoids leaking implementation details into DT or hanging the
* system.
*/
-#define GATE_LINK(_id, cname, pname, linkname, f, o, b, gf) \
+#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
@@ -2429,28 +2429,28 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0,
RK3588_CLKGATE_CON(68), 2, GFLAGS),
- 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(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),
- GATE_LINK(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 5, GFLAGS),
- GATE_LINK(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", "aclk_rkvenc0", 0, RK3588_CLKGATE_CON(48), 3, GFLAGS),
- GATE_LINK(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", "hclk_rkvenc0", 0, RK3588_CLKGATE_CON(48), 2, GFLAGS),
- GATE_LINK(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(40), 5, GFLAGS),
- GATE_LINK(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(40), 6, GFLAGS),
- 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(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(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),
- GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", "hclk_vo0", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
- GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", "hclk_vo1", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ 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(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),
+ GATE_LINK(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 5, GFLAGS),
+ GATE_LINK(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", ACLK_RKVENC0, 0, RK3588_CLKGATE_CON(48), 3, GFLAGS),
+ GATE_LINK(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", HCLK_RKVENC0, 0, RK3588_CLKGATE_CON(48), 2, GFLAGS),
+ GATE_LINK(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(40), 5, GFLAGS),
+ GATE_LINK(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(40), 6, GFLAGS),
+ 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(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(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),
+ GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", HCLK_VO0, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
+ 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)
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 7/7] clk: rockchip: implement proper GATE_LINK support
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support Sebastian Reichel
` (5 preceding siblings ...)
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
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Reichel @ 2023-12-13 18:46 UTC (permalink / raw)
To: Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
Sebastian Reichel, kernel
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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v7 2/7] dt-bindings: clock: rk3588: drop CLK_NR_CLKS
2023-12-13 18:46 ` [PATCH v7 2/7] dt-bindings: clock: rk3588: drop CLK_NR_CLKS Sebastian Reichel
@ 2023-12-14 8:01 ` Krzysztof Kozlowski
0 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-14 8:01 UTC (permalink / raw)
To: Sebastian Reichel, Elaine Zhang, Michael Turquette, Stephen Boyd,
linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
kernel
On 13/12/2023 19:46, Sebastian Reichel wrote:
> CLK_NR_CLKS should not be part of the binding. Let's drop it, since
> the kernel code no longer uses it either.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v7 3/7] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF
2023-12-13 18:46 ` [PATCH v7 3/7] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF Sebastian Reichel
@ 2023-12-14 8:01 ` Krzysztof Kozlowski
0 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2023-12-14 8:01 UTC (permalink / raw)
To: Sebastian Reichel, Elaine Zhang, Michael Turquette, Stephen Boyd,
linux-clk
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, huangtao, andy.yan, devicetree, linux-rockchip,
kernel
On 13/12/2023 19:46, Sebastian Reichel wrote:
> Add PCLK_VO1GRF to complement PCLK_VO0GRF. This will be needed
> for HDMI support.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v7 1/7] clk: rockchip: rk3588: fix CLK_NR_CLKS usage
2023-12-13 18:46 ` [PATCH v7 1/7] clk: rockchip: rk3588: fix CLK_NR_CLKS usage Sebastian Reichel
@ 2023-12-14 8:42 ` Tao Huang
0 siblings, 0 replies; 11+ messages in thread
From: Tao Huang @ 2023-12-14 8:42 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Kever Yang, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, andy.yan, devicetree, linux-rockchip, kernel,
Elaine Zhang, Michael Turquette, Stephen Boyd, linux-clk
On 2023/12/14 上午2:46, Sebastian Reichel wrote:
> CLK_NR_CLKS is not part of the DT bindings and needs to be removed
> from it, just like it recently happened for other platforms. This
> takes care of it by introducing a new function identifying the
> maximum used clock ID at runtime.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
> drivers/clk/rockchip/clk-rk3588.c | 5 ++++-
> drivers/clk/rockchip/clk.c | 17 +++++++++++++++++
> drivers/clk/rockchip/clk.h | 2 ++
> 3 files changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
> index 6994165e0395..0b60ae78f9d8 100644
> --- a/drivers/clk/rockchip/clk-rk3588.c
> +++ b/drivers/clk/rockchip/clk-rk3588.c
> @@ -2458,15 +2458,18 @@ static struct rockchip_clk_branch rk3588_clk_branches[] __initdata = {
> static void __init rk3588_clk_init(struct device_node *np)
> {
> struct rockchip_clk_provider *ctx;
> + unsigned long clk_nr_clks;
> void __iomem *reg_base;
>
> + clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
> + ARRAY_SIZE(rk3588_clk_branches)) + 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(np, reg_base, clk_nr_clks);
> if (IS_ERR(ctx)) {
> pr_err("%s: rockchip clk init failed\n", __func__);
> iounmap(reg_base);
> diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
> index 4059d9365ae6..043458b7c579 100644
> --- a/drivers/clk/rockchip/clk.c
> +++ b/drivers/clk/rockchip/clk.c
> @@ -429,6 +429,23 @@ void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
> }
> EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
>
> +unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
> + unsigned int nr_clk)
> +{
> + unsigned int idx;
> + unsigned long max;
smatch report warning: uninitialized symbol 'max'.
And make sure this function return correct number, for example, when nr_clk == 0.
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + if (list->id > max)
> + max = list->id;
> + if (list->child && list->child->id > max)
> + max = list->id;
> + }
> +
> + return max;
> +}
> +EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id);
> +
> void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
> struct rockchip_clk_branch *list,
> unsigned int nr_clk)
> diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
> index 758ebaf2236b..fd3b476dedda 100644
> --- a/drivers/clk/rockchip/clk.h
> +++ b/drivers/clk/rockchip/clk.h
> @@ -973,6 +973,8 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
> void __iomem *base, unsigned long nr_clks);
> 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,
> + unsigned int nr_clk);
> void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
> struct rockchip_clk_branch *list,
> unsigned int nr_clk);
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-12-14 8:49 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-13 18:46 [PATCH v7 0/7] rockchip: clk: improve GATE_LINK support Sebastian Reichel
2023-12-13 18:46 ` [PATCH v7 1/7] clk: rockchip: rk3588: fix CLK_NR_CLKS usage Sebastian Reichel
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-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-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 ` [PATCH v7 5/7] clk: rockchip: rk3588: fix indent 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 ` [PATCH v7 7/7] clk: rockchip: implement proper GATE_LINK support Sebastian Reichel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).