static int raspberrypi_fw_prepare(struct clk_hw *hw)
{
const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
+ struct raspberrypi_clk_variant *variant = data->variant;
struct raspberrypi_clk *rpi = data->rpi;
u32 state = RPI_FIRMWARE_STATE_ENABLE_BIT;
int ret;
ret = raspberrypi_clock_property(rpi->firmware, data,
RPI_FIRMWARE_SET_CLOCK_STATE, &state);
- if (ret)
+ if (ret) {
dev_err_ratelimited(rpi->dev,
"Failed to set clock %s state to on: %d\n",
clk_hw_get_name(hw), ret);
+ return ret;
+ }
+
+ /*
+ * For clocks marked with 'maximize', restore the rate to the
+ * maximum after enabling. This compensates for the rate being
+ * set to minimum during unprepare (see raspberrypi_fw_unprepare).
+ */
+ if (variant->maximize) {
+ unsigned long min_rate, max_rate;
+
+ clk_hw_get_rate_range(hw, &min_rate, &max_rate);
+ ret = raspberrypi_fw_set_rate(hw, max_rate, 0);
+ }
return ret;
}
{
const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
struct raspberrypi_clk *rpi = data->rpi;
+ unsigned long min_rate, max_rate;
u32 state = 0;
int ret;
+ clk_hw_get_rate_range(hw, &min_rate, &max_rate);
+
+ /*
+ * Setting the rate in unprepare is a deviation from the usual CCF
+ * behavior, where unprepare only gates the clock. However, this is
+ * needed, as RPI_FIRMWARE_SET_CLOCK_STATE doesn't actually power off
+ * the clock on current firmware versions. Setting the rate to minimum
+ * before disabling the clock is the only way to achieve meaningful
+ * power savings.
+ *
+ * This is safe because no consumer should rely on the rate of an
+ * unprepared clock. Any consumer must call clk_prepare() before use,
+ * at which point the rate is either restored to maximum (for clocks
+ * with the 'maximize' flag) or re-established by the consumer.
+ */
+ raspberrypi_fw_set_rate(hw, min_rate, 0);
+
ret = raspberrypi_clock_property(rpi->firmware, data,
RPI_FIRMWARE_SET_CLOCK_STATE, &state);
if (ret)
}
}
- if (variant->maximize)
- variant->min_rate = max_rate;
-
if (variant->min_rate) {
unsigned long rate;