Re: [PATCH v8 05/13] clk: rp1: Add support for clocks provided by RP1

Stefan Wahren
2025-04-14T12:18:40Z

Hi Andrea,

Am 19.03.25 um 22:52 schrieb Andrea della Porta:
> RaspberryPi RP1 is an MFD providing, among other peripherals, several
> clock generators and PLLs that drives the sub-peripherals.
> Add the driver to support the clock providers.
>
> Signed-off-by: Andrea della Porta <andrea.porta@suse.com>
> ---
> MAINTAINERS | 5 +
> drivers/clk/Kconfig | 9 +
> drivers/clk/Makefile | 1 +
> drivers/clk/clk-rp1.c | 1512 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 1527 insertions(+)
> create mode 100644 drivers/clk/clk-rp1.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 896a307fa065..75263700370d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19748,6 +19748,11 @@ S: Maintained
> F: Documentation/devicetree/bindings/media/raspberrypi,rp1-cfe.yaml
> F: drivers/media/platform/raspberrypi/rp1-cfe/
>
> +RASPBERRY PI RP1 PCI DRIVER
> +M: Andrea della Porta <andrea.porta@suse.com>
> +S: Maintained
> +F: drivers/clk/clk-rp1.c
> +
> RC-CORE / LIRC FRAMEWORK
> M: Sean Young <sean@mess.org>
> L: linux-media@vger.kernel.org
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 713573b6c86c..cff90de71409 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -88,6 +88,15 @@ config COMMON_CLK_RK808
> These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
> Clkout1 is always on, Clkout2 can off by control register.
>
> +config COMMON_CLK_RP1
> + tristate "Raspberry Pi RP1-based clock support"
> + depends on MISC_RP1 || COMPILE_TEST
> + default MISC_RP1
> + help
> + Enable common clock framework support for Raspberry Pi RP1.
> + This multi-function device has 3 main PLLs and several clock
> + generators to drive the internal sub-peripherals.
> +
> config COMMON_CLK_HI655X
> tristate "Clock driver for Hi655x" if EXPERT
> depends on (MFD_HI655X_PMIC || COMPILE_TEST)
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index bf4bd45adc3a..ff3993ed7e09 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -84,6 +84,7 @@ obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o
> obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
> obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
> obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
> +obj-$(CONFIG_COMMON_CLK_RP1) += clk-rp1.o
> obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
> obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
> obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
> diff --git a/drivers/clk/clk-rp1.c b/drivers/clk/clk-rp1.c
> new file mode 100644
> index 000000000000..72c74e344c1d
> --- /dev/null
> +++ b/drivers/clk/clk-rp1.c
> @@ -0,0 +1,1512 @@
> +// SPDX-License-Identifier: GPL-2.0
...
> +
> +static int rp1_pll_divider_set_rate(struct clk_hw *hw,
> + unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct rp1_clk_desc *divider = container_of(hw, struct rp1_clk_desc, div.hw);
> + struct rp1_clockman *clockman = divider->clockman;
> + const struct rp1_pll_data *data = divider->data;
> + u32 div, sec;
> +
> + div = DIV_ROUND_UP_ULL(parent_rate, rate);
> + div = clamp(div, 8u, 19u);
> +
> + spin_lock(&clockman->regs_lock);
> + sec = clockman_read(clockman, data->ctrl_reg);
> + sec &= ~PLL_SEC_DIV_MASK;
> + sec |= FIELD_PREP(PLL_SEC_DIV_MASK, div);
> +
> + /* Must keep the divider in reset to change the value. */
> + sec |= PLL_SEC_RST;
> + clockman_write(clockman, data->ctrl_reg, sec);
> +
> + /* TODO: must sleep 10 pll vco cycles */
Is it possible to implement this with some kind of xsleep or xdelay?
> + sec &= ~PLL_SEC_RST;
> + clockman_write(clockman, data->ctrl_reg, sec);
> + spin_unlock(&clockman->regs_lock);
> +
> + return 0;
> +}
> +
>