Commit 054b4eae authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'sunxi-clk-for-6.15' of...

Merge tag 'sunxi-clk-for-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner

Pull Allwinner clk driver updates from Chen-Yu Tsai:

 - Extend Allwinner H616 clock driver to cover TCON clock and reset
 - Enable Allwinner H616 GPU clock reparenting during rate change
 - Add new clock driver for Allwinner's A523/T527

* tag 'sunxi-clk-for-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
  clk: sunxi-ng: add support for the A523/T527 PRCM CCU
  clk: sunxi-ng: a523: add reset lines
  clk: sunxi-ng: a523: add bus clock gates
  clk: sunxi-ng: a523: remaining mod clocks
  clk: sunxi-ng: a523: add USB mod clocks
  clk: sunxi-ng: a523: add interface mod clocks
  clk: sunxi-ng: a523: add system mod clocks
  clk: sunxi-ng: a523: add video mod clocks
  clk: sunxi-ng: a523: Add support for bus clocks
  clk: sunxi-ng: Add support for the A523/T527 CCU PLLs
  dt-bindings: clk: sunxi-ng: document two Allwinner A523 CCUs
  clk: sunxi-ng: Add support for update bit
  clk: sunxi-ng: mp: provide wrappers for setting feature flags
  clk: sunxi-ng: mp: introduce dual-divider clock
  clk: sunxi-ng: h616: Reparent GPU clock during frequency changes
  clk: sunxi-ng: h616: Add clock/reset for LCD TCON
  dt-bindings: clock: sun50i-h616-ccu: Add LCD TCON clk and reset
parents 2014c95a 8cea339c
Loading
Loading
Loading
Loading
+103 −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/allwinner,sun55i-a523-ccu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Allwinner A523 Clock Control Unit

maintainers:
  - Andre Przywara <andre.przywara@arm.com>

properties:
  "#clock-cells":
    const: 1

  "#reset-cells":
    const: 1

  compatible:
    enum:
      - allwinner,sun55i-a523-ccu
      - allwinner,sun55i-a523-r-ccu

  reg:
    maxItems: 1

  clocks:
    minItems: 4
    maxItems: 5

  clock-names:
    minItems: 4
    maxItems: 5

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

allOf:
  - if:
      properties:
        compatible:
          enum:
            - allwinner,sun55i-a523-ccu

    then:
      properties:
        clocks:
          items:
            - description: High Frequency Oscillator (usually at 24MHz)
            - description: Low Frequency Oscillator (usually at 32kHz)
            - description: Internal Oscillator
            - description: Low Frequency Oscillator fanout

        clock-names:
          items:
            - const: hosc
            - const: losc
            - const: iosc
            - const: losc-fanout

  - if:
      properties:
        compatible:
          enum:
            - allwinner,sun55i-a523-r-ccu

    then:
      properties:
        clocks:
          items:
            - description: High Frequency Oscillator (usually at 24MHz)
            - description: Low Frequency Oscillator (usually at 32kHz)
            - description: Internal Oscillator
            - description: Peripherals PLL
            - description: Audio PLL

        clock-names:
          items:
            - const: hosc
            - const: losc
            - const: iosc
            - const: pll-periph
            - const: pll-audio

additionalProperties: false

examples:
  - |
    clock-controller@2001000 {
        compatible = "allwinner,sun55i-a523-ccu";
        reg = <0x02001000 0x1000>;
        clocks = <&osc24M>, <&osc32k>, <&iosc>, <&r_ccu 1>;
        clock-names = "hosc", "losc", "iosc", "losc-fanout";
        #clock-cells = <1>;
        #reset-cells = <1>;
    };

...
+10 −0
Original line number Diff line number Diff line
@@ -52,6 +52,16 @@ config SUN50I_H6_R_CCU
	default y
	depends on ARM64 || COMPILE_TEST

config SUN55I_A523_CCU
	tristate "Support for the Allwinner A523/T527 CCU"
	default y
	depends on ARM64 || COMPILE_TEST

config SUN55I_A523_R_CCU
	tristate "Support for the Allwinner A523/T527 PRCM CCU"
	default y
	depends on ARM64 || COMPILE_TEST

config SUN4I_A10_CCU
	tristate "Support for the Allwinner A10/A20 CCU"
	default y
+4 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ obj-$(CONFIG_SUN50I_A100_R_CCU) += sun50i-a100-r-ccu.o
obj-$(CONFIG_SUN50I_H6_CCU)	+= sun50i-h6-ccu.o
obj-$(CONFIG_SUN50I_H6_R_CCU)	+= sun50i-h6-r-ccu.o
obj-$(CONFIG_SUN50I_H616_CCU)	+= sun50i-h616-ccu.o
obj-$(CONFIG_SUN55I_A523_CCU)	+= sun55i-a523-ccu.o
obj-$(CONFIG_SUN55I_A523_R_CCU)	+= sun55i-a523-r-ccu.o
obj-$(CONFIG_SUN4I_A10_CCU)	+= sun4i-a10-ccu.o
obj-$(CONFIG_SUN5I_CCU)		+= sun5i-ccu.o
obj-$(CONFIG_SUN6I_A31_CCU)	+= sun6i-a31-ccu.o
@@ -58,6 +60,8 @@ sun50i-a100-r-ccu-y += ccu-sun50i-a100-r.o
sun50i-h6-ccu-y			+= ccu-sun50i-h6.o
sun50i-h6-r-ccu-y		+= ccu-sun50i-h6-r.o
sun50i-h616-ccu-y		+= ccu-sun50i-h616.o
sun55i-a523-ccu-y		+= ccu-sun55i-a523.o
sun55i-a523-r-ccu-y		+= ccu-sun55i-a523-r.o
sun4i-a10-ccu-y			+= ccu-sun4i-a10.o
sun5i-ccu-y			+= ccu-sun5i.o
sun6i-a31-ccu-y			+= ccu-sun6i-a31.o
+59 −1
Original line number Diff line number Diff line
@@ -328,10 +328,16 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu0_clk, "gpu0", gpu0_parents, 0x670,
				       24, 1,	/* mux */
				       BIT(31),	/* gate */
				       CLK_SET_RATE_PARENT);

/*
 * This clk is needed as a temporary fall back during GPU PLL freq changes.
 * Set CLK_IS_CRITICAL flag to prevent from being disabled.
 */
#define SUN50I_H616_GPU_CLK1_REG        0x674
static SUNXI_CCU_M_WITH_GATE(gpu1_clk, "gpu1", "pll-periph0-2x", 0x674,
					0, 2,	/* M */
					BIT(31),/* gate */
					0);
					CLK_IS_CRITICAL);

static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
		      0x67c, BIT(0), 0);
@@ -645,6 +651,20 @@ static const char * const tcon_tv_parents[] = { "pll-video0",
						"pll-video0-4x",
						"pll-video1",
						"pll-video1-4x" };
static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0",
			       tcon_tv_parents, 0xb60,
			       24, 3,	/* mux */
			       BIT(31),	/* gate */
			       CLK_SET_RATE_PARENT);
static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1",
			       tcon_tv_parents, 0xb64,
			       24, 3,	/* mux */
			       BIT(31),	/* gate */
			       CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3",
		      0xb7c, BIT(0), 0);
static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb3",
		      0xb7c, BIT(1), 0);
static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0",
				  tcon_tv_parents, 0xb80,
				  0, 4,		/* M */
@@ -855,8 +875,12 @@ static struct ccu_common *sun50i_h616_ccu_clks[] = {
	&hdmi_cec_clk.common,
	&bus_hdmi_clk.common,
	&bus_tcon_top_clk.common,
	&tcon_lcd0_clk.common,
	&tcon_lcd1_clk.common,
	&tcon_tv0_clk.common,
	&tcon_tv1_clk.common,
	&bus_tcon_lcd0_clk.common,
	&bus_tcon_lcd1_clk.common,
	&bus_tcon_tv0_clk.common,
	&bus_tcon_tv1_clk.common,
	&tve0_clk.common,
@@ -989,8 +1013,12 @@ static struct clk_hw_onecell_data sun50i_h616_hw_clks = {
		[CLK_HDMI_CEC]		= &hdmi_cec_clk.common.hw,
		[CLK_BUS_HDMI]		= &bus_hdmi_clk.common.hw,
		[CLK_BUS_TCON_TOP]	= &bus_tcon_top_clk.common.hw,
		[CLK_TCON_LCD0]		= &tcon_lcd0_clk.common.hw,
		[CLK_TCON_LCD1]		= &tcon_lcd1_clk.common.hw,
		[CLK_TCON_TV0]		= &tcon_tv0_clk.common.hw,
		[CLK_TCON_TV1]		= &tcon_tv1_clk.common.hw,
		[CLK_BUS_TCON_LCD0]	= &bus_tcon_lcd0_clk.common.hw,
		[CLK_BUS_TCON_LCD1]	= &bus_tcon_lcd1_clk.common.hw,
		[CLK_BUS_TCON_TV0]	= &bus_tcon_tv0_clk.common.hw,
		[CLK_BUS_TCON_TV1]	= &bus_tcon_tv1_clk.common.hw,
		[CLK_TVE0]		= &tve0_clk.common.hw,
@@ -1062,6 +1090,8 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
	[RST_BUS_HDMI]		= { 0xb1c, BIT(16) },
	[RST_BUS_HDMI_SUB]	= { 0xb1c, BIT(17) },
	[RST_BUS_TCON_TOP]	= { 0xb5c, BIT(16) },
	[RST_BUS_TCON_LCD0]	= { 0xb7c, BIT(16) },
	[RST_BUS_TCON_LCD1]	= { 0xb7c, BIT(17) },
	[RST_BUS_TCON_TV0]	= { 0xb9c, BIT(16) },
	[RST_BUS_TCON_TV1]	= { 0xb9c, BIT(17) },
	[RST_BUS_TVE_TOP]	= { 0xbbc, BIT(16) },
@@ -1120,6 +1150,19 @@ static struct ccu_pll_nb sun50i_h616_pll_cpu_nb = {
	.lock		= BIT(28),
};

static struct ccu_mux_nb sun50i_h616_gpu_nb = {
	.common		= &gpu0_clk.common,
	.cm		= &gpu0_clk.mux,
	.delay_us	= 1, /* manual doesn't really say */
	.bypass_index	= 1, /* GPU_CLK1@400MHz */
};

static struct ccu_pll_nb sun50i_h616_pll_gpu_nb = {
	.common		= &pll_gpu_clk.common,
	.enable		= BIT(29),	/* LOCK_ENABLE */
	.lock		= BIT(28),
};

static int sun50i_h616_ccu_probe(struct platform_device *pdev)
{
	void __iomem *reg;
@@ -1170,6 +1213,14 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev)
	val |= BIT(0);
	writel(val, reg + SUN50I_H616_PLL_AUDIO_REG);

	/*
	 * Set the input-divider for the gpu1 clock to 3, to reach a safe 400 MHz.
	 */
	val = readl(reg + SUN50I_H616_GPU_CLK1_REG);
	val &= ~GENMASK(1, 0);
	val |= 2;
	writel(val, reg + SUN50I_H616_GPU_CLK1_REG);

	/*
	 * First clock parent (osc32K) is unusable for CEC. But since there
	 * is no good way to force parent switch (both run with same frequency),
@@ -1190,6 +1241,13 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev)
	/* Re-lock the CPU PLL after any rate changes */
	ccu_pll_notifier_register(&sun50i_h616_pll_cpu_nb);

	/* Reparent GPU during GPU PLL rate changes */
	ccu_mux_notifier_register(pll_gpu_clk.common.hw.clk,
				  &sun50i_h616_gpu_nb);

	/* Re-lock the GPU PLL after any rate changes */
	ccu_pll_notifier_register(&sun50i_h616_pll_gpu_nb);

	return 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -51,6 +51,6 @@

#define CLK_BUS_DRAM		56

#define CLK_NUMBER		(CLK_BUS_GPADC + 1)
#define CLK_NUMBER		(CLK_BUS_TCON_LCD1 + 1)

#endif /* _CCU_SUN50I_H616_H_ */
Loading