aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.15/950-0860-clk-bcm-rpi-Run-some-clocks-at-the-minimum-rate-allo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0860-clk-bcm-rpi-Run-some-clocks-at-the-minimum-rate-allo.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.15/950-0860-clk-bcm-rpi-Run-some-clocks-at-the-minimum-rate-allo.patch98
1 files changed, 98 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0860-clk-bcm-rpi-Run-some-clocks-at-the-minimum-rate-allo.patch b/target/linux/bcm27xx/patches-5.15/950-0860-clk-bcm-rpi-Run-some-clocks-at-the-minimum-rate-allo.patch
new file mode 100644
index 0000000000..cfa1349c16
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.15/950-0860-clk-bcm-rpi-Run-some-clocks-at-the-minimum-rate-allo.patch
@@ -0,0 +1,98 @@
+From 3bb347f520702ab886aa3513cf7d9035b09e624e Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Mon, 17 Jan 2022 17:36:23 +0100
+Subject: [PATCH] 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 <maxime@cerno.tech>
+---
+ drivers/clk/bcm/clk-raspberrypi.c | 37 +++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+--- a/drivers/clk/bcm/clk-raspberrypi.c
++++ b/drivers/clk/bcm/clk-raspberrypi.c
+@@ -79,6 +79,7 @@ struct raspberrypi_clk_variant {
+ bool export;
+ char *clkdev;
+ unsigned long min_rate;
++ bool minimize;
+ };
+
+ static struct raspberrypi_clk_variant
+@@ -89,6 +90,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NU
+ },
+ [RPI_FIRMWARE_CORE_CLK_ID] = {
+ .export = true,
++
++ /*
++ * The clock is shared between the HVS and the CSI
++ * controllers, on the BCM2711 and will change depending
++ * on the pixels composited on the HVS and the capture
++ * resolution on Unicam.
++ *
++ * Since the rate can get quite large, and we need to
++ * coordinate between both driver instances, let's
++ * always use the minimum the drivers will let us.
++ */
++ .minimize = true,
+ },
+ [RPI_FIRMWARE_M2MC_CLK_ID] = {
+ .export = true,
+@@ -104,6 +117,16 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NU
+ * in this situation.
+ */
+ .min_rate = 120000000,
++
++ /*
++ * The clock is shared between the two HDMI controllers
++ * on the BCM2711 and will change depending on the
++ * resolution output on each. Since the rate can get
++ * quite large, and we need to coordinate between both
++ * driver instances, let's always use the minimum the
++ * drivers will let us.
++ */
++ .minimize = true,
+ },
+ [RPI_FIRMWARE_V3D_CLK_ID] = {
+ .export = true,
+@@ -217,12 +240,26 @@ static int raspberrypi_fw_set_rate(struc
+ static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
++ struct raspberrypi_clk_data *data =
++ container_of(hw, struct raspberrypi_clk_data, hw);
++ struct raspberrypi_clk_variant *variant = data->variant;
++
+ /*
+ * The firmware will do the rounding but that isn't part of
+ * the interface with the firmware, so we just do our best
+ * here.
+ */
++
+ req->rate = clamp(req->rate, req->min_rate, req->max_rate);
++
++ /*
++ * We want to aggressively reduce the clock rate here, so let's
++ * just ignore the requested rate and return the bare minimum
++ * rate we can get away with.
++ */
++ if (variant->minimize && req->min_rate > 0)
++ req->rate = req->min_rate;
++
+ return 0;
+ }
+