Commit 89bf9bb7 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'v5.13-rockchip-clocks' of...

Merge tag 'v5.13-rockchip-clocks' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into clk-rockchip

Pull Rockchip clk driver updates from Heiko Stuebner:

 - Support for the clock controller on the new rk3568
 - Some cleanups for rk3399 modularization

* tag 'v5.13-rockchip-clocks' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip:
  clk: rockchip: drop MODULE_ALIAS from rk3399 clock controller
  clk: rockchip: drop parenthesis from ARM || COMPILE_TEST depends
  clk: rockchip: add clock controller for rk3568
  clk: rockchip: support more core div setting
  dt-binding: clock: Document rockchip, rk3568-cru bindings
  clk: rockchip: add dt-binding header for rk3568
parents a38fd874 40f29839
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/rockchip,rk3568-cru.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: ROCKCHIP rk3568 Family Clock Control Module Binding

maintainers:
  - Elaine Zhang <zhangqing@rock-chips.com>
  - Heiko Stuebner <heiko@sntech.de>

description: |
  The RK3568 clock controller generates the clock and also implements a
  reset controller for SoC peripherals.
  (examples: provide SCLK_UART1\PCLK_UART1 and SRST_P_UART1\SRST_S_UART1 for UART module)
  Each clock is assigned an identifier and client nodes can use this identifier
  to specify the clock which they consume. All available clocks are defined as
  preprocessor macros in the dt-bindings/clock/rk3568-cru.h headers and can be
  used in device tree sources.

properties:
  compatible:
    enum:
      - rockchip,rk3568-cru
      - rockchip,rk3568-pmucru

  reg:
    maxItems: 1

  "#clock-cells":
    const: 1

  "#reset-cells":
    const: 1

required:
  - compatible
  - reg
  - "#clock-cells"
  - "#reset-cells"

additionalProperties: false

examples:
  # Clock Control Module node:
  - |
    pmucru: clock-controller@fdd00000 {
      compatible = "rockchip,rk3568-pmucru";
      reg = <0xfdd00000 0x1000>;
      #clock-cells = <1>;
      #reset-cells = <1>;
    };
  - |
    cru: clock-controller@fdd20000 {
      compatible = "rockchip,rk3568-cru";
      reg = <0xfdd20000 0x1000>;
      #clock-cells = <1>;
      #reset-cells = <1>;
    };
+18 −11
Original line number Diff line number Diff line
@@ -11,78 +11,85 @@ config COMMON_CLK_ROCKCHIP
if COMMON_CLK_ROCKCHIP
config CLK_PX30
	bool "Rockchip PX30 clock controller support"
	depends on (ARM64 || COMPILE_TEST)
	depends on ARM64 || COMPILE_TEST
	default y
	help
	  Build the driver for PX30 Clock Driver.

config CLK_RV110X
	bool "Rockchip RV110x clock controller support"
	depends on (ARM || COMPILE_TEST)
	depends on ARM || COMPILE_TEST
	default y
	help
	  Build the driver for RV110x Clock Driver.

config CLK_RK3036
	bool "Rockchip RK3036 clock controller support"
	depends on (ARM || COMPILE_TEST)
	depends on ARM || COMPILE_TEST
	default y
	help
	  Build the driver for RK3036 Clock Driver.

config CLK_RK312X
	bool "Rockchip RK312x clock controller support"
	depends on (ARM || COMPILE_TEST)
	depends on ARM || COMPILE_TEST
	default y
	help
	  Build the driver for RK312x Clock Driver.

config CLK_RK3188
	bool "Rockchip RK3188 clock controller support"
	depends on (ARM || COMPILE_TEST)
	depends on ARM || COMPILE_TEST
	default y
	help
	  Build the driver for RK3188 Clock Driver.

config CLK_RK322X
	bool "Rockchip RK322x clock controller support"
	depends on (ARM || COMPILE_TEST)
	depends on ARM || COMPILE_TEST
	default y
	help
	  Build the driver for RK322x Clock Driver.

config CLK_RK3288
	bool "Rockchip RK3288 clock controller support"
	depends on (ARM || COMPILE_TEST)
	depends on ARM || COMPILE_TEST
	default y
	help
	  Build the driver for RK3288 Clock Driver.

config CLK_RK3308
	bool "Rockchip RK3308 clock controller support"
	depends on (ARM64 || COMPILE_TEST)
	depends on ARM64 || COMPILE_TEST
	default y
	help
	  Build the driver for RK3308 Clock Driver.

config CLK_RK3328
	bool "Rockchip RK3328 clock controller support"
	depends on (ARM64 || COMPILE_TEST)
	depends on ARM64 || COMPILE_TEST
	default y
	help
	  Build the driver for RK3328 Clock Driver.

config CLK_RK3368
	bool "Rockchip RK3368 clock controller support"
	depends on (ARM64 || COMPILE_TEST)
	depends on ARM64 || COMPILE_TEST
	default y
	help
	  Build the driver for RK3368 Clock Driver.

config CLK_RK3399
	tristate "Rockchip RK3399 clock controller support"
	depends on (ARM64 || COMPILE_TEST)
	depends on ARM64 || COMPILE_TEST
	default y
	help
	  Build the driver for RK3399 Clock Driver.

config CLK_RK3568
	tristate "Rockchip RK3568 clock controller support"
	depends on ARM64 || COMPILE_TEST
	default y
	help
	  Build the driver for RK3568 Clock Driver.
endif
+1 −0
Original line number Diff line number Diff line
@@ -26,3 +26,4 @@ obj-$(CONFIG_CLK_RK3308) += clk-rk3308.o
obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
+29 −24
Original line number Diff line number Diff line
@@ -84,10 +84,10 @@ static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw,
{
	struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_hw(hw);
	const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
	u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg);
	u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg[0]);

	clksel0 >>= reg_data->div_core_shift;
	clksel0 &= reg_data->div_core_mask;
	clksel0 >>= reg_data->div_core_shift[0];
	clksel0 &= reg_data->div_core_mask[0];
	return parent_rate / (clksel0 + 1);
}

@@ -120,6 +120,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
	const struct rockchip_cpuclk_rate_table *rate;
	unsigned long alt_prate, alt_div;
	unsigned long flags;
	int i = 0;

	/* check validity of the new rate */
	rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
@@ -142,10 +143,10 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
	if (alt_prate > ndata->old_rate) {
		/* calculate dividers */
		alt_div =  DIV_ROUND_UP(alt_prate, ndata->old_rate) - 1;
		if (alt_div > reg_data->div_core_mask) {
		if (alt_div > reg_data->div_core_mask[0]) {
			pr_warn("%s: limiting alt-divider %lu to %d\n",
				__func__, alt_div, reg_data->div_core_mask);
			alt_div = reg_data->div_core_mask;
				__func__, alt_div, reg_data->div_core_mask[0]);
			alt_div = reg_data->div_core_mask[0];
		}

		/*
@@ -158,19 +159,17 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
		pr_debug("%s: setting div %lu as alt-rate %lu > old-rate %lu\n",
			 __func__, alt_div, alt_prate, ndata->old_rate);

		writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
					      reg_data->div_core_shift) |
		       HIWORD_UPDATE(reg_data->mux_core_alt,
				     reg_data->mux_core_mask,
				     reg_data->mux_core_shift),
		       cpuclk->reg_base + reg_data->core_reg);
	} else {
		for (i = 0; i < reg_data->num_cores; i++) {
			writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask[i],
					     reg_data->div_core_shift[i]),
			       cpuclk->reg_base + reg_data->core_reg[i]);
		}
	}
	/* select alternate parent */
	writel(HIWORD_UPDATE(reg_data->mux_core_alt,
			     reg_data->mux_core_mask,
			     reg_data->mux_core_shift),
		       cpuclk->reg_base + reg_data->core_reg);
	}
	       cpuclk->reg_base + reg_data->core_reg[0]);

	spin_unlock_irqrestore(cpuclk->lock, flags);
	return 0;
@@ -182,6 +181,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
	const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
	const struct rockchip_cpuclk_rate_table *rate;
	unsigned long flags;
	int i = 0;

	rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
	if (!rate) {
@@ -202,12 +202,17 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
	 * primary parent by the extra dividers that were needed for the alt.
	 */

	writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
				reg_data->div_core_shift) |
	       HIWORD_UPDATE(reg_data->mux_core_main,
	writel(HIWORD_UPDATE(reg_data->mux_core_main,
			     reg_data->mux_core_mask,
			     reg_data->mux_core_shift),
	       cpuclk->reg_base + reg_data->core_reg);
	       cpuclk->reg_base + reg_data->core_reg[0]);

	/* remove dividers */
	for (i = 0; i < reg_data->num_cores; i++) {
		writel(HIWORD_UPDATE(0, reg_data->div_core_mask[i],
				     reg_data->div_core_shift[i]),
		       cpuclk->reg_base + reg_data->core_reg[i]);
	}

	if (ndata->old_rate > ndata->new_rate)
		rockchip_cpuclk_set_dividers(cpuclk, rate);
+4 −3
Original line number Diff line number Diff line
@@ -124,9 +124,10 @@ static struct rockchip_cpuclk_rate_table px30_cpuclk_rates[] __initdata = {
};

static const struct rockchip_cpuclk_reg_data px30_cpuclk_data = {
	.core_reg = PX30_CLKSEL_CON(0),
	.div_core_shift = 0,
	.div_core_mask = 0xf,
	.core_reg[0] = PX30_CLKSEL_CON(0),
	.div_core_shift[0] = 0,
	.div_core_mask[0] = 0xf,
	.num_cores = 1,
	.mux_core_alt = 1,
	.mux_core_main = 0,
	.mux_core_shift = 7,
Loading