Commit 542acfec authored by Maxime Ripard's avatar Maxime Ripard Committed by Stephen Boyd

clk: bcm: rpi: Set a default minimum rate

The M2MC clock provides the state machine clock for both HDMI
controllers.

However, if no HDMI monitor is plugged in at boot, its clock rate will
be left at 0 by the firmware and will make any register access end up in
a CPU stall, even though the clock was enabled.

We had some code in the HDMI controller to deal with this before, but it
makes more sense to have it in the clock driver. Move it there.
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://lore.kernel.org/r/20220225143534.405820-10-maxime@cerno.techSigned-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 12c90f3f
...@@ -76,6 +76,7 @@ struct raspberrypi_clk_data { ...@@ -76,6 +76,7 @@ struct raspberrypi_clk_data {
struct raspberrypi_clk_variant { struct raspberrypi_clk_variant {
bool export; bool export;
char *clkdev; char *clkdev;
unsigned long min_rate;
}; };
static struct raspberrypi_clk_variant static struct raspberrypi_clk_variant
...@@ -89,6 +90,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { ...@@ -89,6 +90,18 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
}, },
[RPI_FIRMWARE_M2MC_CLK_ID] = { [RPI_FIRMWARE_M2MC_CLK_ID] = {
.export = true, .export = true,
/*
* If we boot without any cable connected to any of the
* HDMI connector, the firmware will skip the HSM
* initialization and leave it with a rate of 0,
* resulting in a bus lockup when we're accessing the
* registers even if it's enabled.
*
* Let's put a sensible default so that we don't end up
* in this situation.
*/
.min_rate = 120000000,
}, },
[RPI_FIRMWARE_V3D_CLK_ID] = { [RPI_FIRMWARE_V3D_CLK_ID] = {
.export = true, .export = true,
...@@ -267,6 +280,19 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, ...@@ -267,6 +280,19 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
} }
} }
if (variant->min_rate) {
unsigned long rate;
clk_hw_set_rate_range(&data->hw, variant->min_rate, max_rate);
rate = raspberrypi_fw_get_rate(&data->hw, 0);
if (rate < variant->min_rate) {
ret = raspberrypi_fw_set_rate(&data->hw, variant->min_rate, 0);
if (ret)
return ERR_PTR(ret);
}
}
return &data->hw; return &data->hw;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment