bcm27xx: add support for linux v5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.15 / 950-0834-clk-Always-set-the-rate-on-clk_set_range_rate.patch
1 From c12b9d21ea40c608be608b83f803efdbdfe9657a Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Mon, 17 Jan 2022 16:43:13 +0100
4 Subject: [PATCH] clk: Always set the rate on clk_set_range_rate
5
6 When we change a clock minimum or maximum using clk_set_rate_range(),
7 clk_set_min_rate() or clk_set_max_rate(), the current code will only
8 trigger a new rate change if the rate is outside of the new boundaries.
9
10 However, a clock driver might want to always keep the clock rate to
11 one of its boundary, for example the minimum to keep the power
12 consumption as low as possible.
13
14 Since they don't always get called though, clock providers don't have the
15 opportunity to implement this behaviour.
16
17 Let's trigger a clk_set_rate() on the previous requested rate every time
18 clk_set_rate_range() is called. That way, providers that care about the
19 new boundaries have a chance to adjust the rate, while providers that
20 don't care about those new boundaries will return the same rate than
21 before, which will be ignored by clk_set_rate() and won't result in a
22 new rate change.
23
24 Suggested-by: Stephen Boyd <sboyd@kernel.org>
25 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
26 ---
27 drivers/clk/clk.c | 45 ++++++++++++++++----------------
28 drivers/clk/clk_test.c | 58 +++++++++++++++++++-----------------------
29 2 files changed, 49 insertions(+), 54 deletions(-)
30
31 --- a/drivers/clk/clk.c
32 +++ b/drivers/clk/clk.c
33 @@ -2372,28 +2372,29 @@ int clk_set_rate_range(struct clk *clk,
34 goto out;
35 }
36
37 - rate = clk_core_get_rate_nolock(clk->core);
38 - if (rate < min || rate > max) {
39 - /*
40 - * FIXME:
41 - * We are in bit of trouble here, current rate is outside the
42 - * the requested range. We are going try to request appropriate
43 - * range boundary but there is a catch. It may fail for the
44 - * usual reason (clock broken, clock protected, etc) but also
45 - * because:
46 - * - round_rate() was not favorable and fell on the wrong
47 - * side of the boundary
48 - * - the determine_rate() callback does not really check for
49 - * this corner case when determining the rate
50 - */
51 -
52 - rate = clamp(clk->core->req_rate, min, max);
53 - ret = clk_core_set_rate_nolock(clk->core, rate);
54 - if (ret) {
55 - /* rollback the changes */
56 - clk->min_rate = old_min;
57 - clk->max_rate = old_max;
58 - }
59 + /*
60 + * Since the boundaries have been changed, let's give the
61 + * opportunity to the provider to adjust the clock rate based on
62 + * the new boundaries.
63 + *
64 + * We also need to handle the case where the clock is currently
65 + * outside of the boundaries. Clamping the last requested rate
66 + * to the current minimum and maximum will also handle this.
67 + *
68 + * FIXME:
69 + * There is a catch. It may fail for the usual reason (clock
70 + * broken, clock protected, etc) but also because:
71 + * - round_rate() was not favorable and fell on the wrong
72 + * side of the boundary
73 + * - the determine_rate() callback does not really check for
74 + * this corner case when determining the rate
75 + */
76 + rate = clamp(clk->core->req_rate, min, max);
77 + ret = clk_core_set_rate_nolock(clk->core, rate);
78 + if (ret) {
79 + /* rollback the changes */
80 + clk->min_rate = old_min;
81 + clk->max_rate = old_max;
82 }
83
84 out:
85 --- a/drivers/clk/clk_test.c
86 +++ b/drivers/clk/clk_test.c
87 @@ -549,13 +549,12 @@ static struct kunit_suite clk_range_test
88 };
89
90 /*
91 - * Test that if:
92 - * - we have several subsequent calls to clk_set_rate_range();
93 - * - and we have a round_rate ops that always return the maximum
94 - * frequency allowed;
95 + * Test that if we have several subsequent calls to
96 + * clk_set_rate_range(), the core will reevaluate whether a new rate is
97 + * needed each and every time.
98 *
99 - * The clock will run at the minimum of all maximum boundaries
100 - * requested, even if those boundaries aren't there anymore.
101 + * With clk_dummy_maximize_rate_ops, this means that the the rate will
102 + * trail along the maximum as it evolves.
103 */
104 static void clk_range_test_set_range_rate_maximized(struct kunit *test)
105 {
106 @@ -596,18 +595,16 @@ static void clk_range_test_set_range_rat
107
108 rate = clk_get_rate(clk);
109 KUNIT_ASSERT_GT(test, rate, 0);
110 - KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2 - 1000);
111 + KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
112 }
113
114 /*
115 - * Test that if:
116 - * - we have several subsequent calls to clk_set_rate_range(), across
117 - * multiple users;
118 - * - and we have a round_rate ops that always return the maximum
119 - * frequency allowed;
120 + * Test that if we have several subsequent calls to
121 + * clk_set_rate_range(), across multiple users, the core will reevaluate
122 + * whether a new rate is needed each and every time.
123 *
124 - * The clock will run at the minimum of all maximum boundaries
125 - * requested, even if those boundaries aren't there anymore.
126 + * With clk_dummy_maximize_rate_ops, this means that the the rate will
127 + * trail along the maximum as it evolves.
128 */
129 static void clk_range_test_multiple_set_range_rate_maximized(struct kunit *test)
130 {
131 @@ -653,7 +650,7 @@ static void clk_range_test_multiple_set_
132
133 rate = clk_get_rate(clk);
134 KUNIT_ASSERT_GT(test, rate, 0);
135 - KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
136 + KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
137
138 clk_put(user2);
139 clk_put(user1);
140 @@ -673,14 +670,13 @@ static struct kunit_suite clk_range_maxi
141 };
142
143 /*
144 - * Test that if:
145 - * - we have several subsequent calls to clk_set_rate_range()
146 - * - and we have a round_rate ops that always return the minimum
147 - * frequency allowed;
148 + * Test that if we have several subsequent calls to
149 + * clk_set_rate_range(), the core will reevaluate whether a new rate is
150 + * needed each and every time.
151 *
152 - * The clock will run at the maximum of all minimum boundaries
153 - * requested, even if those boundaries aren't there anymore.
154 -*/
155 + * With clk_dummy_minimize_rate_ops, this means that the the rate will
156 + * trail along the minimum as it evolves.
157 + */
158 static void clk_range_test_set_range_rate_minimized(struct kunit *test)
159 {
160 struct clk_dummy_context *ctx = test->priv;
161 @@ -720,19 +716,17 @@ static void clk_range_test_set_range_rat
162
163 rate = clk_get_rate(clk);
164 KUNIT_ASSERT_GT(test, rate, 0);
165 - KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1 + 1000);
166 + KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
167 }
168
169 /*
170 - * Test that if:
171 - * - we have several subsequent calls to clk_set_rate_range(), across
172 - * multiple users;
173 - * - and we have a round_rate ops that always return the minimum
174 - * frequency allowed;
175 + * Test that if we have several subsequent calls to
176 + * clk_set_rate_range(), across multiple users, the core will reevaluate
177 + * whether a new rate is needed each and every time.
178 *
179 - * The clock will run at the maximum of all minimum boundaries
180 - * requested, even if those boundaries aren't there anymore.
181 -*/
182 + * With clk_dummy_minimize_rate_ops, this means that the the rate will
183 + * trail along the minimum as it evolves.
184 + */
185 static void clk_range_test_multiple_set_range_rate_minimized(struct kunit *test)
186 {
187 struct clk_dummy_context *ctx = test->priv;
188 @@ -773,7 +767,7 @@ static void clk_range_test_multiple_set_
189
190 rate = clk_get_rate(clk);
191 KUNIT_ASSERT_GT(test, rate, 0);
192 - KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_2);
193 + KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
194
195 clk_put(user2);
196 clk_put(user1);