]> git.ipfire.org Git - thirdparty/openwrt.git/blob
564ef84c9e2a87547126f2f54455bfc4a7343256
[thirdparty/openwrt.git] /
1 From 126560c909f38f00c08dd5f35f50c981d5e25e1f Mon Sep 17 00:00:00 2001
2 From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
3 Date: Fri, 10 May 2024 15:30:44 +0100
4 Subject: [PATCH 1177/1215] clk: clk-rp1: Add "varsrc" clocks to represent MIPI
5 byte clocks
6
7 Add a new class of clocks to RP1 to represent clock sources whose
8 frequency changes at run-time as a side-effect of some other driver.
9 Specifically this is for the two MIPI DSI byte-clock sources.
10
11 Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
12 ---
13 drivers/clk/clk-rp1.c | 73 +++++++++++++++++++++++++++++++++++++++++++
14 1 file changed, 73 insertions(+)
15
16 --- a/drivers/clk/clk-rp1.c
17 +++ b/drivers/clk/clk-rp1.c
18 @@ -394,6 +394,11 @@ struct rp1_clock {
19 unsigned long cached_rate;
20 };
21
22 +struct rp1_varsrc {
23 + struct clk_hw hw;
24 + struct rp1_clockman *clockman;
25 + unsigned long rate;
26 +};
27
28 struct rp1_clk_change {
29 struct clk_hw *hw;
30 @@ -1414,6 +1419,34 @@ static void rp1_clk_debug_init(struct cl
31 rp1_debugfs_regset(clockman, 0, regs, i, dentry);
32 }
33
34 +static int rp1_varsrc_set_rate(struct clk_hw *hw,
35 + unsigned long rate, unsigned long parent_rate)
36 +{
37 + struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
38 +
39 + /*
40 + * "varsrc" exists purely to let clock dividers know the frequency
41 + * of an externally-managed clock source (such as MIPI DSI byte-clock)
42 + * which may change at run-time as a side-effect of some other driver.
43 + */
44 + varsrc->rate = rate;
45 + return 0;
46 +}
47 +
48 +static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw,
49 + unsigned long parent_rate)
50 +{
51 + struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
52 +
53 + return varsrc->rate;
54 +}
55 +
56 +static long rp1_varsrc_round_rate(struct clk_hw *hw, unsigned long rate,
57 + unsigned long *parent_rate)
58 +{
59 + return rate;
60 +}
61 +
62 static const struct clk_ops rp1_pll_core_ops = {
63 .is_prepared = rp1_pll_core_is_on,
64 .prepare = rp1_pll_core_on,
65 @@ -1464,6 +1497,12 @@ static const struct clk_ops rp1_clk_ops
66 .debug_init = rp1_clk_debug_init,
67 };
68
69 +static const struct clk_ops rp1_varsrc_ops = {
70 + .set_rate = rp1_varsrc_set_rate,
71 + .recalc_rate = rp1_varsrc_recalc_rate,
72 + .round_rate = rp1_varsrc_round_rate,
73 +};
74 +
75 static bool rp1_clk_is_claimed(const char *name);
76
77 static struct clk_hw *rp1_register_pll_core(struct rp1_clockman *clockman,
78 @@ -1647,6 +1686,35 @@ static struct clk_hw *rp1_register_clock
79 return &clock->hw;
80 }
81
82 +static struct clk_hw *rp1_register_varsrc(struct rp1_clockman *clockman,
83 + const void *data)
84 +{
85 + const char *name = *(char const * const *)data;
86 + struct rp1_varsrc *clock;
87 + struct clk_init_data init;
88 + int ret;
89 +
90 + memset(&init, 0, sizeof(init));
91 + init.parent_names = &ref_clock;
92 + init.num_parents = 1;
93 + init.name = name;
94 + init.flags = CLK_IGNORE_UNUSED;
95 + init.ops = &rp1_varsrc_ops;
96 +
97 + clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
98 + if (!clock)
99 + return NULL;
100 +
101 + clock->clockman = clockman;
102 + clock->hw.init = &init;
103 +
104 + ret = devm_clk_hw_register(clockman->dev, &clock->hw);
105 + if (ret)
106 + return ERR_PTR(ret);
107 +
108 + return &clock->hw;
109 +}
110 +
111 struct rp1_clk_desc {
112 struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
113 const void *data);
114 @@ -1676,6 +1744,8 @@ struct rp1_clk_desc {
115 &(struct rp1_clock_data) \
116 {__VA_ARGS__})
117
118 +#define REGISTER_VARSRC(n) _REGISTER(&rp1_register_varsrc, &(const char *){n})
119 +
120 static const struct rp1_clk_desc clk_desc_array[] = {
121 [RP1_PLL_SYS_CORE] = REGISTER_PLL_CORE(
122 .name = "pll_sys_core",
123 @@ -2318,6 +2388,9 @@ static const struct rp1_clk_desc clk_des
124 .max_freq = 200 * MHz,
125 .fc0_src = FC_NUM(3, 6),
126 ),
127 +
128 + [RP1_CLK_MIPI0_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi0_dsi_byteclk"),
129 + [RP1_CLK_MIPI1_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi1_dsi_byteclk"),
130 };
131
132 static bool rp1_clk_claimed[ARRAY_SIZE(clk_desc_array)];