clk: Introduce a clock request API
authorMaxime Ripard <maxime@cerno.tech>
Tue, 13 Apr 2021 09:00:01 +0000 (11:00 +0200)
committerDom Cobley <popcornmix@gmail.com>
Mon, 21 Mar 2022 16:04:13 +0000 (16:04 +0000)
commit91c3e3a96003fbfcfd5f59c4052f5187de82099c
tree780f712e1d12b4f8c8f8e8e6a0e84ceaeb9dbf51
parente44b7d4b91d4ef6109dc550a0f8b12c0feb5a194
clk: Introduce a clock request API

It's not unusual to find clocks being shared across multiple devices
that need to change the rate depending on what the device is doing at a
given time.

The SoC found on the RaspberryPi4 (BCM2711) is in such a situation
between its two HDMI controllers that share a clock that needs to be
raised depending on the output resolution of each controller.

The current clk_set_rate API doesn't really allow to support that case
since there's really no synchronisation between multiple users, it's
essentially a fire-and-forget solution.

clk_set_min_rate does allow for such a synchronisation, but has another
drawback: it doesn't allow to reduce the clock rate once the work is
over.

In our previous example, this means that if we were to raise the
resolution of one HDMI controller to the largest resolution and then
changing for a smaller one, we would still have the clock running at the
largest resolution rate resulting in a poor power-efficiency.

In order to address both issues, let's create an API that allows user to
create temporary requests to increase the rate to a minimum, before
going back to the initial rate once the request is done.

This introduces mainly two side-effects:

  * There's an interaction between clk_set_rate and requests. This has
    been addressed by having clk_set_rate increasing the rate if it's
    greater than what the requests asked for, and in any case changing
    the rate the clock will return to once all the requests are done.

  * Similarly, clk_round_rate has been adjusted to take the requests
    into account and return a rate that will be greater or equal to the
    requested rates.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
drivers/clk/clk.c
include/linux/clk.h