mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 00:41:17 +00:00
99 lines
3.2 KiB
Diff
99 lines
3.2 KiB
Diff
|
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;
|
||
|
}
|
||
|
|