Skip to content

Commit e9d6cea

Browse files
mripardbebarino
authored andcommitted
clk: bcm: rpi: Run some clocks at the minimum rate allowed
The core clock and M2MC clocks are shared between some devices (Unicam controllers and the HVS, and the HDMI controllers, respectively) that will have various, varying, requirements depending on their current work load. Since those loads can require a fairly high clock rate in extreme conditions (up to ~600MHz), we can end up running those clocks at their maximum frequency even though we no longer require such a high rate. Fortunately, those devices don't require an exact rate but a minimum rate, and all the drivers are using clk_set_min_rate. Thus, we can just rely on the fact that the clk_request minimum (which is the aggregated minimum of all the clock users) is what we want at all times. Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 542acfe commit e9d6cea

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

drivers/clk/bcm/clk-raspberrypi.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct raspberrypi_clk_variant {
7777
bool export;
7878
char *clkdev;
7979
unsigned long min_rate;
80+
bool minimize;
8081
};
8182

8283
static struct raspberrypi_clk_variant
@@ -87,6 +88,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
8788
},
8889
[RPI_FIRMWARE_CORE_CLK_ID] = {
8990
.export = true,
91+
92+
/*
93+
* The clock is shared between the HVS and the CSI
94+
* controllers, on the BCM2711 and will change depending
95+
* on the pixels composited on the HVS and the capture
96+
* resolution on Unicam.
97+
*
98+
* Since the rate can get quite large, and we need to
99+
* coordinate between both driver instances, let's
100+
* always use the minimum the drivers will let us.
101+
*/
102+
.minimize = true,
90103
},
91104
[RPI_FIRMWARE_M2MC_CLK_ID] = {
92105
.export = true,
@@ -102,6 +115,16 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
102115
* in this situation.
103116
*/
104117
.min_rate = 120000000,
118+
119+
/*
120+
* The clock is shared between the two HDMI controllers
121+
* on the BCM2711 and will change depending on the
122+
* resolution output on each. Since the rate can get
123+
* quite large, and we need to coordinate between both
124+
* driver instances, let's always use the minimum the
125+
* drivers will let us.
126+
*/
127+
.minimize = true,
105128
},
106129
[RPI_FIRMWARE_V3D_CLK_ID] = {
107130
.export = true,
@@ -206,12 +229,26 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
206229
static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
207230
struct clk_rate_request *req)
208231
{
232+
struct raspberrypi_clk_data *data =
233+
container_of(hw, struct raspberrypi_clk_data, hw);
234+
struct raspberrypi_clk_variant *variant = data->variant;
235+
209236
/*
210237
* The firmware will do the rounding but that isn't part of
211238
* the interface with the firmware, so we just do our best
212239
* here.
213240
*/
241+
214242
req->rate = clamp(req->rate, req->min_rate, req->max_rate);
243+
244+
/*
245+
* We want to aggressively reduce the clock rate here, so let's
246+
* just ignore the requested rate and return the bare minimum
247+
* rate we can get away with.
248+
*/
249+
if (variant->minimize && req->min_rate > 0)
250+
req->rate = req->min_rate;
251+
215252
return 0;
216253
}
217254

0 commit comments

Comments
 (0)