cfa1349c16db2eb6167d0733bc7ac03a7f8853cf
[openwrt/staging/neocturne.git] /
1 From 3bb347f520702ab886aa3513cf7d9035b09e624e Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Mon, 17 Jan 2022 17:36:23 +0100
4 Subject: [PATCH] clk: bcm: rpi: Run some clocks at the minimum rate
5 allowed
6
7 The core clock and M2MC clocks are shared between some devices (Unicam
8 controllers and the HVS, and the HDMI controllers, respectively) that
9 will have various, varying, requirements depending on their current work
10 load.
11
12 Since those loads can require a fairly high clock rate in extreme
13 conditions (up to ~600MHz), we can end up running those clocks at their
14 maximum frequency even though we no longer require such a high rate.
15
16 Fortunately, those devices don't require an exact rate but a minimum
17 rate, and all the drivers are using clk_set_min_rate. Thus, we can just
18 rely on the fact that the clk_request minimum (which is the aggregated
19 minimum of all the clock users) is what we want at all times.
20
21 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
22 ---
23 drivers/clk/bcm/clk-raspberrypi.c | 37 +++++++++++++++++++++++++++++++
24 1 file changed, 37 insertions(+)
25
26 --- a/drivers/clk/bcm/clk-raspberrypi.c
27 +++ b/drivers/clk/bcm/clk-raspberrypi.c
28 @@ -79,6 +79,7 @@ struct raspberrypi_clk_variant {
29 bool export;
30 char *clkdev;
31 unsigned long min_rate;
32 + bool minimize;
33 };
34
35 static struct raspberrypi_clk_variant
36 @@ -89,6 +90,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NU
37 },
38 [RPI_FIRMWARE_CORE_CLK_ID] = {
39 .export = true,
40 +
41 + /*
42 + * The clock is shared between the HVS and the CSI
43 + * controllers, on the BCM2711 and will change depending
44 + * on the pixels composited on the HVS and the capture
45 + * resolution on Unicam.
46 + *
47 + * Since the rate can get quite large, and we need to
48 + * coordinate between both driver instances, let's
49 + * always use the minimum the drivers will let us.
50 + */
51 + .minimize = true,
52 },
53 [RPI_FIRMWARE_M2MC_CLK_ID] = {
54 .export = true,
55 @@ -104,6 +117,16 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NU
56 * in this situation.
57 */
58 .min_rate = 120000000,
59 +
60 + /*
61 + * The clock is shared between the two HDMI controllers
62 + * on the BCM2711 and will change depending on the
63 + * resolution output on each. Since the rate can get
64 + * quite large, and we need to coordinate between both
65 + * driver instances, let's always use the minimum the
66 + * drivers will let us.
67 + */
68 + .minimize = true,
69 },
70 [RPI_FIRMWARE_V3D_CLK_ID] = {
71 .export = true,
72 @@ -217,12 +240,26 @@ static int raspberrypi_fw_set_rate(struc
73 static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
74 struct clk_rate_request *req)
75 {
76 + struct raspberrypi_clk_data *data =
77 + container_of(hw, struct raspberrypi_clk_data, hw);
78 + struct raspberrypi_clk_variant *variant = data->variant;
79 +
80 /*
81 * The firmware will do the rounding but that isn't part of
82 * the interface with the firmware, so we just do our best
83 * here.
84 */
85 +
86 req->rate = clamp(req->rate, req->min_rate, req->max_rate);
87 +
88 + /*
89 + * We want to aggressively reduce the clock rate here, so let's
90 + * just ignore the requested rate and return the bare minimum
91 + * rate we can get away with.
92 + */
93 + if (variant->minimize && req->min_rate > 0)
94 + req->rate = req->min_rate;
95 +
96 return 0;
97 }
98