Merge tag 'tegra-for-4.7-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra...
authorStephen Boyd <sboyd@codeaurora.org>
Mon, 2 May 2016 23:53:02 +0000 (16:53 -0700)
committerStephen Boyd <sboyd@codeaurora.org>
Mon, 2 May 2016 23:53:02 +0000 (16:53 -0700)
Pull tegra clk driver changes from Thierry Reding:

This set of changes contains a bunch of cleanups and minor fixes along
with some new clocks, mainly on Tegra210, in preparation for supporting
DisplayPort and HDMI 2.0.

* tag 'tegra-for-4.7-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  clk: tegra: dfll: Reformat CVB frequency table
  clk: tegra: dfll: Properly clean up on failure and removal
  clk: tegra: dfll: Make code more comprehensible
  clk: tegra: dfll: Reference CVB table instead of copying data
  clk: tegra: dfll: Update kerneldoc
  clk: tegra: Fix PLL_U post divider and initial rate on Tegra30
  clk: tegra: Initialize PLL_C to sane rate on Tegra30
  clk: tegra: Fix pllre Tegra210 and add pll_re_out1
  clk: tegra: Add sor_safe clock
  clk: tegra: dpaux and dpaux1 are fixed factor clocks
  clk: tegra: Add dpaux1 clock
  clk: tegra: Use correct parent for dpaux clock
  clk: tegra: Add fixed factor peripheral clock type
  clk: tegra: Special-case mipi-cal parent on Tegra114
  clk: tegra: Remove trailing blank line
  clk: tegra: Constify peripheral clock registers
  clk: tegra: Add interface to enable hardware control of SATA/XUSB PLLs

98 files changed:
Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/artpec6.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/oxnas,stdclk.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt [new file with mode: 0644]
Documentation/driver-model/devres.txt
MAINTAINERS
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/clk-h32mx.c
drivers/clk/axis/Makefile [new file with mode: 0644]
drivers/clk/axis/clk-artpec6.c [new file with mode: 0644]
drivers/clk/bcm/clk-bcm2835.c
drivers/clk/clk-clps711x.c
drivers/clk/clk-composite.c
drivers/clk/clk-divider.c
drivers/clk/clk-fixed-factor.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-fractional-divider.c
drivers/clk/clk-gate.c
drivers/clk/clk-gpio.c
drivers/clk/clk-ls1x.c
drivers/clk/clk-mux.c
drivers/clk/clk-nspire.c
drivers/clk/clk-oxnas.c [new file with mode: 0644]
drivers/clk/clk-palmas.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-rk808.c
drivers/clk/clk-tango4.c
drivers/clk/clk-twl6040.c
drivers/clk/clk-wm831x.c
drivers/clk/clk-xgene.c
drivers/clk/clk.c
drivers/clk/clkdev.c
drivers/clk/imx/clk-gate2.c
drivers/clk/imx/clk-imx6sx.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk-vf610.c
drivers/clk/imx/clk.h
drivers/clk/mediatek/reset.c
drivers/clk/meson/meson8b-clkc.c
drivers/clk/mmp/clk-mmp2.c
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/mmp/clk-of-pxa168.c
drivers/clk/mmp/clk-of-pxa1928.c
drivers/clk/mmp/clk-of-pxa910.c
drivers/clk/mmp/clk-pxa168.c
drivers/clk/mmp/clk-pxa910.c
drivers/clk/mmp/reset.c
drivers/clk/qcom/gcc-ipq4019.c
drivers/clk/qcom/reset.c
drivers/clk/qcom/reset.h
drivers/clk/renesas/Kconfig [new file with mode: 0644]
drivers/clk/renesas/Makefile
drivers/clk/renesas/clk-mstp.c
drivers/clk/renesas/r8a7795-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/rockchip/Makefile
drivers/clk/rockchip/clk-cpu.c
drivers/clk/rockchip/clk-mmc-phase.c
drivers/clk/rockchip/clk-pll.c
drivers/clk/rockchip/clk-rk3036.c
drivers/clk/rockchip/clk-rk3188.c
drivers/clk/rockchip/clk-rk3228.c
drivers/clk/rockchip/clk-rk3288.c
drivers/clk/rockchip/clk-rk3368.c
drivers/clk/rockchip/clk-rk3399.c [new file with mode: 0644]
drivers/clk/rockchip/clk.c
drivers/clk/rockchip/clk.h
drivers/clk/rockchip/softrst.c
drivers/clk/samsung/clk-exynos3250.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/sirf/clk-atlas6.c
drivers/clk/sirf/clk-atlas7.c
drivers/clk/sirf/clk-prima2.c
drivers/clk/sunxi/clk-a10-hosc.c
drivers/clk/sunxi/clk-a10-ve.c
drivers/clk/sunxi/clk-sun9i-mmc.c
drivers/clk/sunxi/clk-usb.c
drivers/clk/tegra/clk.c
drivers/clk/ti/clk-54xx.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/clk-dra7-atl.c
drivers/clk/ti/clkt_dflt.c
drivers/clk/ti/clkt_dpll.c
drivers/clk/ti/dpll.c
drivers/clk/zte/clk-zx296702.c
include/dt-bindings/clock/axis,artpec6-clkctrl.h [new file with mode: 0644]
include/dt-bindings/clock/bcm2835.h
include/dt-bindings/clock/exynos3250.h
include/dt-bindings/clock/exynos5420.h
include/dt-bindings/clock/imx7d-clock.h
include/dt-bindings/clock/rk3399-cru.h [new file with mode: 0644]
include/dt-bindings/clock/vf610-clock.h
include/linux/clk-provider.h
include/linux/clk/renesas.h
include/linux/clk/ti.h
include/linux/clkdev.h

diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
new file mode 100644 (file)
index 0000000..8968371
--- /dev/null
@@ -0,0 +1,35 @@
+Marvell Armada AP806 System Controller
+======================================
+
+The AP806 is one of the two core HW blocks of the Marvell Armada 7K/8K
+SoCs. It contains a system controller, which provides a number
+registers giving access to numerous features: clocks, pin-muxing and
+many other SoC configuration items. This DT binding allows to describe
+this system controller.
+
+The Device Tree node representing the AP806 system controller provides
+a number of clocks:
+
+ - 0: clock of CPU cluster 0
+ - 1: clock of CPU cluster 1
+ - 2: fixed PLL at 1200 Mhz
+ - 3: MSS clock, derived from the fixed PLL
+
+Required properties:
+
+ - compatible: must be:
+     "marvell,ap806-system-controller", "syscon"
+ - reg: register area of the AP806 system controller
+ - #clock-cells: must be set to 1
+ - clock-output-names: must be defined to:
+    "ap-cpu-cluster-0", "ap-cpu-cluster-1", "ap-fixed", "ap-mss"
+
+Example:
+
+       syscon: system-controller@6f4000 {
+               compatible = "marvell,ap806-system-controller", "syscon";
+               #clock-cells = <1>;
+               clock-output-names = "ap-cpu-cluster-0", "ap-cpu-cluster-1",
+                                    "ap-fixed", "ap-mss";
+               reg = <0x6f4000 0x1000>;
+       };
diff --git a/Documentation/devicetree/bindings/clock/artpec6.txt b/Documentation/devicetree/bindings/clock/artpec6.txt
new file mode 100644 (file)
index 0000000..dff9cdf
--- /dev/null
@@ -0,0 +1,41 @@
+* Clock bindings for Axis ARTPEC-6 chip
+
+The bindings are based on the clock provider binding in
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+External clocks:
+----------------
+
+There are two external inputs to the main clock controller which should be
+provided using the common clock bindings.
+- "sys_refclk": External 50 Mhz oscillator (required)
+- "i2s_refclk": Alternate audio reference clock (optional).
+
+Main clock controller
+---------------------
+
+Required properties:
+- #clock-cells: Should be <1>
+  See dt-bindings/clock/axis,artpec6-clkctrl.h for the list of valid identifiers.
+- compatible: Should be "axis,artpec6-clkctrl"
+- reg: Must contain the base address and length of the system controller
+- clocks:  Must contain a phandle entry for each clock in clock-names
+- clock-names: Must include the external oscillator ("sys_refclk"). Optional
+  ones are the audio reference clock ("i2s_refclk") and the audio fractional
+  dividers ("frac_clk0" and "frac_clk1").
+
+Examples:
+
+ext_clk: ext_clk {
+       #clock-cells = <0>;
+       compatible = "fixed-clock";
+       clock-frequency = <50000000>;
+};
+
+clkctrl: clkctrl@f8000000 {
+       #clock-cells = <1>;
+       compatible = "axis,artpec6-clkctrl";
+       reg = <0xf8000000 0x48>;
+       clocks = <&ext_clk>;
+       clock-names = "sys_refclk";
+};
diff --git a/Documentation/devicetree/bindings/clock/oxnas,stdclk.txt b/Documentation/devicetree/bindings/clock/oxnas,stdclk.txt
new file mode 100644 (file)
index 0000000..208cca6
--- /dev/null
@@ -0,0 +1,35 @@
+Oxford Semiconductor OXNAS SoC Family Standard Clocks
+================================================
+
+Please also refer to clock-bindings.txt in this directory for common clock
+bindings usage.
+
+Required properties:
+- compatible: Should be "oxsemi,ox810se-stdclk"
+- #clock-cells: 1, see below
+
+Parent node should have the following properties :
+- compatible: Should be "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"
+
+For OX810SE, the clock indices are :
+ - 0: LEON
+ - 1: DMA_SGDMA
+ - 2: CIPHER
+ - 3: SATA
+ - 4: AUDIO
+ - 5: USBMPH
+ - 6: ETHA
+ - 7: PCIA
+ - 8: NAND
+
+example:
+
+sys: sys-ctrl@000000 {
+       compatible = "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd";
+       reg = <0x000000 0x100000>;
+
+       stdclk: stdclk {
+               compatible = "oxsemi,ox810se-stdclk";
+               #clock-cells = <1>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
new file mode 100644 (file)
index 0000000..3888dd3
--- /dev/null
@@ -0,0 +1,62 @@
+* Rockchip RK3399 Clock and Reset Unit
+
+The RK3399 clock controller generates and supplies clock to various
+controllers within the SoC and also implements a reset controller for SoC
+peripherals.
+
+Required Properties:
+
+- compatible: PMU for CRU should be "rockchip,rk3399-pmucru"
+- compatible: CRU should be "rockchip,rk3399-cru"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+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/rk3399-cru.h headers and can be
+used in device tree sources. Similar macros exist for the reset sources in
+these files.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It is expected
+that they are defined using standard clock bindings with following
+clock-output-names:
+ - "xin24m" - crystal input - required,
+ - "xin32k" - rtc clock - optional,
+ - "clkin_gmac" - external GMAC clock - optional,
+ - "clkin_i2s" - external I2S clock - optional,
+ - "pclkin_cif" - external ISP clock - optional,
+ - "clk_usbphy0_480m" - output clock of the pll in the usbphy0
+ - "clk_usbphy1_480m" - output clock of the pll in the usbphy1
+
+Example: Clock controller node:
+
+       pmucru: pmu-clock-controller@ff750000 {
+               compatible = "rockchip,rk3399-pmucru";
+               reg = <0x0 0xff750000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+       cru: clock-controller@ff760000 {
+               compatible = "rockchip,rk3399-cru";
+               reg = <0x0 0xff760000 0x0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller:
+
+       uart0: serial@ff1a0000 {
+               compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff180000 0x0 0x100>;
+               clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+               clock-names = "baudclk", "apb_pclk";
+               interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+       };
index 73b98dfbcea49a0d97b81583263a8e5944a3e7df..108d45553e1bbac2a392a74467dfbacf43c81c2e 100644 (file)
@@ -236,6 +236,7 @@ certainly invest a bit more effort into libata core layer).
 CLOCK
   devm_clk_get()
   devm_clk_put()
+  devm_clk_hw_register()
 
 DMA
   dmam_alloc_coherent()
index 03e00c7c88ebca4161bff9d4be82d59f3698f177..05aeee0aab4c26d87637659df0cd672d60ced41d 100644 (file)
@@ -973,7 +973,7 @@ S:  Maintained
 L:     linux-arm-kernel@axis.com
 F:     arch/arm/mach-artpec
 F:     arch/arm/boot/dts/artpec6*
-F:     drivers/clk/clk-artpec6.c
+F:     drivers/clk/axis
 
 ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
index 16f7d33421d8b63bad61770b638b1034c2dac92e..2dd371deb23ba66db61c239873d36f7cee9ca3f8 100644 (file)
@@ -197,10 +197,17 @@ config COMMON_CLK_PXA
        ---help---
          Support for the Marvell PXA SoC.
 
+config COMMON_CLK_OXNAS
+       bool "Clock driver for the OXNAS SoC Family"
+       select MFD_SYSCON
+       ---help---
+         Support for the OXNAS SoC Family clocks.
+
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
+source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/samsung/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
index 46869d696e4d7bba3962719fb9464684a2bb4c91..4ef71a13ab375e7e0f70a8cb482d1ba0aa47aaf0 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_ARCH_MB86S7X)            += clk-mb86s7x.o
 obj-$(CONFIG_ARCH_MOXART)              += clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)             += clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)              += clk-nspire.o
+obj-$(CONFIG_COMMON_CLK_OXNAS)         += clk-oxnas.o
 obj-$(CONFIG_COMMON_CLK_PALMAS)                += clk-palmas.o
 obj-$(CONFIG_CLK_QORIQ)                        += clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)         += clk-rk808.o
@@ -51,6 +52,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X)               += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)         += clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_PWM)           += clk-pwm.o
 obj-$(CONFIG_COMMON_CLK_AT91)          += at91/
+obj-$(CONFIG_ARCH_ARTPEC)              += axis/
 obj-y                                  += bcm/
 obj-$(CONFIG_ARCH_BERLIN)              += berlin/
 obj-$(CONFIG_ARCH_HISI)                        += hisilicon/
@@ -61,7 +63,7 @@ obj-$(CONFIG_ARCH_MEDIATEK)           += mediatek/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)                 += mmp/
 endif
-obj-$(CONFIG_PLAT_ORION)               += mvebu/
+obj-y                                  += mvebu/
 obj-$(CONFIG_ARCH_MESON)               += meson/
 obj-$(CONFIG_ARCH_MXS)                 += mxs/
 obj-$(CONFIG_MACH_PISTACHIO)           += pistachio/
index 819f5842fa660a22e1bb32c1d301795acb25cd99..8e20c8a76db7e91993bac8484b9bd2b2cb7f4732 100644 (file)
@@ -114,7 +114,7 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
        h32mxclk->regmap = regmap;
 
        clk = clk_register(NULL, &h32mxclk->hw);
-       if (!clk) {
+       if (IS_ERR(clk)) {
                kfree(h32mxclk);
                return;
        }
diff --git a/drivers/clk/axis/Makefile b/drivers/clk/axis/Makefile
new file mode 100644 (file)
index 0000000..628c9d3
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_MACH_ARTPEC6)     += clk-artpec6.o
diff --git a/drivers/clk/axis/clk-artpec6.c b/drivers/clk/axis/clk-artpec6.c
new file mode 100644 (file)
index 0000000..ffc988b
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * ARTPEC-6 clock initialization
+ *
+ * Copyright 2015-2016 Axis Comunications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/axis,artpec6-clkctrl.h>
+
+#define NUM_I2S_CLOCKS 2
+
+struct artpec6_clkctrl_drvdata {
+       struct clk *clk_table[ARTPEC6_CLK_NUMCLOCKS];
+       void __iomem *syscon_base;
+       struct clk_onecell_data clk_data;
+       spinlock_t i2scfg_lock;
+};
+
+static struct artpec6_clkctrl_drvdata *clkdata;
+
+static const char *const i2s_clk_names[NUM_I2S_CLOCKS] = {
+       "i2s0",
+       "i2s1",
+};
+
+static const int i2s_clk_indexes[NUM_I2S_CLOCKS] = {
+       ARTPEC6_CLK_I2S0_CLK,
+       ARTPEC6_CLK_I2S1_CLK,
+};
+
+static void of_artpec6_clkctrl_setup(struct device_node *np)
+{
+       int i;
+       const char *sys_refclk_name;
+       u32 pll_mode, pll_m, pll_n;
+       struct clk **clks;
+
+       /* Mandatory parent clock. */
+       i = of_property_match_string(np, "clock-names", "sys_refclk");
+       if (i < 0)
+               return;
+
+       sys_refclk_name = of_clk_get_parent_name(np, i);
+
+       clkdata = kzalloc(sizeof(*clkdata), GFP_KERNEL);
+       if (!clkdata)
+               return;
+
+       clks = clkdata->clk_table;
+
+       for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i)
+               clks[i] = ERR_PTR(-EPROBE_DEFER);
+
+       clkdata->syscon_base = of_iomap(np, 0);
+       BUG_ON(clkdata->syscon_base == NULL);
+
+       /* Read PLL1 factors configured by boot strap pins. */
+       pll_mode = (readl(clkdata->syscon_base) >> 6) & 3;
+       switch (pll_mode) {
+       case 0:         /* DDR3-2133 mode */
+               pll_m = 4;
+               pll_n = 85;
+               break;
+       case 1:         /* DDR3-1866 mode */
+               pll_m = 6;
+               pll_n = 112;
+               break;
+       case 2:         /* DDR3-1600 mode */
+               pll_m = 4;
+               pll_n = 64;
+               break;
+       case 3:         /* DDR3-1333 mode */
+               pll_m = 8;
+               pll_n = 106;
+               break;
+       }
+
+       clks[ARTPEC6_CLK_CPU] =
+           clk_register_fixed_factor(NULL, "cpu", sys_refclk_name, 0, pll_n,
+                                     pll_m);
+       clks[ARTPEC6_CLK_CPU_PERIPH] =
+           clk_register_fixed_factor(NULL, "cpu_periph", "cpu", 0, 1, 2);
+
+       /* EPROBE_DEFER on the apb_clock is not handled in amba devices. */
+       clks[ARTPEC6_CLK_UART_PCLK] =
+           clk_register_fixed_factor(NULL, "uart_pclk", "cpu", 0, 1, 8);
+       clks[ARTPEC6_CLK_UART_REFCLK] =
+           clk_register_fixed_rate(NULL, "uart_ref", sys_refclk_name, 0,
+                                   50000000);
+
+       clks[ARTPEC6_CLK_SPI_PCLK] =
+           clk_register_fixed_factor(NULL, "spi_pclk", "cpu", 0, 1, 8);
+       clks[ARTPEC6_CLK_SPI_SSPCLK] =
+           clk_register_fixed_rate(NULL, "spi_sspclk", sys_refclk_name, 0,
+                                   50000000);
+
+       clks[ARTPEC6_CLK_DBG_PCLK] =
+           clk_register_fixed_factor(NULL, "dbg_pclk", "cpu", 0, 1, 8);
+
+       clkdata->clk_data.clks = clkdata->clk_table;
+       clkdata->clk_data.clk_num = ARTPEC6_CLK_NUMCLOCKS;
+
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data);
+}
+
+CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl",
+              of_artpec6_clkctrl_setup);
+
+static int artpec6_clkctrl_probe(struct platform_device *pdev)
+{
+       int propidx;
+       struct device_node *np = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       struct clk **clks = clkdata->clk_table;
+       const char *sys_refclk_name;
+       const char *i2s_refclk_name = NULL;
+       const char *frac_clk_name[2] = { NULL, NULL };
+       const char *i2s_mux_parents[2];
+       u32 muxreg;
+       int i;
+       int err = 0;
+
+       /* Mandatory parent clock. */
+       propidx = of_property_match_string(np, "clock-names", "sys_refclk");
+       if (propidx < 0)
+               return -EINVAL;
+
+       sys_refclk_name = of_clk_get_parent_name(np, propidx);
+
+       /* Find clock names of optional parent clocks. */
+       propidx = of_property_match_string(np, "clock-names", "i2s_refclk");
+       if (propidx >= 0)
+               i2s_refclk_name = of_clk_get_parent_name(np, propidx);
+
+       propidx = of_property_match_string(np, "clock-names", "frac_clk0");
+       if (propidx >= 0)
+               frac_clk_name[0] = of_clk_get_parent_name(np, propidx);
+       propidx = of_property_match_string(np, "clock-names", "frac_clk1");
+       if (propidx >= 0)
+               frac_clk_name[1] = of_clk_get_parent_name(np, propidx);
+
+       spin_lock_init(&clkdata->i2scfg_lock);
+
+       clks[ARTPEC6_CLK_NAND_CLKA] =
+           clk_register_fixed_factor(dev, "nand_clka", "cpu", 0, 1, 8);
+       clks[ARTPEC6_CLK_NAND_CLKB] =
+           clk_register_fixed_rate(dev, "nand_clkb", sys_refclk_name, 0,
+                                   100000000);
+       clks[ARTPEC6_CLK_ETH_ACLK] =
+           clk_register_fixed_factor(dev, "eth_aclk", "cpu", 0, 1, 4);
+       clks[ARTPEC6_CLK_DMA_ACLK] =
+           clk_register_fixed_factor(dev, "dma_aclk", "cpu", 0, 1, 4);
+       clks[ARTPEC6_CLK_PTP_REF] =
+           clk_register_fixed_rate(dev, "ptp_ref", sys_refclk_name, 0,
+                                   100000000);
+       clks[ARTPEC6_CLK_SD_PCLK] =
+           clk_register_fixed_rate(dev, "sd_pclk", sys_refclk_name, 0,
+                                   100000000);
+       clks[ARTPEC6_CLK_SD_IMCLK] =
+           clk_register_fixed_rate(dev, "sd_imclk", sys_refclk_name, 0,
+                                   100000000);
+       clks[ARTPEC6_CLK_I2S_HST] =
+           clk_register_fixed_factor(dev, "i2s_hst", "cpu", 0, 1, 8);
+
+       for (i = 0; i < NUM_I2S_CLOCKS; ++i) {
+               if (i2s_refclk_name && frac_clk_name[i]) {
+                       i2s_mux_parents[0] = frac_clk_name[i];
+                       i2s_mux_parents[1] = i2s_refclk_name;
+
+                       clks[i2s_clk_indexes[i]] =
+                           clk_register_mux(dev, i2s_clk_names[i],
+                                            i2s_mux_parents, 2,
+                                            CLK_SET_RATE_NO_REPARENT |
+                                            CLK_SET_RATE_PARENT,
+                                            clkdata->syscon_base + 0x14, i, 1,
+                                            0, &clkdata->i2scfg_lock);
+               } else if (frac_clk_name[i]) {
+                       /* Lock the mux for internal clock reference. */
+                       muxreg = readl(clkdata->syscon_base + 0x14);
+                       muxreg &= ~BIT(i);
+                       writel(muxreg, clkdata->syscon_base + 0x14);
+                       clks[i2s_clk_indexes[i]] =
+                           clk_register_fixed_factor(dev, i2s_clk_names[i],
+                                                     frac_clk_name[i], 0, 1,
+                                                     1);
+               } else if (i2s_refclk_name) {
+                       /* Lock the mux for external clock reference. */
+                       muxreg = readl(clkdata->syscon_base + 0x14);
+                       muxreg |= BIT(i);
+                       writel(muxreg, clkdata->syscon_base + 0x14);
+                       clks[i2s_clk_indexes[i]] =
+                           clk_register_fixed_factor(dev, i2s_clk_names[i],
+                                                     i2s_refclk_name, 0, 1, 1);
+               }
+       }
+
+       clks[ARTPEC6_CLK_I2C] =
+           clk_register_fixed_rate(dev, "i2c", sys_refclk_name, 0, 100000000);
+
+       clks[ARTPEC6_CLK_SYS_TIMER] =
+           clk_register_fixed_rate(dev, "timer", sys_refclk_name, 0,
+                                   100000000);
+       clks[ARTPEC6_CLK_FRACDIV_IN] =
+           clk_register_fixed_rate(dev, "fracdiv_in", sys_refclk_name, 0,
+                                   600000000);
+
+       for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i) {
+               if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -EPROBE_DEFER) {
+                       dev_err(dev,
+                               "Failed to register clock at index %d err=%ld\n",
+                               i, PTR_ERR(clks[i]));
+                       err = PTR_ERR(clks[i]);
+               }
+       }
+
+       return err;
+}
+
+static const struct of_device_id artpec_clkctrl_of_match[] = {
+       { .compatible = "axis,artpec6-clkctrl" },
+       {}
+};
+
+static struct platform_driver artpec6_clkctrl_driver = {
+       .probe = artpec6_clkctrl_probe,
+       .driver = {
+                  .name = "artpec6_clkctrl",
+                  .of_match_table = artpec_clkctrl_of_match,
+       },
+};
+
+builtin_platform_driver(artpec6_clkctrl_driver);
index c74ed3fd496dba5a8d4fa867257ee5030491a3c9..7a7970865c2d856b6b57113c2bb7e8074140a5dd 100644 (file)
@@ -12,9 +12,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /**
@@ -40,6 +37,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/bcm2835.h>
+#include <linux/debugfs.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -51,6 +49,7 @@
 #define CM_GNRICCTL            0x000
 #define CM_GNRICDIV            0x004
 # define CM_DIV_FRAC_BITS      12
+# define CM_DIV_FRAC_MASK      GENMASK(CM_DIV_FRAC_BITS - 1, 0)
 
 #define CM_VPUCTL              0x008
 #define CM_VPUDIV              0x00c
 #define CM_SDCCTL              0x1a8
 #define CM_SDCDIV              0x1ac
 #define CM_ARMCTL              0x1b0
+#define CM_AVEOCTL             0x1b8
+#define CM_AVEODIV             0x1bc
 #define CM_EMMCCTL             0x1c0
 #define CM_EMMCDIV             0x1c4
 
 # define CM_GATE                       BIT(CM_GATE_BIT)
 # define CM_BUSY                       BIT(7)
 # define CM_BUSYD                      BIT(8)
+# define CM_FRAC                       BIT(9)
 # define CM_SRC_SHIFT                  0
 # define CM_SRC_BITS                   4
 # define CM_SRC_MASK                   0xf
 struct bcm2835_cprman {
        struct device *dev;
        void __iomem *regs;
-       spinlock_t regs_lock;
+       spinlock_t regs_lock; /* spinlock for all clocks */
        const char *osc_name;
 
        struct clk_onecell_data onecell;
-       struct clk *clks[BCM2835_CLOCK_COUNT];
+       struct clk *clks[];
 };
 
 static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
@@ -314,6 +316,27 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
        return readl(cprman->regs + reg);
 }
 
+static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
+                                 struct debugfs_reg32 *regs, size_t nregs,
+                                 struct dentry *dentry)
+{
+       struct dentry *regdump;
+       struct debugfs_regset32 *regset;
+
+       regset = devm_kzalloc(cprman->dev, sizeof(*regset), GFP_KERNEL);
+       if (!regset)
+               return -ENOMEM;
+
+       regset->regs = regs;
+       regset->nregs = nregs;
+       regset->base = cprman->regs + base;
+
+       regdump = debugfs_create_regset32("regdump", S_IRUGO, dentry,
+                                         regset);
+
+       return regdump ? 0 : -ENOMEM;
+}
+
 /*
  * These are fixed clocks. They're probably not all root clocks and it may
  * be possible to turn them on and off but until this is mapped out better
@@ -377,132 +400,27 @@ struct bcm2835_pll_ana_bits {
 static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
        .mask0 = 0,
        .set0 = 0,
-       .mask1 = ~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
+       .mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
        .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
-       .mask3 = ~A2W_PLL_KA_MASK,
+       .mask3 = (u32)~A2W_PLL_KA_MASK,
        .set3 = (2 << A2W_PLL_KA_SHIFT),
        .fb_prediv_mask = BIT(14),
 };
 
 static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
-       .mask0 = ~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
+       .mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
        .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
-       .mask1 = ~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
+       .mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
        .set1 = (6 << A2W_PLLH_KP_SHIFT),
        .mask3 = 0,
        .set3 = 0,
        .fb_prediv_mask = BIT(11),
 };
 
-/*
- * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
- * Port 2) transmitter clock.
- *
- * It is in the PX LDO power domain, which is on when the AUDIO domain
- * is on.
- */
-static const struct bcm2835_pll_data bcm2835_plla_data = {
-       .name = "plla",
-       .cm_ctrl_reg = CM_PLLA,
-       .a2w_ctrl_reg = A2W_PLLA_CTRL,
-       .frac_reg = A2W_PLLA_FRAC,
-       .ana_reg_base = A2W_PLLA_ANA0,
-       .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
-       .lock_mask = CM_LOCK_FLOCKA,
-
-       .ana = &bcm2835_ana_default,
-
-       .min_rate = 600000000u,
-       .max_rate = 2400000000u,
-       .max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/* PLLB is used for the ARM's clock. */
-static const struct bcm2835_pll_data bcm2835_pllb_data = {
-       .name = "pllb",
-       .cm_ctrl_reg = CM_PLLB,
-       .a2w_ctrl_reg = A2W_PLLB_CTRL,
-       .frac_reg = A2W_PLLB_FRAC,
-       .ana_reg_base = A2W_PLLB_ANA0,
-       .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
-       .lock_mask = CM_LOCK_FLOCKB,
-
-       .ana = &bcm2835_ana_default,
-
-       .min_rate = 600000000u,
-       .max_rate = 3000000000u,
-       .max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/*
- * PLLC is the core PLL, used to drive the core VPU clock.
- *
- * It is in the PX LDO power domain, which is on when the AUDIO domain
- * is on.
-*/
-static const struct bcm2835_pll_data bcm2835_pllc_data = {
-       .name = "pllc",
-       .cm_ctrl_reg = CM_PLLC,
-       .a2w_ctrl_reg = A2W_PLLC_CTRL,
-       .frac_reg = A2W_PLLC_FRAC,
-       .ana_reg_base = A2W_PLLC_ANA0,
-       .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
-       .lock_mask = CM_LOCK_FLOCKC,
-
-       .ana = &bcm2835_ana_default,
-
-       .min_rate = 600000000u,
-       .max_rate = 3000000000u,
-       .max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/*
- * PLLD is the display PLL, used to drive DSI display panels.
- *
- * It is in the PX LDO power domain, which is on when the AUDIO domain
- * is on.
- */
-static const struct bcm2835_pll_data bcm2835_plld_data = {
-       .name = "plld",
-       .cm_ctrl_reg = CM_PLLD,
-       .a2w_ctrl_reg = A2W_PLLD_CTRL,
-       .frac_reg = A2W_PLLD_FRAC,
-       .ana_reg_base = A2W_PLLD_ANA0,
-       .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
-       .lock_mask = CM_LOCK_FLOCKD,
-
-       .ana = &bcm2835_ana_default,
-
-       .min_rate = 600000000u,
-       .max_rate = 2400000000u,
-       .max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/*
- * PLLH is used to supply the pixel clock or the AUX clock for the TV
- * encoder.
- *
- * It is in the HDMI power domain.
- */
-static const struct bcm2835_pll_data bcm2835_pllh_data = {
-       "pllh",
-       .cm_ctrl_reg = CM_PLLH,
-       .a2w_ctrl_reg = A2W_PLLH_CTRL,
-       .frac_reg = A2W_PLLH_FRAC,
-       .ana_reg_base = A2W_PLLH_ANA0,
-       .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
-       .lock_mask = CM_LOCK_FLOCKH,
-
-       .ana = &bcm2835_ana_pllh,
-
-       .min_rate = 600000000u,
-       .max_rate = 3000000000u,
-       .max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
 struct bcm2835_pll_divider_data {
        const char *name;
-       const struct bcm2835_pll_data *source_pll;
+       const char *source_pll;
+
        u32 cm_reg;
        u32 a2w_reg;
 
@@ -511,124 +429,6 @@ struct bcm2835_pll_divider_data {
        u32 fixed_divider;
 };
 
-static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
-       .name = "plla_core",
-       .source_pll = &bcm2835_plla_data,
-       .cm_reg = CM_PLLA,
-       .a2w_reg = A2W_PLLA_CORE,
-       .load_mask = CM_PLLA_LOADCORE,
-       .hold_mask = CM_PLLA_HOLDCORE,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
-       .name = "plla_per",
-       .source_pll = &bcm2835_plla_data,
-       .cm_reg = CM_PLLA,
-       .a2w_reg = A2W_PLLA_PER,
-       .load_mask = CM_PLLA_LOADPER,
-       .hold_mask = CM_PLLA_HOLDPER,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
-       .name = "pllb_arm",
-       .source_pll = &bcm2835_pllb_data,
-       .cm_reg = CM_PLLB,
-       .a2w_reg = A2W_PLLB_ARM,
-       .load_mask = CM_PLLB_LOADARM,
-       .hold_mask = CM_PLLB_HOLDARM,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
-       .name = "pllc_core0",
-       .source_pll = &bcm2835_pllc_data,
-       .cm_reg = CM_PLLC,
-       .a2w_reg = A2W_PLLC_CORE0,
-       .load_mask = CM_PLLC_LOADCORE0,
-       .hold_mask = CM_PLLC_HOLDCORE0,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
-       .name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
-       .cm_reg = CM_PLLC, A2W_PLLC_CORE1,
-       .load_mask = CM_PLLC_LOADCORE1,
-       .hold_mask = CM_PLLC_HOLDCORE1,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
-       .name = "pllc_core2",
-       .source_pll = &bcm2835_pllc_data,
-       .cm_reg = CM_PLLC,
-       .a2w_reg = A2W_PLLC_CORE2,
-       .load_mask = CM_PLLC_LOADCORE2,
-       .hold_mask = CM_PLLC_HOLDCORE2,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
-       .name = "pllc_per",
-       .source_pll = &bcm2835_pllc_data,
-       .cm_reg = CM_PLLC,
-       .a2w_reg = A2W_PLLC_PER,
-       .load_mask = CM_PLLC_LOADPER,
-       .hold_mask = CM_PLLC_HOLDPER,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
-       .name = "plld_core",
-       .source_pll = &bcm2835_plld_data,
-       .cm_reg = CM_PLLD,
-       .a2w_reg = A2W_PLLD_CORE,
-       .load_mask = CM_PLLD_LOADCORE,
-       .hold_mask = CM_PLLD_HOLDCORE,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
-       .name = "plld_per",
-       .source_pll = &bcm2835_plld_data,
-       .cm_reg = CM_PLLD,
-       .a2w_reg = A2W_PLLD_PER,
-       .load_mask = CM_PLLD_LOADPER,
-       .hold_mask = CM_PLLD_HOLDPER,
-       .fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
-       .name = "pllh_rcal",
-       .source_pll = &bcm2835_pllh_data,
-       .cm_reg = CM_PLLH,
-       .a2w_reg = A2W_PLLH_RCAL,
-       .load_mask = CM_PLLH_LOADRCAL,
-       .hold_mask = 0,
-       .fixed_divider = 10,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
-       .name = "pllh_aux",
-       .source_pll = &bcm2835_pllh_data,
-       .cm_reg = CM_PLLH,
-       .a2w_reg = A2W_PLLH_AUX,
-       .load_mask = CM_PLLH_LOADAUX,
-       .hold_mask = 0,
-       .fixed_divider = 10,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
-       .name = "pllh_pix",
-       .source_pll = &bcm2835_pllh_data,
-       .cm_reg = CM_PLLH,
-       .a2w_reg = A2W_PLLH_PIX,
-       .load_mask = CM_PLLH_LOADPIX,
-       .hold_mask = 0,
-       .fixed_divider = 10,
-};
-
 struct bcm2835_clock_data {
        const char *name;
 
@@ -644,187 +444,14 @@ struct bcm2835_clock_data {
        u32 frac_bits;
 
        bool is_vpu_clock;
+       bool is_mash_clock;
 };
 
-static const char *const bcm2835_clock_per_parents[] = {
-       "gnd",
-       "xosc",
-       "testdebug0",
-       "testdebug1",
-       "plla_per",
-       "pllc_per",
-       "plld_per",
-       "pllh_aux",
-};
-
-static const char *const bcm2835_clock_vpu_parents[] = {
-       "gnd",
-       "xosc",
-       "testdebug0",
-       "testdebug1",
-       "plla_core",
-       "pllc_core0",
-       "plld_core",
-       "pllh_aux",
-       "pllc_core1",
-       "pllc_core2",
-};
-
-static const char *const bcm2835_clock_osc_parents[] = {
-       "gnd",
-       "xosc",
-       "testdebug0",
-       "testdebug1"
-};
-
-/*
- * Used for a 1Mhz clock for the system clocksource, and also used by
- * the watchdog timer and the camera pulse generator.
- */
-static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
-       .name = "timer",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
-       .parents = bcm2835_clock_osc_parents,
-       .ctl_reg = CM_TIMERCTL,
-       .div_reg = CM_TIMERDIV,
-       .int_bits = 6,
-       .frac_bits = 12,
-};
-
-/* One Time Programmable Memory clock.  Maximum 10Mhz. */
-static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
-       .name = "otp",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
-       .parents = bcm2835_clock_osc_parents,
-       .ctl_reg = CM_OTPCTL,
-       .div_reg = CM_OTPDIV,
-       .int_bits = 4,
-       .frac_bits = 0,
-};
-
-/*
- * VPU clock.  This doesn't have an enable bit, since it drives the
- * bus for everything else, and is special so it doesn't need to be
- * gated for rate changes.  It is also known as "clk_audio" in various
- * hardware documentation.
- */
-static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
-       .name = "vpu",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-       .parents = bcm2835_clock_vpu_parents,
-       .ctl_reg = CM_VPUCTL,
-       .div_reg = CM_VPUDIV,
-       .int_bits = 12,
-       .frac_bits = 8,
-       .is_vpu_clock = true,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
-       .name = "v3d",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-       .parents = bcm2835_clock_vpu_parents,
-       .ctl_reg = CM_V3DCTL,
-       .div_reg = CM_V3DDIV,
-       .int_bits = 4,
-       .frac_bits = 8,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
-       .name = "isp",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-       .parents = bcm2835_clock_vpu_parents,
-       .ctl_reg = CM_ISPCTL,
-       .div_reg = CM_ISPDIV,
-       .int_bits = 4,
-       .frac_bits = 8,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
-       .name = "h264",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-       .parents = bcm2835_clock_vpu_parents,
-       .ctl_reg = CM_H264CTL,
-       .div_reg = CM_H264DIV,
-       .int_bits = 4,
-       .frac_bits = 8,
-};
-
-/* TV encoder clock.  Only operating frequency is 108Mhz.  */
-static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
-       .name = "vec",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-       .parents = bcm2835_clock_per_parents,
-       .ctl_reg = CM_VECCTL,
-       .div_reg = CM_VECDIV,
-       .int_bits = 4,
-       .frac_bits = 0,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
-       .name = "uart",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-       .parents = bcm2835_clock_per_parents,
-       .ctl_reg = CM_UARTCTL,
-       .div_reg = CM_UARTDIV,
-       .int_bits = 10,
-       .frac_bits = 12,
-};
-
-/* HDMI state machine */
-static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
-       .name = "hsm",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-       .parents = bcm2835_clock_per_parents,
-       .ctl_reg = CM_HSMCTL,
-       .div_reg = CM_HSMDIV,
-       .int_bits = 4,
-       .frac_bits = 8,
-};
-
-/*
- * Secondary SDRAM clock.  Used for low-voltage modes when the PLL in
- * the SDRAM controller can't be used.
- */
-static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
-       .name = "sdram",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-       .parents = bcm2835_clock_vpu_parents,
-       .ctl_reg = CM_SDCCTL,
-       .div_reg = CM_SDCDIV,
-       .int_bits = 6,
-       .frac_bits = 0,
-};
-
-/* Clock for the temperature sensor.  Generally run at 2Mhz, max 5Mhz. */
-static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
-       .name = "tsens",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
-       .parents = bcm2835_clock_osc_parents,
-       .ctl_reg = CM_TSENSCTL,
-       .div_reg = CM_TSENSDIV,
-       .int_bits = 5,
-       .frac_bits = 0,
-};
-
-/* Arasan EMMC clock */
-static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
-       .name = "emmc",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-       .parents = bcm2835_clock_per_parents,
-       .ctl_reg = CM_EMMCCTL,
-       .div_reg = CM_EMMCDIV,
-       .int_bits = 4,
-       .frac_bits = 8,
-};
+struct bcm2835_gate_data {
+       const char *name;
+       const char *parent;
 
-static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
-       .name = "pwm",
-       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-       .parents = bcm2835_clock_per_parents,
-       .ctl_reg = CM_PWMCTL,
-       .div_reg = CM_PWMDIV,
-       .int_bits = 12,
-       .frac_bits = 12,
+       u32 ctl_reg;
 };
 
 struct bcm2835_pll {
@@ -910,8 +537,14 @@ static void bcm2835_pll_off(struct clk_hw *hw)
        struct bcm2835_cprman *cprman = pll->cprman;
        const struct bcm2835_pll_data *data = pll->data;
 
-       cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
-       cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
+       spin_lock(&cprman->regs_lock);
+       cprman_write(cprman, data->cm_ctrl_reg,
+                    cprman_read(cprman, data->cm_ctrl_reg) |
+                    CM_PLL_ANARST);
+       cprman_write(cprman, data->a2w_ctrl_reg,
+                    cprman_read(cprman, data->a2w_ctrl_reg) |
+                    A2W_PLL_CTRL_PWRDN);
+       spin_unlock(&cprman->regs_lock);
 }
 
 static int bcm2835_pll_on(struct clk_hw *hw)
@@ -921,6 +554,10 @@ static int bcm2835_pll_on(struct clk_hw *hw)
        const struct bcm2835_pll_data *data = pll->data;
        ktime_t timeout;
 
+       cprman_write(cprman, data->a2w_ctrl_reg,
+                    cprman_read(cprman, data->a2w_ctrl_reg) &
+                    ~A2W_PLL_CTRL_PWRDN);
+
        /* Take the PLL out of reset. */
        cprman_write(cprman, data->cm_ctrl_reg,
                     cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
@@ -1030,6 +667,36 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
        return 0;
 }
 
+static int bcm2835_pll_debug_init(struct clk_hw *hw,
+                                 struct dentry *dentry)
+{
+       struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+       struct bcm2835_cprman *cprman = pll->cprman;
+       const struct bcm2835_pll_data *data = pll->data;
+       struct debugfs_reg32 *regs;
+
+       regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
+       if (!regs)
+               return -ENOMEM;
+
+       regs[0].name = "cm_ctrl";
+       regs[0].offset = data->cm_ctrl_reg;
+       regs[1].name = "a2w_ctrl";
+       regs[1].offset = data->a2w_ctrl_reg;
+       regs[2].name = "frac";
+       regs[2].offset = data->frac_reg;
+       regs[3].name = "ana0";
+       regs[3].offset = data->ana_reg_base + 0 * 4;
+       regs[4].name = "ana1";
+       regs[4].offset = data->ana_reg_base + 1 * 4;
+       regs[5].name = "ana2";
+       regs[5].offset = data->ana_reg_base + 2 * 4;
+       regs[6].name = "ana3";
+       regs[6].offset = data->ana_reg_base + 3 * 4;
+
+       return bcm2835_debugfs_regset(cprman, 0, regs, 7, dentry);
+}
+
 static const struct clk_ops bcm2835_pll_clk_ops = {
        .is_prepared = bcm2835_pll_is_on,
        .prepare = bcm2835_pll_on,
@@ -1037,6 +704,7 @@ static const struct clk_ops bcm2835_pll_clk_ops = {
        .recalc_rate = bcm2835_pll_get_rate,
        .set_rate = bcm2835_pll_set_rate,
        .round_rate = bcm2835_pll_round_rate,
+       .debug_init = bcm2835_pll_debug_init,
 };
 
 struct bcm2835_pll_divider {
@@ -1079,10 +747,12 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw)
        struct bcm2835_cprman *cprman = divider->cprman;
        const struct bcm2835_pll_divider_data *data = divider->data;
 
+       spin_lock(&cprman->regs_lock);
        cprman_write(cprman, data->cm_reg,
                     (cprman_read(cprman, data->cm_reg) &
                      ~data->load_mask) | data->hold_mask);
        cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
+       spin_unlock(&cprman->regs_lock);
 }
 
 static int bcm2835_pll_divider_on(struct clk_hw *hw)
@@ -1091,12 +761,14 @@ static int bcm2835_pll_divider_on(struct clk_hw *hw)
        struct bcm2835_cprman *cprman = divider->cprman;
        const struct bcm2835_pll_divider_data *data = divider->data;
 
+       spin_lock(&cprman->regs_lock);
        cprman_write(cprman, data->a2w_reg,
                     cprman_read(cprman, data->a2w_reg) &
                     ~A2W_PLL_CHANNEL_DISABLE);
 
        cprman_write(cprman, data->cm_reg,
                     cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
+       spin_unlock(&cprman->regs_lock);
 
        return 0;
 }
@@ -1124,6 +796,26 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
        return 0;
 }
 
+static int bcm2835_pll_divider_debug_init(struct clk_hw *hw,
+                                         struct dentry *dentry)
+{
+       struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+       struct bcm2835_cprman *cprman = divider->cprman;
+       const struct bcm2835_pll_divider_data *data = divider->data;
+       struct debugfs_reg32 *regs;
+
+       regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
+       if (!regs)
+               return -ENOMEM;
+
+       regs[0].name = "cm";
+       regs[0].offset = data->cm_reg;
+       regs[1].name = "a2w";
+       regs[1].offset = data->a2w_reg;
+
+       return bcm2835_debugfs_regset(cprman, 0, regs, 2, dentry);
+}
+
 static const struct clk_ops bcm2835_pll_divider_clk_ops = {
        .is_prepared = bcm2835_pll_divider_is_on,
        .prepare = bcm2835_pll_divider_on,
@@ -1131,6 +823,7 @@ static const struct clk_ops bcm2835_pll_divider_clk_ops = {
        .recalc_rate = bcm2835_pll_divider_get_rate,
        .set_rate = bcm2835_pll_divider_set_rate,
        .round_rate = bcm2835_pll_divider_round_rate,
+       .debug_init = bcm2835_pll_divider_debug_init,
 };
 
 /*
@@ -1170,7 +863,7 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
                GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
        u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
        u64 rem;
-       u32 div;
+       u32 div, mindiv, maxdiv;
 
        rem = do_div(temp, rate);
        div = temp;
@@ -1180,10 +873,23 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
                div += unused_frac_mask + 1;
        div &= ~unused_frac_mask;
 
-       /* Clamp to the limits. */
-       div = max(div, unused_frac_mask + 1);
-       div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
-                                     CM_DIV_FRAC_BITS - data->frac_bits));
+       /* different clamping limits apply for a mash clock */
+       if (data->is_mash_clock) {
+               /* clamp to min divider of 2 */
+               mindiv = 2 << CM_DIV_FRAC_BITS;
+               /* clamp to the highest possible integer divider */
+               maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS;
+       } else {
+               /* clamp to min divider of 1 */
+               mindiv = 1 << CM_DIV_FRAC_BITS;
+               /* clamp to the highest possible fractional divider */
+               maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+                                CM_DIV_FRAC_BITS - data->frac_bits);
+       }
+
+       /* apply the clamping  limits */
+       div = max_t(u32, div, mindiv);
+       div = min_t(u32, div, maxdiv);
 
        return div;
 }
@@ -1277,14 +983,31 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
        struct bcm2835_cprman *cprman = clock->cprman;
        const struct bcm2835_clock_data *data = clock->data;
        u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
+       u32 ctl;
+
+       spin_lock(&cprman->regs_lock);
+
+       /*
+        * Setting up frac support
+        *
+        * In principle it is recommended to stop/start the clock first,
+        * but as we set CLK_SET_RATE_GATE during registration of the
+        * clock this requirement should be take care of by the
+        * clk-framework.
+        */
+       ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
+       ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
+       cprman_write(cprman, data->ctl_reg, ctl);
 
        cprman_write(cprman, data->div_reg, div);
 
+       spin_unlock(&cprman->regs_lock);
+
        return 0;
 }
 
 static int bcm2835_clock_determine_rate(struct clk_hw *hw,
-               struct clk_rate_request *req)
+                                       struct clk_rate_request *req)
 {
        struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
        struct clk_hw *parent, *best_parent = NULL;
@@ -1342,6 +1065,30 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
        return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
 }
 
+static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
+       {
+               .name = "ctl",
+               .offset = 0,
+       },
+       {
+               .name = "div",
+               .offset = 4,
+       },
+};
+
+static int bcm2835_clock_debug_init(struct clk_hw *hw,
+                                   struct dentry *dentry)
+{
+       struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+       struct bcm2835_cprman *cprman = clock->cprman;
+       const struct bcm2835_clock_data *data = clock->data;
+
+       return bcm2835_debugfs_regset(
+               cprman, data->ctl_reg,
+               bcm2835_debugfs_clock_reg32,
+               ARRAY_SIZE(bcm2835_debugfs_clock_reg32),
+               dentry);
+}
 
 static const struct clk_ops bcm2835_clock_clk_ops = {
        .is_prepared = bcm2835_clock_is_on,
@@ -1352,6 +1099,7 @@ static const struct clk_ops bcm2835_clock_clk_ops = {
        .determine_rate = bcm2835_clock_determine_rate,
        .set_parent = bcm2835_clock_set_parent,
        .get_parent = bcm2835_clock_get_parent,
+       .debug_init = bcm2835_clock_debug_init,
 };
 
 static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
@@ -1370,6 +1118,7 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
        .determine_rate = bcm2835_clock_determine_rate,
        .set_parent = bcm2835_clock_set_parent,
        .get_parent = bcm2835_clock_get_parent,
+       .debug_init = bcm2835_clock_debug_init,
 };
 
 static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
@@ -1418,7 +1167,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
 
        memset(&init, 0, sizeof(init));
 
-       init.parent_names = &data->source_pll->name;
+       init.parent_names = &data->source_pll;
        init.num_parents = 1;
        init.name = divider_name;
        init.ops = &bcm2835_pll_divider_clk_ops;
@@ -1501,14 +1250,559 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
        return devm_clk_register(cprman->dev, &clock->hw);
 }
 
+static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
+                                        const struct bcm2835_gate_data *data)
+{
+       return clk_register_gate(cprman->dev, data->name, data->parent,
+                                CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
+                                cprman->regs + data->ctl_reg,
+                                CM_GATE_BIT, 0, &cprman->regs_lock);
+}
+
+typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
+                                           const void *data);
+struct bcm2835_clk_desc {
+       bcm2835_clk_register clk_register;
+       const void *data;
+};
+
+/* assignment helper macros for different clock types */
+#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
+                           .data = __VA_ARGS__ }
+#define REGISTER_PLL(...)      _REGISTER(&bcm2835_register_pll,        \
+                                         &(struct bcm2835_pll_data)    \
+                                         {__VA_ARGS__})
+#define REGISTER_PLL_DIV(...)  _REGISTER(&bcm2835_register_pll_divider, \
+                                         &(struct bcm2835_pll_divider_data) \
+                                         {__VA_ARGS__})
+#define REGISTER_CLK(...)      _REGISTER(&bcm2835_register_clock,      \
+                                         &(struct bcm2835_clock_data)  \
+                                         {__VA_ARGS__})
+#define REGISTER_GATE(...)     _REGISTER(&bcm2835_register_gate,       \
+                                         &(struct bcm2835_gate_data)   \
+                                         {__VA_ARGS__})
+
+/* parent mux arrays plus helper macros */
+
+/* main oscillator parent mux */
+static const char *const bcm2835_clock_osc_parents[] = {
+       "gnd",
+       "xosc",
+       "testdebug0",
+       "testdebug1"
+};
+
+#define REGISTER_OSC_CLK(...)  REGISTER_CLK(                           \
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),       \
+       .parents = bcm2835_clock_osc_parents,                           \
+       __VA_ARGS__)
+
+/* main peripherial parent mux */
+static const char *const bcm2835_clock_per_parents[] = {
+       "gnd",
+       "xosc",
+       "testdebug0",
+       "testdebug1",
+       "plla_per",
+       "pllc_per",
+       "plld_per",
+       "pllh_aux",
+};
+
+#define REGISTER_PER_CLK(...)  REGISTER_CLK(                           \
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),       \
+       .parents = bcm2835_clock_per_parents,                           \
+       __VA_ARGS__)
+
+/* main vpu parent mux */
+static const char *const bcm2835_clock_vpu_parents[] = {
+       "gnd",
+       "xosc",
+       "testdebug0",
+       "testdebug1",
+       "plla_core",
+       "pllc_core0",
+       "plld_core",
+       "pllh_aux",
+       "pllc_core1",
+       "pllc_core2",
+};
+
+#define REGISTER_VPU_CLK(...)  REGISTER_CLK(                           \
+       .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),       \
+       .parents = bcm2835_clock_vpu_parents,                           \
+       __VA_ARGS__)
+
+/*
+ * the real definition of all the pll, pll_dividers and clocks
+ * these make use of the above REGISTER_* macros
+ */
+static const struct bcm2835_clk_desc clk_desc_array[] = {
+       /* the PLL + PLL dividers */
+
+       /*
+        * PLLA is the auxiliary PLL, used to drive the CCP2
+        * (Compact Camera Port 2) transmitter clock.
+        *
+        * It is in the PX LDO power domain, which is on when the
+        * AUDIO domain is on.
+        */
+       [BCM2835_PLLA]          = REGISTER_PLL(
+               .name = "plla",
+               .cm_ctrl_reg = CM_PLLA,
+               .a2w_ctrl_reg = A2W_PLLA_CTRL,
+               .frac_reg = A2W_PLLA_FRAC,
+               .ana_reg_base = A2W_PLLA_ANA0,
+               .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
+               .lock_mask = CM_LOCK_FLOCKA,
+
+               .ana = &bcm2835_ana_default,
+
+               .min_rate = 600000000u,
+               .max_rate = 2400000000u,
+               .max_fb_rate = BCM2835_MAX_FB_RATE),
+       [BCM2835_PLLA_CORE]     = REGISTER_PLL_DIV(
+               .name = "plla_core",
+               .source_pll = "plla",
+               .cm_reg = CM_PLLA,
+               .a2w_reg = A2W_PLLA_CORE,
+               .load_mask = CM_PLLA_LOADCORE,
+               .hold_mask = CM_PLLA_HOLDCORE,
+               .fixed_divider = 1),
+       [BCM2835_PLLA_PER]      = REGISTER_PLL_DIV(
+               .name = "plla_per",
+               .source_pll = "plla",
+               .cm_reg = CM_PLLA,
+               .a2w_reg = A2W_PLLA_PER,
+               .load_mask = CM_PLLA_LOADPER,
+               .hold_mask = CM_PLLA_HOLDPER,
+               .fixed_divider = 1),
+       [BCM2835_PLLA_DSI0]     = REGISTER_PLL_DIV(
+               .name = "plla_dsi0",
+               .source_pll = "plla",
+               .cm_reg = CM_PLLA,
+               .a2w_reg = A2W_PLLA_DSI0,
+               .load_mask = CM_PLLA_LOADDSI0,
+               .hold_mask = CM_PLLA_HOLDDSI0,
+               .fixed_divider = 1),
+       [BCM2835_PLLA_CCP2]     = REGISTER_PLL_DIV(
+               .name = "plla_ccp2",
+               .source_pll = "plla",
+               .cm_reg = CM_PLLA,
+               .a2w_reg = A2W_PLLA_CCP2,
+               .load_mask = CM_PLLA_LOADCCP2,
+               .hold_mask = CM_PLLA_HOLDCCP2,
+               .fixed_divider = 1),
+
+       /* PLLB is used for the ARM's clock. */
+       [BCM2835_PLLB]          = REGISTER_PLL(
+               .name = "pllb",
+               .cm_ctrl_reg = CM_PLLB,
+               .a2w_ctrl_reg = A2W_PLLB_CTRL,
+               .frac_reg = A2W_PLLB_FRAC,
+               .ana_reg_base = A2W_PLLB_ANA0,
+               .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+               .lock_mask = CM_LOCK_FLOCKB,
+
+               .ana = &bcm2835_ana_default,
+
+               .min_rate = 600000000u,
+               .max_rate = 3000000000u,
+               .max_fb_rate = BCM2835_MAX_FB_RATE),
+       [BCM2835_PLLB_ARM]      = REGISTER_PLL_DIV(
+               .name = "pllb_arm",
+               .source_pll = "pllb",
+               .cm_reg = CM_PLLB,
+               .a2w_reg = A2W_PLLB_ARM,
+               .load_mask = CM_PLLB_LOADARM,
+               .hold_mask = CM_PLLB_HOLDARM,
+               .fixed_divider = 1),
+
+       /*
+        * PLLC is the core PLL, used to drive the core VPU clock.
+        *
+        * It is in the PX LDO power domain, which is on when the
+        * AUDIO domain is on.
+        */
+       [BCM2835_PLLC]          = REGISTER_PLL(
+               .name = "pllc",
+               .cm_ctrl_reg = CM_PLLC,
+               .a2w_ctrl_reg = A2W_PLLC_CTRL,
+               .frac_reg = A2W_PLLC_FRAC,
+               .ana_reg_base = A2W_PLLC_ANA0,
+               .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+               .lock_mask = CM_LOCK_FLOCKC,
+
+               .ana = &bcm2835_ana_default,
+
+               .min_rate = 600000000u,
+               .max_rate = 3000000000u,
+               .max_fb_rate = BCM2835_MAX_FB_RATE),
+       [BCM2835_PLLC_CORE0]    = REGISTER_PLL_DIV(
+               .name = "pllc_core0",
+               .source_pll = "pllc",
+               .cm_reg = CM_PLLC,
+               .a2w_reg = A2W_PLLC_CORE0,
+               .load_mask = CM_PLLC_LOADCORE0,
+               .hold_mask = CM_PLLC_HOLDCORE0,
+               .fixed_divider = 1),
+       [BCM2835_PLLC_CORE1]    = REGISTER_PLL_DIV(
+               .name = "pllc_core1",
+               .source_pll = "pllc",
+               .cm_reg = CM_PLLC,
+               .a2w_reg = A2W_PLLC_CORE1,
+               .load_mask = CM_PLLC_LOADCORE1,
+               .hold_mask = CM_PLLC_HOLDCORE1,
+               .fixed_divider = 1),
+       [BCM2835_PLLC_CORE2]    = REGISTER_PLL_DIV(
+               .name = "pllc_core2",
+               .source_pll = "pllc",
+               .cm_reg = CM_PLLC,
+               .a2w_reg = A2W_PLLC_CORE2,
+               .load_mask = CM_PLLC_LOADCORE2,
+               .hold_mask = CM_PLLC_HOLDCORE2,
+               .fixed_divider = 1),
+       [BCM2835_PLLC_PER]      = REGISTER_PLL_DIV(
+               .name = "pllc_per",
+               .source_pll = "pllc",
+               .cm_reg = CM_PLLC,
+               .a2w_reg = A2W_PLLC_PER,
+               .load_mask = CM_PLLC_LOADPER,
+               .hold_mask = CM_PLLC_HOLDPER,
+               .fixed_divider = 1),
+
+       /*
+        * PLLD is the display PLL, used to drive DSI display panels.
+        *
+        * It is in the PX LDO power domain, which is on when the
+        * AUDIO domain is on.
+        */
+       [BCM2835_PLLD]          = REGISTER_PLL(
+               .name = "plld",
+               .cm_ctrl_reg = CM_PLLD,
+               .a2w_ctrl_reg = A2W_PLLD_CTRL,
+               .frac_reg = A2W_PLLD_FRAC,
+               .ana_reg_base = A2W_PLLD_ANA0,
+               .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
+               .lock_mask = CM_LOCK_FLOCKD,
+
+               .ana = &bcm2835_ana_default,
+
+               .min_rate = 600000000u,
+               .max_rate = 2400000000u,
+               .max_fb_rate = BCM2835_MAX_FB_RATE),
+       [BCM2835_PLLD_CORE]     = REGISTER_PLL_DIV(
+               .name = "plld_core",
+               .source_pll = "plld",
+               .cm_reg = CM_PLLD,
+               .a2w_reg = A2W_PLLD_CORE,
+               .load_mask = CM_PLLD_LOADCORE,
+               .hold_mask = CM_PLLD_HOLDCORE,
+               .fixed_divider = 1),
+       [BCM2835_PLLD_PER]      = REGISTER_PLL_DIV(
+               .name = "plld_per",
+               .source_pll = "plld",
+               .cm_reg = CM_PLLD,
+               .a2w_reg = A2W_PLLD_PER,
+               .load_mask = CM_PLLD_LOADPER,
+               .hold_mask = CM_PLLD_HOLDPER,
+               .fixed_divider = 1),
+       [BCM2835_PLLD_DSI0]     = REGISTER_PLL_DIV(
+               .name = "plld_dsi0",
+               .source_pll = "plld",
+               .cm_reg = CM_PLLD,
+               .a2w_reg = A2W_PLLD_DSI0,
+               .load_mask = CM_PLLD_LOADDSI0,
+               .hold_mask = CM_PLLD_HOLDDSI0,
+               .fixed_divider = 1),
+       [BCM2835_PLLD_DSI1]     = REGISTER_PLL_DIV(
+               .name = "plld_dsi1",
+               .source_pll = "plld",
+               .cm_reg = CM_PLLD,
+               .a2w_reg = A2W_PLLD_DSI1,
+               .load_mask = CM_PLLD_LOADDSI1,
+               .hold_mask = CM_PLLD_HOLDDSI1,
+               .fixed_divider = 1),
+
+       /*
+        * PLLH is used to supply the pixel clock or the AUX clock for the
+        * TV encoder.
+        *
+        * It is in the HDMI power domain.
+        */
+       [BCM2835_PLLH]          = REGISTER_PLL(
+               "pllh",
+               .cm_ctrl_reg = CM_PLLH,
+               .a2w_ctrl_reg = A2W_PLLH_CTRL,
+               .frac_reg = A2W_PLLH_FRAC,
+               .ana_reg_base = A2W_PLLH_ANA0,
+               .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+               .lock_mask = CM_LOCK_FLOCKH,
+
+               .ana = &bcm2835_ana_pllh,
+
+               .min_rate = 600000000u,
+               .max_rate = 3000000000u,
+               .max_fb_rate = BCM2835_MAX_FB_RATE),
+       [BCM2835_PLLH_RCAL]     = REGISTER_PLL_DIV(
+               .name = "pllh_rcal",
+               .source_pll = "pllh",
+               .cm_reg = CM_PLLH,
+               .a2w_reg = A2W_PLLH_RCAL,
+               .load_mask = CM_PLLH_LOADRCAL,
+               .hold_mask = 0,
+               .fixed_divider = 10),
+       [BCM2835_PLLH_AUX]      = REGISTER_PLL_DIV(
+               .name = "pllh_aux",
+               .source_pll = "pllh",
+               .cm_reg = CM_PLLH,
+               .a2w_reg = A2W_PLLH_AUX,
+               .load_mask = CM_PLLH_LOADAUX,
+               .hold_mask = 0,
+               .fixed_divider = 10),
+       [BCM2835_PLLH_PIX]      = REGISTER_PLL_DIV(
+               .name = "pllh_pix",
+               .source_pll = "pllh",
+               .cm_reg = CM_PLLH,
+               .a2w_reg = A2W_PLLH_PIX,
+               .load_mask = CM_PLLH_LOADPIX,
+               .hold_mask = 0,
+               .fixed_divider = 10),
+
+       /* the clocks */
+
+       /* clocks with oscillator parent mux */
+
+       /* One Time Programmable Memory clock.  Maximum 10Mhz. */
+       [BCM2835_CLOCK_OTP]     = REGISTER_OSC_CLK(
+               .name = "otp",
+               .ctl_reg = CM_OTPCTL,
+               .div_reg = CM_OTPDIV,
+               .int_bits = 4,
+               .frac_bits = 0),
+       /*
+        * Used for a 1Mhz clock for the system clocksource, and also used
+        * bythe watchdog timer and the camera pulse generator.
+        */
+       [BCM2835_CLOCK_TIMER]   = REGISTER_OSC_CLK(
+               .name = "timer",
+               .ctl_reg = CM_TIMERCTL,
+               .div_reg = CM_TIMERDIV,
+               .int_bits = 6,
+               .frac_bits = 12),
+       /*
+        * Clock for the temperature sensor.
+        * Generally run at 2Mhz, max 5Mhz.
+        */
+       [BCM2835_CLOCK_TSENS]   = REGISTER_OSC_CLK(
+               .name = "tsens",
+               .ctl_reg = CM_TSENSCTL,
+               .div_reg = CM_TSENSDIV,
+               .int_bits = 5,
+               .frac_bits = 0),
+       [BCM2835_CLOCK_TEC]     = REGISTER_OSC_CLK(
+               .name = "tec",
+               .ctl_reg = CM_TECCTL,
+               .div_reg = CM_TECDIV,
+               .int_bits = 6,
+               .frac_bits = 0),
+
+       /* clocks with vpu parent mux */
+       [BCM2835_CLOCK_H264]    = REGISTER_VPU_CLK(
+               .name = "h264",
+               .ctl_reg = CM_H264CTL,
+               .div_reg = CM_H264DIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       [BCM2835_CLOCK_ISP]     = REGISTER_VPU_CLK(
+               .name = "isp",
+               .ctl_reg = CM_ISPCTL,
+               .div_reg = CM_ISPDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+
+       /*
+        * Secondary SDRAM clock.  Used for low-voltage modes when the PLL
+        * in the SDRAM controller can't be used.
+        */
+       [BCM2835_CLOCK_SDRAM]   = REGISTER_VPU_CLK(
+               .name = "sdram",
+               .ctl_reg = CM_SDCCTL,
+               .div_reg = CM_SDCDIV,
+               .int_bits = 6,
+               .frac_bits = 0),
+       [BCM2835_CLOCK_V3D]     = REGISTER_VPU_CLK(
+               .name = "v3d",
+               .ctl_reg = CM_V3DCTL,
+               .div_reg = CM_V3DDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       /*
+        * VPU clock.  This doesn't have an enable bit, since it drives
+        * the bus for everything else, and is special so it doesn't need
+        * to be gated for rate changes.  It is also known as "clk_audio"
+        * in various hardware documentation.
+        */
+       [BCM2835_CLOCK_VPU]     = REGISTER_VPU_CLK(
+               .name = "vpu",
+               .ctl_reg = CM_VPUCTL,
+               .div_reg = CM_VPUDIV,
+               .int_bits = 12,
+               .frac_bits = 8,
+               .is_vpu_clock = true),
+
+       /* clocks with per parent mux */
+       [BCM2835_CLOCK_AVEO]    = REGISTER_PER_CLK(
+               .name = "aveo",
+               .ctl_reg = CM_AVEOCTL,
+               .div_reg = CM_AVEODIV,
+               .int_bits = 4,
+               .frac_bits = 0),
+       [BCM2835_CLOCK_CAM0]    = REGISTER_PER_CLK(
+               .name = "cam0",
+               .ctl_reg = CM_CAM0CTL,
+               .div_reg = CM_CAM0DIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       [BCM2835_CLOCK_CAM1]    = REGISTER_PER_CLK(
+               .name = "cam1",
+               .ctl_reg = CM_CAM1CTL,
+               .div_reg = CM_CAM1DIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       [BCM2835_CLOCK_DFT]     = REGISTER_PER_CLK(
+               .name = "dft",
+               .ctl_reg = CM_DFTCTL,
+               .div_reg = CM_DFTDIV,
+               .int_bits = 5,
+               .frac_bits = 0),
+       [BCM2835_CLOCK_DPI]     = REGISTER_PER_CLK(
+               .name = "dpi",
+               .ctl_reg = CM_DPICTL,
+               .div_reg = CM_DPIDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+
+       /* Arasan EMMC clock */
+       [BCM2835_CLOCK_EMMC]    = REGISTER_PER_CLK(
+               .name = "emmc",
+               .ctl_reg = CM_EMMCCTL,
+               .div_reg = CM_EMMCDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+
+       /* General purpose (GPIO) clocks */
+       [BCM2835_CLOCK_GP0]     = REGISTER_PER_CLK(
+               .name = "gp0",
+               .ctl_reg = CM_GP0CTL,
+               .div_reg = CM_GP0DIV,
+               .int_bits = 12,
+               .frac_bits = 12,
+               .is_mash_clock = true),
+       [BCM2835_CLOCK_GP1]     = REGISTER_PER_CLK(
+               .name = "gp1",
+               .ctl_reg = CM_GP1CTL,
+               .div_reg = CM_GP1DIV,
+               .int_bits = 12,
+               .frac_bits = 12,
+               .is_mash_clock = true),
+       [BCM2835_CLOCK_GP2]     = REGISTER_PER_CLK(
+               .name = "gp2",
+               .ctl_reg = CM_GP2CTL,
+               .div_reg = CM_GP2DIV,
+               .int_bits = 12,
+               .frac_bits = 12),
+
+       /* HDMI state machine */
+       [BCM2835_CLOCK_HSM]     = REGISTER_PER_CLK(
+               .name = "hsm",
+               .ctl_reg = CM_HSMCTL,
+               .div_reg = CM_HSMDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       [BCM2835_CLOCK_PCM]     = REGISTER_PER_CLK(
+               .name = "pcm",
+               .ctl_reg = CM_PCMCTL,
+               .div_reg = CM_PCMDIV,
+               .int_bits = 12,
+               .frac_bits = 12,
+               .is_mash_clock = true),
+       [BCM2835_CLOCK_PWM]     = REGISTER_PER_CLK(
+               .name = "pwm",
+               .ctl_reg = CM_PWMCTL,
+               .div_reg = CM_PWMDIV,
+               .int_bits = 12,
+               .frac_bits = 12,
+               .is_mash_clock = true),
+       [BCM2835_CLOCK_SLIM]    = REGISTER_PER_CLK(
+               .name = "slim",
+               .ctl_reg = CM_SLIMCTL,
+               .div_reg = CM_SLIMDIV,
+               .int_bits = 12,
+               .frac_bits = 12,
+               .is_mash_clock = true),
+       [BCM2835_CLOCK_SMI]     = REGISTER_PER_CLK(
+               .name = "smi",
+               .ctl_reg = CM_SMICTL,
+               .div_reg = CM_SMIDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       [BCM2835_CLOCK_UART]    = REGISTER_PER_CLK(
+               .name = "uart",
+               .ctl_reg = CM_UARTCTL,
+               .div_reg = CM_UARTDIV,
+               .int_bits = 10,
+               .frac_bits = 12),
+
+       /* TV encoder clock.  Only operating frequency is 108Mhz.  */
+       [BCM2835_CLOCK_VEC]     = REGISTER_PER_CLK(
+               .name = "vec",
+               .ctl_reg = CM_VECCTL,
+               .div_reg = CM_VECDIV,
+               .int_bits = 4,
+               .frac_bits = 0),
+
+       /* dsi clocks */
+       [BCM2835_CLOCK_DSI0E]   = REGISTER_PER_CLK(
+               .name = "dsi0e",
+               .ctl_reg = CM_DSI0ECTL,
+               .div_reg = CM_DSI0EDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+       [BCM2835_CLOCK_DSI1E]   = REGISTER_PER_CLK(
+               .name = "dsi1e",
+               .ctl_reg = CM_DSI1ECTL,
+               .div_reg = CM_DSI1EDIV,
+               .int_bits = 4,
+               .frac_bits = 8),
+
+       /* the gates */
+
+       /*
+        * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+        * you have the debug bit set in the power manager, which we
+        * don't bother exposing) are individual gates off of the
+        * non-stop vpu clock.
+        */
+       [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
+               .name = "peri_image",
+               .parent = "vpu",
+               .ctl_reg = CM_PERIICTL),
+};
+
 static int bcm2835_clk_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct clk **clks;
        struct bcm2835_cprman *cprman;
        struct resource *res;
+       const struct bcm2835_clk_desc *desc;
+       const size_t asize = ARRAY_SIZE(clk_desc_array);
+       size_t i;
 
-       cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL);
+       cprman = devm_kzalloc(dev,
+                             sizeof(*cprman) + asize * sizeof(*clks),
+                             GFP_KERNEL);
        if (!cprman)
                return -ENOMEM;
 
@@ -1525,80 +1819,15 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, cprman);
 
-       cprman->onecell.clk_num = BCM2835_CLOCK_COUNT;
+       cprman->onecell.clk_num = asize;
        cprman->onecell.clks = cprman->clks;
        clks = cprman->clks;
 
-       clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data);
-       clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data);
-       clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data);
-       clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data);
-       clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data);
-
-       clks[BCM2835_PLLA_CORE] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
-       clks[BCM2835_PLLA_PER] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
-       clks[BCM2835_PLLC_CORE0] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
-       clks[BCM2835_PLLC_CORE1] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
-       clks[BCM2835_PLLC_CORE2] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
-       clks[BCM2835_PLLC_PER] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
-       clks[BCM2835_PLLD_CORE] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
-       clks[BCM2835_PLLD_PER] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
-       clks[BCM2835_PLLH_RCAL] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
-       clks[BCM2835_PLLH_AUX] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
-       clks[BCM2835_PLLH_PIX] =
-               bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
-
-       clks[BCM2835_CLOCK_TIMER] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
-       clks[BCM2835_CLOCK_OTP] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
-       clks[BCM2835_CLOCK_TSENS] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
-       clks[BCM2835_CLOCK_VPU] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
-       clks[BCM2835_CLOCK_V3D] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
-       clks[BCM2835_CLOCK_ISP] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
-       clks[BCM2835_CLOCK_H264] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
-       clks[BCM2835_CLOCK_V3D] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
-       clks[BCM2835_CLOCK_SDRAM] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
-       clks[BCM2835_CLOCK_UART] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
-       clks[BCM2835_CLOCK_VEC] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
-       clks[BCM2835_CLOCK_HSM] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
-       clks[BCM2835_CLOCK_EMMC] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
-
-       /*
-        * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
-        * you have the debug bit set in the power manager, which we
-        * don't bother exposing) are individual gates off of the
-        * non-stop vpu clock.
-        */
-       clks[BCM2835_CLOCK_PERI_IMAGE] =
-               clk_register_gate(dev, "peri_image", "vpu",
-                                 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
-                                 cprman->regs + CM_PERIICTL, CM_GATE_BIT,
-                                 0, &cprman->regs_lock);
-
-       clks[BCM2835_CLOCK_PWM] =
-               bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data);
+       for (i = 0; i < asize; i++) {
+               desc = &clk_desc_array[i];
+               if (desc->clk_register && desc->data)
+                       clks[i] = desc->clk_register(cprman, desc->data);
+       }
 
        return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
                                   &cprman->onecell);
index ff4ef4f1df622a5529402acf3127ada88941491c..1f60b02416a757d49c59c465a377545c1094d47f 100644 (file)
@@ -107,16 +107,15 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
        writel(tmp, base + CLPS711X_SYSCON1);
 
        clps711x_clk->clks[CLPS711X_CLK_DUMMY] =
-               clk_register_fixed_rate(NULL, "dummy", NULL, CLK_IS_ROOT, 0);
+               clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
        clps711x_clk->clks[CLPS711X_CLK_CPU] =
-               clk_register_fixed_rate(NULL, "cpu", NULL, CLK_IS_ROOT, f_cpu);
+               clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
        clps711x_clk->clks[CLPS711X_CLK_BUS] =
-               clk_register_fixed_rate(NULL, "bus", NULL, CLK_IS_ROOT, f_bus);
+               clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
        clps711x_clk->clks[CLPS711X_CLK_PLL] =
-               clk_register_fixed_rate(NULL, "pll", NULL, CLK_IS_ROOT, f_pll);
+               clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
        clps711x_clk->clks[CLPS711X_CLK_TIMERREF] =
-               clk_register_fixed_rate(NULL, "timer_ref", NULL, CLK_IS_ROOT,
-                                       f_tim);
+               clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
        clps711x_clk->clks[CLPS711X_CLK_TIMER1] =
                clk_register_divider_table(NULL, "timer1", "timer_ref", 0,
                                           base + CLPS711X_SYSCON1, 5, 1, 0,
@@ -126,10 +125,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
                                           base + CLPS711X_SYSCON1, 7, 1, 0,
                                           timer_div_table, &clps711x_clk->lock);
        clps711x_clk->clks[CLPS711X_CLK_PWM] =
-               clk_register_fixed_rate(NULL, "pwm", NULL, CLK_IS_ROOT, f_pwm);
+               clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
        clps711x_clk->clks[CLPS711X_CLK_SPIREF] =
-               clk_register_fixed_rate(NULL, "spi_ref", NULL, CLK_IS_ROOT,
-                                       f_spi);
+               clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
        clps711x_clk->clks[CLPS711X_CLK_SPI] =
                clk_register_divider_table(NULL, "spi", "spi_ref", 0,
                                           base + CLPS711X_SYSCON1, 16, 2, 0,
@@ -137,8 +135,7 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
        clps711x_clk->clks[CLPS711X_CLK_UART] =
                clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
        clps711x_clk->clks[CLPS711X_CLK_TICK] =
-               clk_register_fixed_rate(NULL, "tick", NULL, CLK_IS_ROOT, 64);
-
+               clk_register_fixed_rate(NULL, "tick", NULL, 0, 64);
        for (i = 0; i < CLPS711X_CLK_MAX; i++)
                if (IS_ERR(clps711x_clk->clks[i]))
                        pr_err("clk %i: register failed with %ld\n",
index 1f903e1f86a281385a817d0a450404240ac40109..00269de2f390deef253efee479b4b2cff70446d5 100644 (file)
@@ -151,6 +151,33 @@ static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
        return rate_ops->set_rate(rate_hw, rate, parent_rate);
 }
 
+static int clk_composite_set_rate_and_parent(struct clk_hw *hw,
+                                            unsigned long rate,
+                                            unsigned long parent_rate,
+                                            u8 index)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *rate_ops = composite->rate_ops;
+       const struct clk_ops *mux_ops = composite->mux_ops;
+       struct clk_hw *rate_hw = composite->rate_hw;
+       struct clk_hw *mux_hw = composite->mux_hw;
+       unsigned long temp_rate;
+
+       __clk_hw_set_clk(rate_hw, hw);
+       __clk_hw_set_clk(mux_hw, hw);
+
+       temp_rate = rate_ops->recalc_rate(rate_hw, parent_rate);
+       if (temp_rate > rate) {
+               rate_ops->set_rate(rate_hw, rate, parent_rate);
+               mux_ops->set_parent(mux_hw, index);
+       } else {
+               mux_ops->set_parent(mux_hw, index);
+               rate_ops->set_rate(rate_hw, rate, parent_rate);
+       }
+
+       return 0;
+}
+
 static int clk_composite_is_enabled(struct clk_hw *hw)
 {
        struct clk_composite *composite = to_clk_composite(hw);
@@ -184,17 +211,18 @@ static void clk_composite_disable(struct clk_hw *hw)
        gate_ops->disable(gate_hw);
 }
 
-struct clk *clk_register_composite(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
                        const char * const *parent_names, int num_parents,
                        struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
                        struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
                        struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
                        unsigned long flags)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
        struct clk_composite *composite;
        struct clk_ops *clk_composite_ops;
+       int ret;
 
        composite = kzalloc(sizeof(*composite), GFP_KERNEL);
        if (!composite)
@@ -204,12 +232,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
        init.flags = flags | CLK_IS_BASIC;
        init.parent_names = parent_names;
        init.num_parents = num_parents;
+       hw = &composite->hw;
 
        clk_composite_ops = &composite->ops;
 
        if (mux_hw && mux_ops) {
                if (!mux_ops->get_parent) {
-                       clk = ERR_PTR(-EINVAL);
+                       hw = ERR_PTR(-EINVAL);
                        goto err;
                }
 
@@ -224,7 +253,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 
        if (rate_hw && rate_ops) {
                if (!rate_ops->recalc_rate) {
-                       clk = ERR_PTR(-EINVAL);
+                       hw = ERR_PTR(-EINVAL);
                        goto err;
                }
                clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
@@ -250,10 +279,16 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
                composite->rate_ops = rate_ops;
        }
 
+       if (mux_hw && mux_ops && rate_hw && rate_ops) {
+               if (mux_ops->set_parent && rate_ops->set_rate)
+                       clk_composite_ops->set_rate_and_parent =
+                       clk_composite_set_rate_and_parent;
+       }
+
        if (gate_hw && gate_ops) {
                if (!gate_ops->is_enabled || !gate_ops->enable ||
                    !gate_ops->disable) {
-                       clk = ERR_PTR(-EINVAL);
+                       hw = ERR_PTR(-EINVAL);
                        goto err;
                }
 
@@ -267,22 +302,56 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
        init.ops = clk_composite_ops;
        composite->hw.init = &init;
 
-       clk = clk_register(dev, &composite->hw);
-       if (IS_ERR(clk))
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
+               hw = ERR_PTR(ret);
                goto err;
+       }
 
        if (composite->mux_hw)
-               composite->mux_hw->clk = clk;
+               composite->mux_hw->clk = hw->clk;
 
        if (composite->rate_hw)
-               composite->rate_hw->clk = clk;
+               composite->rate_hw->clk = hw->clk;
 
        if (composite->gate_hw)
-               composite->gate_hw->clk = clk;
+               composite->gate_hw->clk = hw->clk;
 
-       return clk;
+       return hw;
 
 err:
        kfree(composite);
-       return clk;
+       return hw;
+}
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+                       const char * const *parent_names, int num_parents,
+                       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+                       struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+                       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+                       unsigned long flags)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
+                       mux_hw, mux_ops, rate_hw, rate_ops, gate_hw, gate_ops,
+                       flags);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
+}
+
+void clk_unregister_composite(struct clk *clk)
+{
+       struct clk_composite *composite;
+       struct clk_hw *hw;
+
+       hw = __clk_get_hw(clk);
+       if (!hw)
+               return;
+
+       composite = to_clk_composite(hw);
+
+       clk_unregister(clk);
+       kfree(composite);
 }
index 00e035b51c695be31a215319fd3af62fcd72112d..a0f55bc1ad3d277f687c6ba42cd15dbb6928c5e1 100644 (file)
@@ -426,15 +426,16 @@ const struct clk_ops clk_divider_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
 
-static struct clk *_register_divider(struct device *dev, const char *name,
+static struct clk_hw *_register_divider(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, const struct clk_div_table *table,
                spinlock_t *lock)
 {
        struct clk_divider *div;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
                if (width + shift > 16) {
@@ -467,12 +468,14 @@ static struct clk *_register_divider(struct device *dev, const char *name,
        div->table = table;
 
        /* register the clock */
-       clk = clk_register(dev, &div->hw);
-
-       if (IS_ERR(clk))
+       hw = &div->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(div);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 /**
@@ -492,11 +495,38 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, spinlock_t *lock)
 {
-       return _register_divider(dev, name, parent_name, flags, reg, shift,
+       struct clk_hw *hw;
+
+       hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
                        width, clk_divider_flags, NULL, lock);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_divider);
 
+/**
+ * clk_hw_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, spinlock_t *lock)
+{
+       return _register_divider(dev, name, parent_name, flags, reg, shift,
+                       width, clk_divider_flags, NULL, lock);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_divider);
+
 /**
  * clk_register_divider_table - register a table based divider clock with
  * the clock framework
@@ -517,11 +547,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
                u8 clk_divider_flags, const struct clk_div_table *table,
                spinlock_t *lock)
 {
-       return _register_divider(dev, name, parent_name, flags, reg, shift,
+       struct clk_hw *hw;
+
+       hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
                        width, clk_divider_flags, table, lock);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
 
+/**
+ * clk_hw_register_divider_table - register a table based divider clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+struct clk_hw *clk_hw_register_divider_table(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, const struct clk_div_table *table,
+               spinlock_t *lock)
+{
+       return _register_divider(dev, name, parent_name, flags, reg, shift,
+                       width, clk_divider_flags, table, lock);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
+
 void clk_unregister_divider(struct clk *clk)
 {
        struct clk_divider *div;
@@ -537,3 +597,18 @@ void clk_unregister_divider(struct clk *clk)
        kfree(div);
 }
 EXPORT_SYMBOL_GPL(clk_unregister_divider);
+
+/**
+ * clk_hw_unregister_divider - unregister a clk divider
+ * @hw: hardware-specific clock data to unregister
+ */
+void clk_hw_unregister_divider(struct clk_hw *hw)
+{
+       struct clk_divider *div;
+
+       div = to_clk_divider(hw);
+
+       clk_hw_unregister(hw);
+       kfree(div);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);
index 053448e2453d7b2c44726440853495541138c714..75cd6c792cb8cd10b57c55f29e4eadbaec4138b6 100644 (file)
@@ -68,13 +68,14 @@ const struct clk_ops clk_fixed_factor_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
 
-struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
+struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
                unsigned int mult, unsigned int div)
 {
        struct clk_fixed_factor *fix;
        struct clk_init_data init;
-       struct clk *clk;
+       struct clk_hw *hw;
+       int ret;
 
        fix = kmalloc(sizeof(*fix), GFP_KERNEL);
        if (!fix)
@@ -91,12 +92,28 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
        init.parent_names = &parent_name;
        init.num_parents = 1;
 
-       clk = clk_register(dev, &fix->hw);
-
-       if (IS_ERR(clk))
+       hw = &fix->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(fix);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
+
+struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned int mult, unsigned int div)
+{
+       struct clk_hw *hw;
 
-       return clk;
+       hw = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
+                                         div);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
 
@@ -113,6 +130,17 @@ void clk_unregister_fixed_factor(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
 
+void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
+{
+       struct clk_fixed_factor *fix;
+
+       fix = to_clk_fixed_factor(hw);
+
+       clk_hw_unregister(hw);
+       kfree(fix);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
+
 #ifdef CONFIG_OF
 /**
  * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
index cd9dc925b3f85901822cdaf1c015eda743ffc040..8e4453eb54e8266479d6f6256e02a9b505a90e8a 100644 (file)
@@ -45,8 +45,8 @@ const struct clk_ops clk_fixed_rate_ops = {
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
 
 /**
- * clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the
- *                                        clock framework
+ * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
+ * the clock framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of clock's parent
@@ -54,13 +54,14 @@ EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
  * @fixed_rate: non-adjustable clock rate
  * @fixed_accuracy: non-adjustable clock rate
  */
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
+struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
                const char *name, const char *parent_name, unsigned long flags,
                unsigned long fixed_rate, unsigned long fixed_accuracy)
 {
        struct clk_fixed_rate *fixed;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        /* allocate fixed-rate clock */
        fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
@@ -79,22 +80,49 @@ struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
        fixed->hw.init = &init;
 
        /* register the clock */
-       clk = clk_register(dev, &fixed->hw);
-       if (IS_ERR(clk))
+       hw = &fixed->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(fixed);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
+
+struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate, unsigned long fixed_accuracy)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
+                       flags, fixed_rate, fixed_accuracy);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
 
 /**
- * clk_register_fixed_rate - register fixed-rate clock with the clock framework
+ * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
+ * framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of clock's parent
  * @flags: framework-specific flags
  * @fixed_rate: non-adjustable clock rate
  */
+struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate)
+{
+       return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
+                                                    flags, fixed_rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
+
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned long fixed_rate)
index 1abcd76b4993805f2b135b92e5bc285b10de5c95..aab904618eb636f9f926a6b7b46d7b03b780b10c 100644 (file)
@@ -116,14 +116,15 @@ const struct clk_ops clk_fractional_divider_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fractional_divider_ops);
 
-struct clk *clk_register_fractional_divider(struct device *dev,
+struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
                const char *name, const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
                u8 clk_divider_flags, spinlock_t *lock)
 {
        struct clk_fractional_divider *fd;
        struct clk_init_data init;
-       struct clk *clk;
+       struct clk_hw *hw;
+       int ret;
 
        fd = kzalloc(sizeof(*fd), GFP_KERNEL);
        if (!fd)
@@ -146,10 +147,39 @@ struct clk *clk_register_fractional_divider(struct device *dev,
        fd->lock = lock;
        fd->hw.init = &init;
 
-       clk = clk_register(dev, &fd->hw);
-       if (IS_ERR(clk))
+       hw = &fd->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(fd);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_fractional_divider);
 
-       return clk;
+struct clk *clk_register_fractional_divider(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
+               u8 clk_divider_flags, spinlock_t *lock)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_fractional_divider(dev, name, parent_name, flags,
+                       reg, mshift, mwidth, nshift, nwidth, clk_divider_flags,
+                       lock);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_fractional_divider);
+
+void clk_hw_unregister_fractional_divider(struct clk_hw *hw)
+{
+       struct clk_fractional_divider *fd;
+
+       fd = to_clk_fd(hw);
+
+       clk_hw_unregister(hw);
+       kfree(fd);
+}
index d0d8ec8e1f1b0c8ae6de9457179ddf6bb8616434..4e691e35483a7ee5425b36f6d33668f741bdca6a 100644 (file)
@@ -110,7 +110,7 @@ const struct clk_ops clk_gate_ops = {
 EXPORT_SYMBOL_GPL(clk_gate_ops);
 
 /**
- * clk_register_gate - register a gate clock with the clock framework
+ * clk_hw_register_gate - register a gate clock with the clock framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of this clock's parent
@@ -120,14 +120,15 @@ EXPORT_SYMBOL_GPL(clk_gate_ops);
  * @clk_gate_flags: gate-specific flags for this clock
  * @lock: shared register lock for this clock
  */
-struct clk *clk_register_gate(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock)
 {
        struct clk_gate *gate;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
                if (bit_idx > 15) {
@@ -154,12 +155,29 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
        gate->lock = lock;
        gate->hw.init = &init;
 
-       clk = clk_register(dev, &gate->hw);
-
-       if (IS_ERR(clk))
+       hw = &gate->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(gate);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_gate);
+
+struct clk *clk_register_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 bit_idx,
+               u8 clk_gate_flags, spinlock_t *lock)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_gate(dev, name, parent_name, flags, reg,
+                                 bit_idx, clk_gate_flags, lock);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_gate);
 
@@ -178,3 +196,14 @@ void clk_unregister_gate(struct clk *clk)
        kfree(gate);
 }
 EXPORT_SYMBOL_GPL(clk_unregister_gate);
+
+void clk_hw_unregister_gate(struct clk_hw *hw)
+{
+       struct clk_gate *gate;
+
+       gate = to_clk_gate(hw);
+
+       clk_hw_unregister(hw);
+       kfree(gate);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);
index 08f65acc5d57b99f122d22d06ee4487ad9ed424f..86b245746a6bad5895b267101268124e5050c4b9 100644 (file)
@@ -94,13 +94,13 @@ const struct clk_ops clk_gpio_mux_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
 
-static struct clk *clk_register_gpio(struct device *dev, const char *name,
+static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents, unsigned gpio,
                bool active_low, unsigned long flags,
                const struct clk_ops *clk_gpio_ops)
 {
        struct clk_gpio *clk_gpio;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init = {};
        unsigned long gpio_flags;
        int err;
@@ -141,24 +141,26 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
        clk_gpio->gpiod = gpio_to_desc(gpio);
        clk_gpio->hw.init = &init;
 
+       hw = &clk_gpio->hw;
        if (dev)
-               clk = devm_clk_register(dev, &clk_gpio->hw);
+               err = devm_clk_hw_register(dev, hw);
        else
-               clk = clk_register(NULL, &clk_gpio->hw);
+               err = clk_hw_register(NULL, hw);
 
-       if (!IS_ERR(clk))
-               return clk;
+       if (!err)
+               return hw;
 
        if (!dev) {
                gpiod_put(clk_gpio->gpiod);
                kfree(clk_gpio);
        }
 
-       return clk;
+       return ERR_PTR(err);
 }
 
 /**
- * clk_register_gpio_gate - register a gpio clock gate with the clock framework
+ * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
+ * framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_name: name of this clock's parent
@@ -166,7 +168,7 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
  * @active_low: true if gpio should be set to 0 to enable clock
  * @flags: clock flags
  */
-struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned gpio, bool active_low,
                unsigned long flags)
 {
@@ -175,10 +177,24 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
                        (parent_name ? 1 : 0), gpio, active_low, flags,
                        &clk_gpio_gate_ops);
 }
+EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
+
+struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned gpio, bool active_low,
+               unsigned long flags)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low,
+                                      flags);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
+}
 EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
 
 /**
- * clk_register_gpio_mux - register a gpio clock mux with the clock framework
+ * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
  * @dev: device that is registering this clock
  * @name: name of this clock
  * @parent_names: names of this clock's parents
@@ -187,7 +203,7 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
  * @active_low: true if gpio should be set to 0 to enable clock
  * @flags: clock flags
  */
-struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents, unsigned gpio,
                bool active_low, unsigned long flags)
 {
@@ -199,6 +215,20 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
        return clk_register_gpio(dev, name, parent_names, num_parents,
                        gpio, active_low, flags, &clk_gpio_mux_ops);
 }
+EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
+
+struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents, unsigned gpio,
+               bool active_low, unsigned long flags)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
+                       gpio, active_low, flags);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
+}
 EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 static int gpio_clk_driver_probe(struct platform_device *pdev)
index d4c61985f4488ac1fac3ebc2f6061d98e922d2e3..5097831387ff061da202d806a3488a02d676bb7c 100644 (file)
@@ -88,8 +88,7 @@ void __init ls1x_clk_init(void)
 {
        struct clk *clk;
 
-       clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, CLK_IS_ROOT,
-                                     OSC);
+       clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC);
        clk_register_clkdev(clk, "osc_33m_clk", NULL);
 
        /* clock derived from 33 MHz OSC clk */
index 252188fd8bcdf49872bff06d313142df6d297ba3..16a3d5717f4edc371da411168276371f0a656cac 100644 (file)
@@ -113,16 +113,17 @@ const struct clk_ops clk_mux_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
 
-struct clk *clk_register_mux_table(struct device *dev, const char *name,
+struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
                unsigned long flags,
                void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
        struct clk_mux *mux;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
        u8 width = 0;
+       int ret;
 
        if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
                width = fls(mask) - ffs(mask) + 1;
@@ -157,12 +158,31 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
        mux->table = table;
        mux->hw.init = &init;
 
-       clk = clk_register(dev, &mux->hw);
-
-       if (IS_ERR(clk))
+       hw = &mux->hw;
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(mux);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
+
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u32 mask,
+               u8 clk_mux_flags, u32 *table, spinlock_t *lock)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
+                                      flags, reg, shift, mask, clk_mux_flags,
+                                      table, lock);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_mux_table);
 
@@ -180,6 +200,20 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 }
 EXPORT_SYMBOL_GPL(clk_register_mux);
 
+struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags, spinlock_t *lock)
+{
+       u32 mask = BIT(width) - 1;
+
+       return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
+                                     flags, reg, shift, mask, clk_mux_flags,
+                                     NULL, lock);
+}
+EXPORT_SYMBOL_GPL(clk_hw_register_mux);
+
 void clk_unregister_mux(struct clk *clk)
 {
        struct clk_mux *mux;
@@ -195,3 +229,14 @@ void clk_unregister_mux(struct clk *clk)
        kfree(mux);
 }
 EXPORT_SYMBOL_GPL(clk_unregister_mux);
+
+void clk_hw_unregister_mux(struct clk_hw *hw)
+{
+       struct clk_mux *mux;
+
+       mux = to_clk_mux(hw);
+
+       clk_hw_unregister(hw);
+       kfree(mux);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister_mux);
index a378db7b23822a9cb6da0bd52fc3c47fa3206260..64f196a9081630676bc4e98381d356feeed77029 100644 (file)
@@ -125,8 +125,7 @@ static void __init nspire_clk_setup(struct device_node *node,
 
        of_property_read_string(node, "clock-output-names", &clk_name);
 
-       clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT,
-                       info.base_clock);
+       clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, info.base_clock);
        if (!IS_ERR(clk))
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
        else
diff --git a/drivers/clk/clk-oxnas.c b/drivers/clk/clk-oxnas.c
new file mode 100644 (file)
index 0000000..efba7d4
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2010 Broadcom
+ * Copyright (C) 2012 Stephen Warren
+ * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/stringify.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+/* Standard regmap gate clocks */
+struct clk_oxnas {
+       struct clk_hw hw;
+       signed char bit;
+       struct regmap *regmap;
+};
+
+/* Regmap offsets */
+#define CLK_STAT_REGOFFSET     0x24
+#define CLK_SET_REGOFFSET      0x2c
+#define CLK_CLR_REGOFFSET      0x30
+
+static inline struct clk_oxnas *to_clk_oxnas(struct clk_hw *hw)
+{
+       return container_of(hw, struct clk_oxnas, hw);
+}
+
+static int oxnas_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_oxnas *std = to_clk_oxnas(hw);
+       int ret;
+       unsigned int val;
+
+       ret = regmap_read(std->regmap, CLK_STAT_REGOFFSET, &val);
+       if (ret < 0)
+               return ret;
+
+       return val & BIT(std->bit);
+}
+
+static int oxnas_clk_enable(struct clk_hw *hw)
+{
+       struct clk_oxnas *std = to_clk_oxnas(hw);
+
+       regmap_write(std->regmap, CLK_SET_REGOFFSET, BIT(std->bit));
+
+       return 0;
+}
+
+static void oxnas_clk_disable(struct clk_hw *hw)
+{
+       struct clk_oxnas *std = to_clk_oxnas(hw);
+
+       regmap_write(std->regmap, CLK_CLR_REGOFFSET, BIT(std->bit));
+}
+
+static const struct clk_ops oxnas_clk_ops = {
+       .enable = oxnas_clk_enable,
+       .disable = oxnas_clk_disable,
+       .is_enabled = oxnas_clk_is_enabled,
+};
+
+static const char *const oxnas_clk_parents[] = {
+       "oscillator",
+};
+
+static const char *const eth_parents[] = {
+       "gmacclk",
+};
+
+#define DECLARE_STD_CLKP(__clk, __parent)                      \
+static const struct clk_init_data clk_##__clk##_init = {       \
+       .name = __stringify(__clk),                             \
+       .ops = &oxnas_clk_ops,                                  \
+       .parent_names = __parent,                               \
+       .num_parents = ARRAY_SIZE(__parent),                    \
+}
+
+#define DECLARE_STD_CLK(__clk) DECLARE_STD_CLKP(__clk, oxnas_clk_parents)
+
+/* Hardware Bit - Clock association */
+struct clk_oxnas_init_data {
+       unsigned long bit;
+       const struct clk_init_data *clk_init;
+};
+
+/* Clk init data declaration */
+DECLARE_STD_CLK(leon);
+DECLARE_STD_CLK(dma_sgdma);
+DECLARE_STD_CLK(cipher);
+DECLARE_STD_CLK(sata);
+DECLARE_STD_CLK(audio);
+DECLARE_STD_CLK(usbmph);
+DECLARE_STD_CLKP(etha, eth_parents);
+DECLARE_STD_CLK(pciea);
+DECLARE_STD_CLK(nand);
+
+/* Table index is clock indice */
+static const struct clk_oxnas_init_data clk_oxnas_init[] = {
+       [0] = {0, &clk_leon_init},
+       [1] = {1, &clk_dma_sgdma_init},
+       [2] = {2, &clk_cipher_init},
+       /* Skip & Do not touch to DDR clock */
+       [3] = {4, &clk_sata_init},
+       [4] = {5, &clk_audio_init},
+       [5] = {6, &clk_usbmph_init},
+       [6] = {7, &clk_etha_init},
+       [7] = {8, &clk_pciea_init},
+       [8] = {9, &clk_nand_init},
+};
+
+struct clk_oxnas_data {
+       struct clk_oxnas clk_oxnas[ARRAY_SIZE(clk_oxnas_init)];
+       struct clk_onecell_data onecell_data[ARRAY_SIZE(clk_oxnas_init)];
+       struct clk *clks[ARRAY_SIZE(clk_oxnas_init)];
+};
+
+static int oxnas_stdclk_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct clk_oxnas_data *clk_oxnas;
+       struct regmap *regmap;
+       int i;
+
+       clk_oxnas = devm_kzalloc(&pdev->dev, sizeof(*clk_oxnas), GFP_KERNEL);
+       if (!clk_oxnas)
+               return -ENOMEM;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (!regmap) {
+               dev_err(&pdev->dev, "failed to have parent regmap\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(clk_oxnas_init); i++) {
+               struct clk_oxnas *_clk;
+
+               _clk = &clk_oxnas->clk_oxnas[i];
+               _clk->bit = clk_oxnas_init[i].bit;
+               _clk->hw.init = clk_oxnas_init[i].clk_init;
+               _clk->regmap = regmap;
+
+               clk_oxnas->clks[i] =
+                       devm_clk_register(&pdev->dev, &_clk->hw);
+               if (WARN_ON(IS_ERR(clk_oxnas->clks[i])))
+                       return PTR_ERR(clk_oxnas->clks[i]);
+       }
+
+       clk_oxnas->onecell_data->clks = clk_oxnas->clks;
+       clk_oxnas->onecell_data->clk_num = ARRAY_SIZE(clk_oxnas_init);
+
+       return of_clk_add_provider(np, of_clk_src_onecell_get,
+                                  clk_oxnas->onecell_data);
+}
+
+static int oxnas_stdclk_remove(struct platform_device *pdev)
+{
+       of_clk_del_provider(pdev->dev.of_node);
+
+       return 0;
+}
+
+static const struct of_device_id oxnas_stdclk_dt_ids[] = {
+       { .compatible = "oxsemi,ox810se-stdclk" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, oxnas_stdclk_dt_ids);
+
+static struct platform_driver oxnas_stdclk_driver = {
+       .probe = oxnas_stdclk_probe,
+       .remove = oxnas_stdclk_remove,
+       .driver = {
+               .name = "oxnas-stdclk",
+               .of_match_table = oxnas_stdclk_dt_ids,
+       },
+};
+
+module_platform_driver(oxnas_stdclk_driver);
index 9c0b8e6b1ab322b13aaef11ddb451c1b84ecffc9..8328863cb0e04709684d66efc128221ec92b4b0f 100644 (file)
@@ -132,7 +132,7 @@ static const struct palmas_clks_of_match_data palmas_of_clk32kg = {
        .init = {
                .name = "clk32kg",
                .ops = &palmas_clks_ops,
-               .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
+               .flags = CLK_IGNORE_UNUSED,
        },
        .desc = {
                .clk_name = "clk32kg",
@@ -148,7 +148,7 @@ static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
        .init = {
                .name = "clk32kgaudio",
                .ops = &palmas_clks_ops,
-               .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
+               .flags = CLK_IGNORE_UNUSED,
        },
        .desc = {
                .clk_name = "clk32kgaudio",
index 7bc1c4527ae48d0baad2ebb4e141385e695ff8f4..58566a17944a7320799b5e17316d02178d4be878 100644 (file)
@@ -869,14 +869,15 @@ static void __init core_mux_init(struct device_node *np)
        }
 }
 
-static struct clk *sysclk_from_fixed(struct device_node *node, const char *name)
+static struct clk __init
+*sysclk_from_fixed(struct device_node *node, const char *name)
 {
        u32 rate;
 
        if (of_property_read_u32(node, "clock-frequency", &rate))
                return ERR_PTR(-ENODEV);
 
-       return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
+       return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
 }
 
 static struct clk *sysclk_from_parent(const char *name)
index 0fee2f4ca258365bfa48a183c5712e7696e3b306..74383039761e6fab27fa9066e6cbd2e71bd4a880 100644 (file)
@@ -106,7 +106,6 @@ static int rk808_clkout_probe(struct platform_device *pdev)
        if (!clk_table)
                return -ENOMEM;
 
-       init.flags = CLK_IS_ROOT;
        init.parent_names = NULL;
        init.num_parents = 0;
        init.name = "rk808-clkout1";
index 004ab7dfcfe3b7539ae7533bccba9d80161fc0a6..eef75e305a595f6f4e453c6d5f0e950cc419bd56 100644 (file)
@@ -4,17 +4,19 @@
 #include <linux/init.h>
 #include <linux/io.h>
 
-static struct clk *out[2];
-static struct clk_onecell_data clk_data = { out, 2 };
+#define CLK_COUNT 4 /* cpu_clk, sys_clk, usb_clk, sdio_clk */
+static struct clk *clks[CLK_COUNT];
+static struct clk_onecell_data clk_data = { clks, CLK_COUNT };
 
-#define SYSCLK_CTRL    0x20
-#define CPUCLK_CTRL    0x24
-#define LEGACY_DIV     0x3c
+#define SYSCLK_DIV     0x20
+#define CPUCLK_DIV     0x24
+#define DIV_BYPASS     BIT(23)
 
-#define PLL_N(val)     (((val) >>  0) & 0x7f)
-#define PLL_K(val)     (((val) >> 13) & 0x7)
-#define PLL_M(val)     (((val) >> 16) & 0x7)
-#define DIV_INDEX(val) (((val) >>  8) & 0xf)
+/*** CLKGEN_PLL ***/
+#define extract_pll_n(val)     ((val >>  0) & ((1u << 7) - 1))
+#define extract_pll_k(val)     ((val >> 13) & ((1u << 3) - 1))
+#define extract_pll_m(val)     ((val >> 16) & ((1u << 3) - 1))
+#define extract_pll_isel(val)  ((val >> 24) & ((1u << 3) - 1))
 
 static void __init make_pll(int idx, const char *parent, void __iomem *base)
 {
@@ -22,40 +24,61 @@ static void __init make_pll(int idx, const char *parent, void __iomem *base)
        u32 val, mul, div;
 
        sprintf(name, "pll%d", idx);
-       val = readl_relaxed(base + idx*8);
-       mul =  PLL_N(val) + 1;
-       div = (PLL_M(val) + 1) << PLL_K(val);
+       val = readl(base + idx * 8);
+       mul =  extract_pll_n(val) + 1;
+       div = (extract_pll_m(val) + 1) << extract_pll_k(val);
        clk_register_fixed_factor(NULL, name, parent, 0, mul, div);
+       if (extract_pll_isel(val) != 1)
+               panic("%s: input not set to XTAL_IN\n", name);
 }
 
-static int __init get_div(void __iomem *base)
+static void __init make_cd(int idx, void __iomem *base)
 {
-       u8 sysclk_tab[16] = { 2, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 };
-       int idx = DIV_INDEX(readl_relaxed(base + LEGACY_DIV));
+       char name[8];
+       u32 val, mul, div;
 
-       return sysclk_tab[idx];
+       sprintf(name, "cd%d", idx);
+       val = readl(base + idx * 8);
+       mul =  1 << 27;
+       div = (2 << 27) + val;
+       clk_register_fixed_factor(NULL, name, "pll2", 0, mul, div);
+       if (val > 0xf0000000)
+               panic("%s: unsupported divider %x\n", name, val);
 }
 
 static void __init tango4_clkgen_setup(struct device_node *np)
 {
-       int div, ret;
+       struct clk **pp = clk_data.clks;
        void __iomem *base = of_iomap(np, 0);
        const char *parent = of_clk_get_parent_name(np, 0);
 
        if (!base)
-               panic("%s: invalid address\n", np->full_name);
+               panic("%s: invalid address\n", np->name);
+
+       if (readl(base + CPUCLK_DIV) & DIV_BYPASS)
+               panic("%s: unsupported cpuclk setup\n", np->name);
+
+       if (readl(base + SYSCLK_DIV) & DIV_BYPASS)
+               panic("%s: unsupported sysclk setup\n", np->name);
+
+       writel(0x100, base + CPUCLK_DIV); /* disable frequency ramping */
 
        make_pll(0, parent, base);
        make_pll(1, parent, base);
+       make_pll(2, parent, base);
+       make_cd(2, base + 0x80);
+       make_cd(6, base + 0x80);
 
-       out[0] = clk_register_divider(NULL, "cpuclk", "pll0", 0,
-                       base + CPUCLK_CTRL, 8, 8, CLK_DIVIDER_ONE_BASED, NULL);
+       pp[0] = clk_register_divider(NULL, "cpu_clk", "pll0", 0,
+                       base + CPUCLK_DIV, 8, 8, CLK_DIVIDER_ONE_BASED, NULL);
+       pp[1] = clk_register_fixed_factor(NULL, "sys_clk", "pll1", 0, 1, 4);
+       pp[2] = clk_register_fixed_factor(NULL,  "usb_clk", "cd2", 0, 1, 2);
+       pp[3] = clk_register_fixed_factor(NULL, "sdio_clk", "cd6", 0, 1, 2);
 
-       div = readl_relaxed(base + SYSCLK_CTRL) & BIT(23) ? get_div(base) : 4;
-       out[1] = clk_register_fixed_factor(NULL, "sysclk", "pll1", 0, 1, div);
+       if (IS_ERR(pp[0]) || IS_ERR(pp[1]) || IS_ERR(pp[2]) || IS_ERR(pp[3]))
+               panic("%s: clk registration failed\n", np->name);
 
-       ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-       if (IS_ERR(out[0]) || IS_ERR(out[1]) || ret < 0)
-               panic("%s: clk registration failed\n", np->full_name);
+       if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data))
+               panic("%s: clk provider registration failed\n", np->name);
 }
 CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup);
index 8e5ed649a0986721a1fcad1a9038ccb5b0c1e73d..697c66757400ccc2e502b9bf24b79bdf94d7fa6d 100644 (file)
@@ -74,7 +74,6 @@ static const struct clk_ops twl6040_mcpdm_ops = {
 static struct clk_init_data wm831x_clkout_init = {
        .name = "mcpdm_fclk",
        .ops = &twl6040_mcpdm_ops,
-       .flags = CLK_IS_ROOT,
 };
 
 static int twl6040_clk_probe(struct platform_device *pdev)
index 43f9d15255f4fd3a902b9ead2ccdc67d6e61fac4..88def4b2761cbf7fa6d4a64f3de1a667e2d6a41d 100644 (file)
@@ -58,7 +58,6 @@ static const struct clk_ops wm831x_xtal_ops = {
 static struct clk_init_data wm831x_xtal_init = {
        .name = "xtal",
        .ops = &wm831x_xtal_ops,
-       .flags = CLK_IS_ROOT,
 };
 
 static const unsigned long wm831x_fll_auto_rates[] = {
index d73450b60b2808413b7ca886644ff46e82a9d09e..343313250c58a2cbf60e7c6999358a0cdea00b22 100644 (file)
@@ -198,7 +198,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
        of_property_read_string(np, "clock-output-names", &clk_name);
        clk = xgene_register_clk_pll(NULL,
                        clk_name, of_clk_get_parent_name(np, 0),
-                       CLK_IS_ROOT, reg, 0, pll_type, &clk_lock,
+                       0, reg, 0, pll_type, &clk_lock,
                        version);
        if (!IS_ERR(clk)) {
                of_clk_add_provider(np, of_clk_src_simple_get, clk);
index fb74dc1f7520503d72f024b596dc72d002851e4c..ba1c3647fbf8d2f83f289748ec4f1a83f3ac85a2 100644 (file)
@@ -574,6 +574,9 @@ static void clk_core_unprepare(struct clk_core *core)
        if (WARN_ON(core->prepare_count == 0))
                return;
 
+       if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL))
+               return;
+
        if (--core->prepare_count > 0)
                return;
 
@@ -679,6 +682,9 @@ static void clk_core_disable(struct clk_core *core)
        if (WARN_ON(core->enable_count == 0))
                return;
 
+       if (WARN_ON(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL))
+               return;
+
        if (--core->enable_count > 0)
                return;
 
@@ -2397,6 +2403,11 @@ static int __clk_core_init(struct clk_core *core)
        if (core->ops->init)
                core->ops->init(core->hw);
 
+       if (core->flags & CLK_IS_CRITICAL) {
+               clk_core_prepare(core);
+               clk_core_enable(core);
+       }
+
        kref_init(&core->ref);
 out:
        clk_prepare_unlock();
@@ -2536,6 +2547,22 @@ fail_out:
 }
 EXPORT_SYMBOL_GPL(clk_register);
 
+/**
+ * clk_hw_register - register a clk_hw and return an error code
+ * @dev: device that is registering this clock
+ * @hw: link to hardware-specific clock data
+ *
+ * clk_hw_register is the primary interface for populating the clock tree with
+ * new clock nodes. It returns an integer equal to zero indicating success or
+ * less than zero indicating failure. Drivers must test for an error code after
+ * calling clk_hw_register().
+ */
+int clk_hw_register(struct device *dev, struct clk_hw *hw)
+{
+       return PTR_ERR_OR_ZERO(clk_register(dev, hw));
+}
+EXPORT_SYMBOL_GPL(clk_hw_register);
+
 /* Free memory allocated for a clock. */
 static void __clk_release(struct kref *ref)
 {
@@ -2637,11 +2664,26 @@ unlock:
 }
 EXPORT_SYMBOL_GPL(clk_unregister);
 
+/**
+ * clk_hw_unregister - unregister a currently registered clk_hw
+ * @hw: hardware-specific clock data to unregister
+ */
+void clk_hw_unregister(struct clk_hw *hw)
+{
+       clk_unregister(hw->clk);
+}
+EXPORT_SYMBOL_GPL(clk_hw_unregister);
+
 static void devm_clk_release(struct device *dev, void *res)
 {
        clk_unregister(*(struct clk **)res);
 }
 
+static void devm_clk_hw_release(struct device *dev, void *res)
+{
+       clk_hw_unregister(*(struct clk_hw **)res);
+}
+
 /**
  * devm_clk_register - resource managed clk_register()
  * @dev: device that is registering this clock
@@ -2672,6 +2714,36 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
 }
 EXPORT_SYMBOL_GPL(devm_clk_register);
 
+/**
+ * devm_clk_hw_register - resource managed clk_hw_register()
+ * @dev: device that is registering this clock
+ * @hw: link to hardware-specific clock data
+ *
+ * Managed clk_hw_register(). Clocks returned from this function are
+ * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
+ * for more information.
+ */
+int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
+{
+       struct clk_hw **hwp;
+       int ret;
+
+       hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
+       if (!hwp)
+               return -ENOMEM;
+
+       ret = clk_hw_register(dev, hw);
+       if (!ret) {
+               *hwp = hw;
+               devres_add(dev, hwp);
+       } else {
+               devres_free(hwp);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_register);
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
        struct clk *c = res;
@@ -2680,6 +2752,15 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
        return c == data;
 }
 
+static int devm_clk_hw_match(struct device *dev, void *res, void *data)
+{
+       struct clk_hw *hw = res;
+
+       if (WARN_ON(!hw))
+               return 0;
+       return hw == data;
+}
+
 /**
  * devm_clk_unregister - resource managed clk_unregister()
  * @clk: clock to unregister
@@ -2694,6 +2775,22 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(devm_clk_unregister);
 
+/**
+ * devm_clk_hw_unregister - resource managed clk_hw_unregister()
+ * @dev: device that is unregistering the hardware-specific clock data
+ * @hw: link to hardware-specific clock data
+ *
+ * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
+ * this function will not need to be called and the resource management
+ * code will ensure that the resource is freed.
+ */
+void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
+{
+       WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
+                               hw));
+}
+EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
+
 /*
  * clkdev helpers
  */
@@ -2855,6 +2952,7 @@ struct of_clk_provider {
 
        struct device_node *node;
        struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
+       struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
        void *data;
 };
 
@@ -2871,6 +2969,12 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
 }
 EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
 
+struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
+{
+       return data;
+}
+EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
+
 struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
 {
        struct clk_onecell_data *clk_data = data;
@@ -2885,6 +2989,21 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
 }
 EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
 
+struct clk_hw *
+of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct clk_hw_onecell_data *hw_data = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= hw_data->num) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return hw_data->hws[idx];
+}
+EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
+
 /**
  * of_clk_add_provider() - Register a clock provider for a node
  * @np: Device node pointer associated with clock provider
@@ -2920,6 +3039,41 @@ int of_clk_add_provider(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(of_clk_add_provider);
 
+/**
+ * of_clk_add_hw_provider() - Register a clock provider for a node
+ * @np: Device node pointer associated with clock provider
+ * @get: callback for decoding clk_hw
+ * @data: context pointer for @get callback.
+ */
+int of_clk_add_hw_provider(struct device_node *np,
+                          struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+                                                void *data),
+                          void *data)
+{
+       struct of_clk_provider *cp;
+       int ret;
+
+       cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+       if (!cp)
+               return -ENOMEM;
+
+       cp->node = of_node_get(np);
+       cp->data = data;
+       cp->get_hw = get;
+
+       mutex_lock(&of_clk_mutex);
+       list_add(&cp->link, &of_clk_providers);
+       mutex_unlock(&of_clk_mutex);
+       pr_debug("Added clk_hw provider from %s\n", np->full_name);
+
+       ret = of_clk_set_defaults(np, true);
+       if (ret < 0)
+               of_clk_del_provider(np);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
+
 /**
  * of_clk_del_provider() - Remove a previously registered clock provider
  * @np: Device node pointer associated with clock provider
@@ -2941,11 +3095,32 @@ void of_clk_del_provider(struct device_node *np)
 }
 EXPORT_SYMBOL_GPL(of_clk_del_provider);
 
+static struct clk_hw *
+__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
+                             struct of_phandle_args *clkspec)
+{
+       struct clk *clk;
+       struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
+
+       if (provider->get_hw) {
+               hw = provider->get_hw(clkspec, provider->data);
+       } else if (provider->get) {
+               clk = provider->get(clkspec, provider->data);
+               if (!IS_ERR(clk))
+                       hw = __clk_get_hw(clk);
+               else
+                       hw = ERR_CAST(clk);
+       }
+
+       return hw;
+}
+
 struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
                                       const char *dev_id, const char *con_id)
 {
        struct of_clk_provider *provider;
        struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+       struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
 
        if (!clkspec)
                return ERR_PTR(-EINVAL);
@@ -2954,10 +3129,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
        mutex_lock(&of_clk_mutex);
        list_for_each_entry(provider, &of_clk_providers, link) {
                if (provider->node == clkspec->np)
-                       clk = provider->get(clkspec, provider->data);
-               if (!IS_ERR(clk)) {
-                       clk = __clk_create_clk(__clk_get_hw(clk), dev_id,
-                                              con_id);
+                       hw = __of_clk_get_hw_from_provider(provider, clkspec);
+               if (!IS_ERR(hw)) {
+                       clk = __clk_create_clk(hw, dev_id, con_id);
 
                        if (!IS_ERR(clk) && !__clk_get(clk)) {
                                __clk_free_clk(clk);
@@ -3126,6 +3300,41 @@ static int parent_ready(struct device_node *np)
        }
 }
 
+/**
+ * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
+ * @np: Device node pointer associated with clock provider
+ * @index: clock index
+ * @flags: pointer to clk_core->flags
+ *
+ * Detects if the clock-critical property exists and, if so, sets the
+ * corresponding CLK_IS_CRITICAL flag.
+ *
+ * Do not use this function. It exists only for legacy Device Tree
+ * bindings, such as the one-clock-per-node style that are outdated.
+ * Those bindings typically put all clock data into .dts and the Linux
+ * driver has no clock data, thus making it impossible to set this flag
+ * correctly from the driver. Only those drivers may call
+ * of_clk_detect_critical from their setup functions.
+ *
+ * Return: error code or zero on success
+ */
+int of_clk_detect_critical(struct device_node *np,
+                                         int index, unsigned long *flags)
+{
+       struct property *prop;
+       const __be32 *cur;
+       uint32_t idx;
+
+       if (!np || !flags)
+               return -EINVAL;
+
+       of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
+               if (index == idx)
+                       *flags |= CLK_IS_CRITICAL;
+
+       return 0;
+}
+
 /**
  * of_clk_init() - Scan and init clock providers from the DT
  * @matches: array of compatible values and init functions for providers.
index eb20b941154babe8ad145633b642e53ac9891069..89cc700fbc37bd299eaac573326494ed71d78e15 100644 (file)
@@ -301,6 +301,20 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 }
 EXPORT_SYMBOL(clkdev_alloc);
 
+struct clk_lookup *
+clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
+{
+       struct clk_lookup *cl;
+       va_list ap;
+
+       va_start(ap, dev_fmt);
+       cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
+       va_end(ap);
+
+       return cl;
+}
+EXPORT_SYMBOL(clkdev_hw_alloc);
+
 /**
  * clkdev_create - allocate and add a clkdev lookup structure
  * @clk: struct clk to associate with all clk_lookups
@@ -324,6 +338,29 @@ struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
 }
 EXPORT_SYMBOL_GPL(clkdev_create);
 
+/**
+ * clkdev_hw_create - allocate and add a clkdev lookup structure
+ * @hw: struct clk_hw to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_fmt: format string describing device name
+ *
+ * Returns a clk_lookup structure, which can be later unregistered and
+ * freed.
+ */
+struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
+       const char *dev_fmt, ...)
+{
+       struct clk_lookup *cl;
+       va_list ap;
+
+       va_start(ap, dev_fmt);
+       cl = vclkdev_create(hw, con_id, dev_fmt, ap);
+       va_end(ap);
+
+       return cl;
+}
+EXPORT_SYMBOL_GPL(clkdev_hw_create);
+
 int clk_add_alias(const char *alias, const char *alias_dev_name,
        const char *con_id, struct device *dev)
 {
@@ -404,28 +441,28 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
 EXPORT_SYMBOL(clk_register_clkdev);
 
 /**
- * clk_register_clkdevs - register a set of clk_lookup for a struct clk
- * @clk: struct clk to associate with all clk_lookups
- * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
- * @num: number of clk_lookup structures to register
+ * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
+ * @hw: struct clk_hw to associate with all clk_lookups
+ * @con_id: connection ID string on device
+ * @dev_id: format string describing device name
  *
- * To make things easier for mass registration, we detect error clks
- * from a previous clk_register() call, and return the error code for
- * those.  This is to permit this function to be called immediately
- * after clk_register().
+ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * clkdev.
  */
-int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
+int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
+       const char *dev_id)
 {
-       unsigned i;
-
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       struct clk_lookup *cl;
 
-       for (i = 0; i < num; i++, cl++) {
-               cl->clk_hw = __clk_get_hw(clk);
-               __clkdev_add(cl);
-       }
+       /*
+        * Since dev_id can be NULL, and NULL is handled specially, we must
+        * pass it as either a NULL format string, or with "%s".
+        */
+       if (dev_id)
+               cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
+       else
+               cl = __clk_register_clkdev(hw, con_id, NULL);
 
-       return 0;
+       return cl ? 0 : -ENOMEM;
 }
-EXPORT_SYMBOL(clk_register_clkdevs);
+EXPORT_SYMBOL(clk_hw_register_clkdev);
index 8935bff99fe7acc083fb631c5ff8b7e97e7544c6..db44a198a0d9999f3e998033a3f8a517035c5e74 100644 (file)
@@ -31,6 +31,7 @@ struct clk_gate2 {
        struct clk_hw hw;
        void __iomem    *reg;
        u8              bit_idx;
+       u8              cgr_val;
        u8              flags;
        spinlock_t      *lock;
        unsigned int    *share_count;
@@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
                goto out;
 
        reg = readl(gate->reg);
-       reg |= 3 << gate->bit_idx;
+       reg &= ~(3 << gate->bit_idx);
+       reg |= gate->cgr_val << gate->bit_idx;
        writel(reg, gate->reg);
 
 out:
@@ -125,7 +127,7 @@ static struct clk_ops clk_gate2_ops = {
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 bit_idx,
+               void __iomem *reg, u8 bit_idx, u8 cgr_val,
                u8 clk_gate2_flags, spinlock_t *lock,
                unsigned int *share_count)
 {
@@ -140,6 +142,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
        /* struct clk_gate2 assignments */
        gate->reg = reg;
        gate->bit_idx = bit_idx;
+       gate->cgr_val = cgr_val;
        gate->flags = clk_gate2_flags;
        gate->lock = lock;
        gate->share_count = share_count;
index fea125eb4330beba84d9788b91755c37f6ada3e5..97e742a8be174597b81ae1916cbf0ca3526b220f 100644 (file)
@@ -134,6 +134,8 @@ static u32 share_count_esai;
 static u32 share_count_ssi1;
 static u32 share_count_ssi2;
 static u32 share_count_ssi3;
+static u32 share_count_sai1;
+static u32 share_count_sai2;
 
 static struct clk ** const uart_clks[] __initconst = {
        &clks[IMX6SX_CLK_UART_IPG],
@@ -469,10 +471,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
        clks[IMX6SX_CLK_SSI3]         = imx_clk_gate2_shared("ssi3",          "ssi3_podf",  base + 0x7c, 22, &share_count_ssi3);
        clks[IMX6SX_CLK_UART_IPG]     = imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
        clks[IMX6SX_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",   "uart_podf",         base + 0x7c, 26);
-       clks[IMX6SX_CLK_SAI1_IPG]     = imx_clk_gate2("sai1_ipg",      "ipg",               base + 0x7c, 28);
-       clks[IMX6SX_CLK_SAI2_IPG]     = imx_clk_gate2("sai2_ipg",      "ipg",               base + 0x7c, 30);
-       clks[IMX6SX_CLK_SAI1]         = imx_clk_gate2("sai1",          "ssi1_podf",         base + 0x7c, 28);
-       clks[IMX6SX_CLK_SAI2]         = imx_clk_gate2("sai2",          "ssi2_podf",         base + 0x7c, 30);
+       clks[IMX6SX_CLK_SAI1_IPG]     = imx_clk_gate2_shared("sai1_ipg", "ipg",             base + 0x7c, 28, &share_count_sai1);
+       clks[IMX6SX_CLK_SAI2_IPG]     = imx_clk_gate2_shared("sai2_ipg", "ipg",             base + 0x7c, 30, &share_count_sai2);
+       clks[IMX6SX_CLK_SAI1]         = imx_clk_gate2_shared("sai1",    "ssi1_podf",        base + 0x7c, 28, &share_count_sai1);
+       clks[IMX6SX_CLK_SAI2]         = imx_clk_gate2_shared("sai2",    "ssi2_podf",        base + 0x7c, 30, &share_count_sai2);
 
        /* CCGR6 */
        clks[IMX6SX_CLK_USBOH3]       = imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
index fbb6a8c8653dcb1045640dd178eef02669ab9950..7912be83c4af192317a5783b3aa29e6128abe89a 100644 (file)
@@ -342,7 +342,7 @@ static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
 
 static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
        "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", };
+       "pll_audio_main_clk", "pll_video_main_clk", "ckil", };
 
 static const char *lvds1_sel[] = { "pll_arm_main_clk",
        "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
@@ -382,6 +382,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 
        clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
        clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc");
+       clks[IMX7D_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop");
        base = of_iomap(np, 0);
index 0a94d9661d9123551b5b84cd5764cb9b91a6c176..3a1f24475ee4af56b2329eadb0e9ce38b85b4d8a 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/of_address.h>
 #include <linux/clk.h>
+#include <linux/syscore_ops.h>
 #include <dt-bindings/clock/vf610-clock.h>
 
 #include "clk.h"
@@ -40,6 +41,7 @@
 #define CCM_CCGR9              (ccm_base + 0x64)
 #define CCM_CCGR10             (ccm_base + 0x68)
 #define CCM_CCGR11             (ccm_base + 0x6c)
+#define CCM_CCGRx(x)           (CCM_CCGR0 + (x) * 4)
 #define CCM_CMEOR0             (ccm_base + 0x70)
 #define CCM_CMEOR1             (ccm_base + 0x74)
 #define CCM_CMEOR2             (ccm_base + 0x78)
@@ -115,10 +117,19 @@ static struct clk_div_table pll4_audio_div_table[] = {
 static struct clk *clk[VF610_CLK_END];
 static struct clk_onecell_data clk_data;
 
+static u32 cscmr1;
+static u32 cscmr2;
+static u32 cscdr1;
+static u32 cscdr2;
+static u32 cscdr3;
+static u32 ccgr[12];
+
 static unsigned int const clks_init_on[] __initconst = {
        VF610_CLK_SYS_BUS,
        VF610_CLK_DDR_SEL,
        VF610_CLK_DAP,
+       VF610_CLK_DDRMC,
+       VF610_CLK_WKPU,
 };
 
 static struct clk * __init vf610_get_fixed_clock(
@@ -132,6 +143,43 @@ static struct clk * __init vf610_get_fixed_clock(
        return clk;
 };
 
+static int vf610_clk_suspend(void)
+{
+       int i;
+
+       cscmr1 = readl_relaxed(CCM_CSCMR1);
+       cscmr2 = readl_relaxed(CCM_CSCMR2);
+
+       cscdr1 = readl_relaxed(CCM_CSCDR1);
+       cscdr2 = readl_relaxed(CCM_CSCDR2);
+       cscdr3 = readl_relaxed(CCM_CSCDR3);
+
+       for (i = 0; i < 12; i++)
+               ccgr[i] = readl_relaxed(CCM_CCGRx(i));
+
+       return 0;
+}
+
+static void vf610_clk_resume(void)
+{
+       int i;
+
+       writel_relaxed(cscmr1, CCM_CSCMR1);
+       writel_relaxed(cscmr2, CCM_CSCMR2);
+
+       writel_relaxed(cscdr1, CCM_CSCDR1);
+       writel_relaxed(cscdr2, CCM_CSCDR2);
+       writel_relaxed(cscdr3, CCM_CSCDR3);
+
+       for (i = 0; i < 12; i++)
+               writel_relaxed(ccgr[i], CCM_CCGRx(i));
+}
+
+static struct syscore_ops vf610_clk_syscore_ops = {
+       .suspend = vf610_clk_suspend,
+       .resume = vf610_clk_resume,
+};
+
 static void __init vf610_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
@@ -233,6 +281,9 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, 0, pll4_audio_div_table, &imx_ccm_lock);
        clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
 
+       clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
+       clk[VF610_CLK_WKPU] = imx_clk_gate2_cgr("wkpu", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(10), 0x2);
+
        clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6);
        clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6);
 
@@ -321,11 +372,14 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
        clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
        clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
-       clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8));
+       clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, CCM_CCGRx_CGn(8));
        clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
        clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
        clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
-       clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8));
+       clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(8));
+
+       clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", CCM_CCGR1, CCM_CCGRx_CGn(13));
+       clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", CCM_CCGR7, CCM_CCGRx_CGn(13));
 
        clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
        clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
@@ -409,6 +463,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
                clk_prepare_enable(clk[clks_init_on[i]]);
 
+       register_syscore_ops(&vf610_clk_syscore_ops);
+
        /* Add the clocks to provider list */
        clk_data.clks = clk;
        clk_data.clk_num = ARRAY_SIZE(clk);
index d942f5748d08ecad14f06cb6461765212a52f6a1..508d0fad84cf0744d7a7d4c73d8ba748be03a09f 100644 (file)
@@ -41,7 +41,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 bit_idx,
+               void __iomem *reg, u8 bit_idx, u8 cgr_val,
                u8 clk_gate_flags, spinlock_t *lock,
                unsigned int *share_count);
 
@@ -55,7 +55,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
                void __iomem *reg, u8 shift)
 {
        return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-                       shift, 0, &imx_ccm_lock, NULL);
+                       shift, 0x3, 0, &imx_ccm_lock, NULL);
 }
 
 static inline struct clk *imx_clk_gate2_shared(const char *name,
@@ -63,7 +63,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
                unsigned int *share_count)
 {
        return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-                       shift, 0, &imx_ccm_lock, share_count);
+                       shift, 0x3, 0, &imx_ccm_lock, share_count);
+}
+
+static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent,
+               void __iomem *reg, u8 shift, u8 cgr_val)
+{
+       return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+                       shift, cgr_val, 0, &imx_ccm_lock, NULL);
 }
 
 struct clk *imx_clk_pfd(const char *name, const char *parent_name,
index 9e9fe4b19ac47b11dc2fba8431687137e1934f99..309049d41f1ba04539fee6a7853a98d1f44e7874 100644 (file)
@@ -57,7 +57,7 @@ static int mtk_reset(struct reset_controller_dev *rcdev,
        return mtk_reset_deassert(rcdev, id);
 }
 
-static struct reset_control_ops mtk_reset_ops = {
+static const struct reset_control_ops mtk_reset_ops = {
        .assert = mtk_reset_assert,
        .deassert = mtk_reset_deassert,
        .reset = mtk_reset,
index 61f6d55c4ac701766e6e9f7dd067a17d10a4bbea..4d057b3e21b2a50d9bbae66abf745d2d7a4ef277 100644 (file)
@@ -141,11 +141,11 @@ static const struct composite_conf mali_conf __initconst = {
 };
 
 static const struct clk_conf meson8b_xtal_conf __initconst =
-       FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal",
-                    CLK_IS_ROOT, PARM(0x00, 4, 7));
+       FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 0,
+                       PARM(0x00, 4, 7));
 
 static const struct clk_conf meson8b_clk_confs[] __initconst = {
-       FIXED_RATE(CLKID_ZERO, "zero", CLK_IS_ROOT, 0),
+       FIXED_RATE(CLKID_ZERO, "zero", 0, 0),
        PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
            p_xtal, 0, &pll_confs),
        PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
index 38931dbd1effd7a9ce6b11360274e673add57e98..383f6a4f64f093258e60ea725197125a5e0f07fc 100644 (file)
@@ -99,23 +99,19 @@ void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
                return;
        }
 
-       clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200);
+       clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200);
        clk_register_clkdev(clk, "clk32", NULL);
 
-       vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT,
-                               26000000);
+       vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000);
        clk_register_clkdev(vctcxo, "vctcxo", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT,
-                               800000000);
+       clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 800000000);
        clk_register_clkdev(clk, "pll1", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, CLK_IS_ROOT,
-                               480000000);
+       clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, 0, 480000000);
        clk_register_clkdev(clk, "usb_pll", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "pll2", NULL, CLK_IS_ROOT,
-                               960000000);
+       clk = clk_register_fixed_rate(NULL, "pll2", NULL, 0, 960000000);
        clk_register_clkdev(clk, "pll2", NULL);
 
        clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
index 251533d87c6538f6ff2cb46bee025a2589a1df2f..3a51fff1b0e76b7bbebdbc969d7f1d67fe796887 100644 (file)
@@ -63,11 +63,11 @@ struct mmp2_clk_unit {
 };
 
 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
-       {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
-       {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
-       {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 800000000},
-       {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 960000000},
-       {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
+       {MMP2_CLK_CLK32, "clk32", NULL, 0, 32768},
+       {MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
+       {MMP2_CLK_PLL1, "pll1", NULL, 0, 800000000},
+       {MMP2_CLK_PLL2, "pll2", NULL, 0, 960000000},
+       {MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
index 64eaf4141c69842a766f49a79a1b2698b6974e8a..87f2317b2a005aca6aed18a39de7509010edd19e 100644 (file)
@@ -56,10 +56,10 @@ struct pxa168_clk_unit {
 };
 
 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
-       {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
-       {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
-       {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
-       {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
+       {PXA168_CLK_CLK32, "clk32", NULL, 0, 32768},
+       {PXA168_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
+       {PXA168_CLK_PLL1, "pll1", NULL, 0, 624000000},
+       {PXA168_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
index 433a5ae1eae0f7237ce5641f076663e57f64bd4a..e478ff44e170b4591430064fb9d4eba9592e8dbe 100644 (file)
@@ -34,12 +34,12 @@ struct pxa1928_clk_unit {
 };
 
 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
-       {0, "clk32", NULL, CLK_IS_ROOT, 32768},
-       {0, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
-       {0, "pll1_624", NULL, CLK_IS_ROOT, 624000000},
-       {0, "pll5p", NULL, CLK_IS_ROOT, 832000000},
-       {0, "pll5", NULL, CLK_IS_ROOT, 1248000000},
-       {0, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
+       {0, "clk32", NULL, 0, 32768},
+       {0, "vctcxo", NULL, 0, 26000000},
+       {0, "pll1_624", NULL, 0, 624000000},
+       {0, "pll5p", NULL, 0, 832000000},
+       {0, "pll5", NULL, 0, 1248000000},
+       {0, "usb_pll", NULL, 0, 480000000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
index 13d6173326a435ad46af652f27bfc20e32302e04..e22a67f76d932546eba42aec3b69be266d775238 100644 (file)
@@ -56,10 +56,10 @@ struct pxa910_clk_unit {
 };
 
 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
-       {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
-       {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
-       {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
-       {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
+       {PXA910_CLK_CLK32, "clk32", NULL, 0, 32768},
+       {PXA910_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
+       {PXA910_CLK_PLL1, "pll1", NULL, 0, 624000000},
+       {PXA910_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
 };
 
 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
index 0dd83fb950c9464a8ad7b20f680f0e5ef3a84e5b..a9ef9209532aa66605c1eca9de7b1f74d52ae09c 100644 (file)
@@ -92,15 +92,13 @@ void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
                return;
        }
 
-       clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200);
+       clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200);
        clk_register_clkdev(clk, "clk32", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT,
-                               26000000);
+       clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000);
        clk_register_clkdev(clk, "vctcxo", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT,
-                               624000000);
+       clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 624000000);
        clk_register_clkdev(clk, "pll1", NULL);
 
        clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
index e1d2ce22cdf11a704da261ca6e397db139c52368..a520cf7702a11649fe14581a59cdb063c859b461 100644 (file)
@@ -97,15 +97,13 @@ void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
                return;
        }
 
-       clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200);
+       clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200);
        clk_register_clkdev(clk, "clk32", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT,
-                               26000000);
+       clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000);
        clk_register_clkdev(clk, "vctcxo", NULL);
 
-       clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT,
-                               624000000);
+       clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 624000000);
        clk_register_clkdev(clk, "pll1", NULL);
 
        clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
index b54da1fe73f07ea5f36a82ac33da211b9cc375a1..b4e4d6aa26319a3b871d7d609df4ac6ee9a9ab78 100644 (file)
@@ -74,7 +74,7 @@ static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,
        return 0;
 }
 
-static struct reset_control_ops mmp_clk_reset_ops = {
+static const struct reset_control_ops mmp_clk_reset_ops = {
        .assert         = mmp_clk_reset_assert,
        .deassert       = mmp_clk_reset_deassert,
 };
index 5428efb9fbf5dc9fb311664f67932c57bdd7211f..3cd1af0af0d97299facff7fcb0717b13256a6cbe 100644 (file)
@@ -129,20 +129,10 @@ static const char * const gcc_xo_ddr_500_200[] = {
 };
 
 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-#define P_XO 0
-#define FE_PLL_200 1
-#define FE_PLL_500 2
-#define DDRC_PLL_666  3
-
-#define DDRC_PLL_666_SDCC  1
-#define FE_PLL_125_DLY 1
-
-#define FE_PLL_WCSS2G 1
-#define FE_PLL_WCSS5G 1
 
 static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = {
        F(48000000, P_XO, 1, 0, 0),
-       F(200000000, FE_PLL_200, 1, 0, 0),
+       F(200000000, P_FEPLL200, 1, 0, 0),
        { }
 };
 
@@ -334,15 +324,15 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
 };
 
 static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = {
-       F(1843200, FE_PLL_200, 1, 144, 15625),
-       F(3686400, FE_PLL_200, 1, 288, 15625),
-       F(7372800, FE_PLL_200, 1, 576, 15625),
-       F(14745600, FE_PLL_200, 1, 1152, 15625),
-       F(16000000, FE_PLL_200, 1, 2, 25),
+       F(1843200, P_FEPLL200, 1, 144, 15625),
+       F(3686400, P_FEPLL200, 1, 288, 15625),
+       F(7372800, P_FEPLL200, 1, 576, 15625),
+       F(14745600, P_FEPLL200, 1, 1152, 15625),
+       F(16000000, P_FEPLL200, 1, 2, 25),
        F(24000000, P_XO, 1, 1, 2),
-       F(32000000, FE_PLL_200, 1, 4, 25),
-       F(40000000, FE_PLL_200, 1, 1, 5),
-       F(46400000, FE_PLL_200, 1, 29, 125),
+       F(32000000, P_FEPLL200, 1, 4, 25),
+       F(40000000, P_FEPLL200, 1, 1, 5),
+       F(46400000, P_FEPLL200, 1, 29, 125),
        F(48000000, P_XO, 1, 0, 0),
        { }
 };
@@ -410,9 +400,9 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = {
 };
 
 static const struct freq_tbl ftbl_gcc_gp_clk[] = {
-       F(1250000,  FE_PLL_200, 1, 16, 0),
-       F(2500000,  FE_PLL_200, 1,  8, 0),
-       F(5000000,  FE_PLL_200, 1,  4, 0),
+       F(1250000,  P_FEPLL200, 1, 16, 0),
+       F(2500000,  P_FEPLL200, 1,  8, 0),
+       F(5000000,  P_FEPLL200, 1,  4, 0),
        { }
 };
 
@@ -512,11 +502,11 @@ static struct clk_branch gcc_gp3_clk = {
 static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
        F(144000,    P_XO,                      1,  3, 240),
        F(400000,    P_XO,                      1,  1, 0),
-       F(20000000,  FE_PLL_500,                1,  1, 25),
-       F(25000000,  FE_PLL_500,                1,  1, 20),
-       F(50000000,  FE_PLL_500,                1,  1, 10),
-       F(100000000, FE_PLL_500,                1,  1, 5),
-       F(193000000, DDRC_PLL_666_SDCC,         1,  0, 0),
+       F(20000000,  P_FEPLL500,                1,  1, 25),
+       F(25000000,  P_FEPLL500,                1,  1, 20),
+       F(50000000,  P_FEPLL500,                1,  1, 10),
+       F(100000000, P_FEPLL500,                1,  1, 5),
+       F(193000000, P_DDRPLL,          1,  0, 0),
        { }
 };
 
@@ -536,9 +526,9 @@ static struct clk_rcg2  sdcc1_apps_clk_src = {
 
 static const struct freq_tbl ftbl_gcc_apps_clk[] = {
        F(48000000, P_XO,          1, 0, 0),
-       F(200000000, FE_PLL_200,   1, 0, 0),
-       F(500000000, FE_PLL_500,   1, 0, 0),
-       F(626000000, DDRC_PLL_666, 1, 0, 0),
+       F(200000000, P_FEPLL200,   1, 0, 0),
+       F(500000000, P_FEPLL500,   1, 0, 0),
+       F(626000000, P_DDRPLLAPSS, 1, 0, 0),
        { }
 };
 
@@ -557,7 +547,7 @@ static struct clk_rcg2 apps_clk_src = {
 
 static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = {
        F(48000000, P_XO,          1, 0, 0),
-       F(100000000, FE_PLL_200,   2, 0, 0),
+       F(100000000, P_FEPLL200,   2, 0, 0),
        { }
 };
 
@@ -940,7 +930,7 @@ static struct clk_branch gcc_usb2_mock_utmi_clk = {
 };
 
 static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
-       F(2000000, FE_PLL_200, 10, 0, 0),
+       F(2000000, P_FEPLL200, 10, 0, 0),
        { }
 };
 
@@ -1007,7 +997,7 @@ static struct clk_branch gcc_usb3_mock_utmi_clk = {
 };
 
 static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = {
-       F(125000000, FE_PLL_125_DLY, 1, 0, 0),
+       F(125000000, P_FEPLL125DLY, 1, 0, 0),
        { }
 };
 
@@ -1027,7 +1017,7 @@ static struct clk_rcg2 fephy_125m_dly_clk_src = {
 
 static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = {
        F(48000000, P_XO, 1, 0, 0),
-       F(250000000, FE_PLL_WCSS2G, 1, 0, 0),
+       F(250000000, P_FEPLLWCSS2G, 1, 0, 0),
        { }
 };
 
@@ -1097,7 +1087,7 @@ static struct clk_branch gcc_wcss2g_rtc_clk = {
 
 static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = {
        F(48000000, P_XO, 1, 0, 0),
-       F(250000000, FE_PLL_WCSS5G, 1, 0, 0),
+       F(250000000, P_FEPLLWCSS5G, 1, 0, 0),
        { }
 };
 
@@ -1325,6 +1315,16 @@ MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
 
 static int gcc_ipq4019_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
+
+       clk_register_fixed_rate(dev, "fepll125", "xo", 0, 200000000);
+       clk_register_fixed_rate(dev, "fepll125dly", "xo", 0, 200000000);
+       clk_register_fixed_rate(dev, "fepllwcss2g", "xo", 0, 200000000);
+       clk_register_fixed_rate(dev, "fepllwcss5g", "xo", 0, 200000000);
+       clk_register_fixed_rate(dev, "fepll200", "xo", 0, 200000000);
+       clk_register_fixed_rate(dev, "fepll500", "xo", 0, 200000000);
+       clk_register_fixed_rate(dev, "ddrpllapss", "xo", 0, 666000000);
+
        return qcom_cc_probe(pdev, &gcc_ipq4019_desc);
 }
 
index 6c977d3a8590674ff97fb81962ba3fccc33ce3a6..0324d8daab9bc01e6099ed78770dab235f9fd98d 100644 (file)
@@ -55,7 +55,7 @@ qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
        return regmap_update_bits(rst->regmap, map->reg, mask, 0);
 }
 
-struct reset_control_ops qcom_reset_ops = {
+const struct reset_control_ops qcom_reset_ops = {
        .reset = qcom_reset,
        .assert = qcom_reset_assert,
        .deassert = qcom_reset_deassert,
index 0e11e2130f97cd244c56cc3a27a9bf49c72a6945..cda877927d43a03f5628149038da9d620354170c 100644 (file)
@@ -32,6 +32,6 @@ struct qcom_reset_controller {
 #define to_qcom_reset_controller(r) \
        container_of(r, struct qcom_reset_controller, rcdev);
 
-extern struct reset_control_ops qcom_reset_ops;
+extern const struct reset_control_ops qcom_reset_ops;
 
 #endif
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
new file mode 100644 (file)
index 0000000..2115ce4
--- /dev/null
@@ -0,0 +1,16 @@
+config CLK_RENESAS_CPG_MSSR
+       bool
+       default y if ARCH_R8A7795
+
+config CLK_RENESAS_CPG_MSTP
+       bool
+       default y if ARCH_R7S72100
+       default y if ARCH_R8A73A4
+       default y if ARCH_R8A7740
+       default y if ARCH_R8A7778
+       default y if ARCH_R8A7779
+       default y if ARCH_R8A7790
+       default y if ARCH_R8A7791
+       default y if ARCH_R8A7793
+       default y if ARCH_R8A7794
+       default y if ARCH_SH73A0
index 7e2579b303267d8badc1feb9d242af08b6260318..ead8bb8435249493958f2320c5c15aca9430fa66 100644 (file)
@@ -1,13 +1,15 @@
 obj-$(CONFIG_ARCH_EMEV2)               += clk-emev2.o
-obj-$(CONFIG_ARCH_R7S72100)            += clk-rz.o clk-mstp.o
-obj-$(CONFIG_ARCH_R8A73A4)             += clk-r8a73a4.o clk-mstp.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7740)             += clk-r8a7740.o clk-mstp.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7778)             += clk-r8a7778.o clk-mstp.o
-obj-$(CONFIG_ARCH_R8A7779)             += clk-r8a7779.o clk-mstp.o
-obj-$(CONFIG_ARCH_R8A7790)             += clk-rcar-gen2.o clk-mstp.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7791)             += clk-rcar-gen2.o clk-mstp.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7793)             += clk-rcar-gen2.o clk-mstp.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7794)             += clk-rcar-gen2.o clk-mstp.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7795)             += renesas-cpg-mssr.o \
-                                          r8a7795-cpg-mssr.o clk-div6.o
-obj-$(CONFIG_ARCH_SH73A0)              += clk-sh73a0.o clk-mstp.o clk-div6.o
+obj-$(CONFIG_ARCH_R7S72100)            += clk-rz.o
+obj-$(CONFIG_ARCH_R8A73A4)             += clk-r8a73a4.o clk-div6.o
+obj-$(CONFIG_ARCH_R8A7740)             += clk-r8a7740.o clk-div6.o
+obj-$(CONFIG_ARCH_R8A7778)             += clk-r8a7778.o
+obj-$(CONFIG_ARCH_R8A7779)             += clk-r8a7779.o
+obj-$(CONFIG_ARCH_R8A7790)             += clk-rcar-gen2.o clk-div6.o
+obj-$(CONFIG_ARCH_R8A7791)             += clk-rcar-gen2.o clk-div6.o
+obj-$(CONFIG_ARCH_R8A7793)             += clk-rcar-gen2.o clk-div6.o
+obj-$(CONFIG_ARCH_R8A7794)             += clk-rcar-gen2.o clk-div6.o
+obj-$(CONFIG_ARCH_R8A7795)             += r8a7795-cpg-mssr.o
+obj-$(CONFIG_ARCH_SH73A0)              += clk-sh73a0.o clk-div6.o
+
+obj-$(CONFIG_CLK_RENESAS_CPG_MSSR)     += renesas-cpg-mssr.o clk-div6.o
+obj-$(CONFIG_CLK_RENESAS_CPG_MSTP)     += clk-mstp.o
index 3d44e183aedd61c7fd28d15b6ede180033e0b6e1..8b597b9a380442e8bbbc17086a2c194be848a7f2 100644 (file)
@@ -243,9 +243,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
 }
 CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
 
-
-#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
-int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
+int cpg_mstp_attach_dev(struct generic_pm_domain *unused, struct device *dev)
 {
        struct device_node *np = dev->of_node;
        struct of_phandle_args clkspec;
@@ -297,7 +295,7 @@ fail_put:
        return error;
 }
 
-void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev)
+void cpg_mstp_detach_dev(struct generic_pm_domain *unused, struct device *dev)
 {
        if (!list_empty(&dev->power.subsys_data->clock_list))
                pm_clk_destroy(dev);
@@ -326,4 +324,3 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np)
 
        of_genpd_add_provider_simple(np, pd);
 }
-#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
index b2198aef5ed4291291d30ca1df3cc2ba5ab5c9a0..6af7f5b6e8240b37d6155088b6ebafd73689f368 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/bug.h>
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -26,6 +27,7 @@
 
 #include "renesas-cpg-mssr.h"
 
+#define CPG_RCKCR      0x240
 
 enum clk_ids {
        /* Core Clock Outputs exported to DT */
@@ -50,6 +52,7 @@ enum clk_ids {
        CLK_S3,
        CLK_SDSRC,
        CLK_SSPSRC,
+       CLK_RINT,
 
        /* Module Clocks */
        MOD_CLK_BASE
@@ -63,8 +66,12 @@ enum r8a7795_clk_types {
        CLK_TYPE_GEN3_PLL3,
        CLK_TYPE_GEN3_PLL4,
        CLK_TYPE_GEN3_SD,
+       CLK_TYPE_GEN3_R,
 };
 
+#define DEF_GEN3_SD(_name, _id, _parent, _offset)      \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
+
 static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
        /* External Clock Inputs */
        DEF_INPUT("extal",  CLK_EXTAL),
@@ -102,10 +109,10 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A7795_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A7795_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_SD("sd0",           R8A7795_CLK_SD0,   CLK_PLL1_DIV2, 0x0074),
-       DEF_SD("sd1",           R8A7795_CLK_SD1,   CLK_PLL1_DIV2, 0x0078),
-       DEF_SD("sd2",           R8A7795_CLK_SD2,   CLK_PLL1_DIV2, 0x0268),
-       DEF_SD("sd3",           R8A7795_CLK_SD3,   CLK_PLL1_DIV2, 0x026c),
+       DEF_GEN3_SD("sd0",      R8A7795_CLK_SD0,   CLK_PLL1_DIV2, 0x0074),
+       DEF_GEN3_SD("sd1",      R8A7795_CLK_SD1,   CLK_PLL1_DIV2, 0x0078),
+       DEF_GEN3_SD("sd2",      R8A7795_CLK_SD2,   CLK_PLL1_DIV2, 0x0268),
+       DEF_GEN3_SD("sd3",      R8A7795_CLK_SD3,   CLK_PLL1_DIV2, 0x026c),
 
        DEF_FIXED("cl",         R8A7795_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A7795_CLK_CP,    CLK_EXTAL,      2, 1),
@@ -113,6 +120,11 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
        DEF_DIV6P1("mso",       R8A7795_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
        DEF_DIV6P1("hdmi",      R8A7795_CLK_HDMI,  CLK_PLL1_DIV2, 0x250),
        DEF_DIV6P1("canfd",     R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+
+       DEF_DIV6_RO("osc",      R8A7795_CLK_OSC,   CLK_EXTAL, CPG_RCKCR, 8),
+       DEF_DIV6_RO("r_int",    CLK_RINT,          CLK_EXTAL, CPG_RCKCR, 32),
+
+       DEF_BASE("r",           R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
 };
 
 static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
@@ -139,6 +151,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
        DEF_MOD("usb3-if0",              328,   R8A7795_CLK_S3D1),
        DEF_MOD("usb-dmac0",             330,   R8A7795_CLK_S3D1),
        DEF_MOD("usb-dmac1",             331,   R8A7795_CLK_S3D1),
+       DEF_MOD("rwdt0",                 402,   R8A7795_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A7795_CLK_CP),
        DEF_MOD("intc-ap",               408,   R8A7795_CLK_S3D1),
        DEF_MOD("audmac0",               502,   R8A7795_CLK_S3D4),
@@ -148,6 +161,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
        DEF_MOD("hscif2",                518,   R8A7795_CLK_S3D1),
        DEF_MOD("hscif1",                519,   R8A7795_CLK_S3D1),
        DEF_MOD("hscif0",                520,   R8A7795_CLK_S3D1),
+       DEF_MOD("pwm",                   523,   R8A7795_CLK_S3D4),
        DEF_MOD("fcpvd3",                600,   R8A7795_CLK_S2D1),
        DEF_MOD("fcpvd2",                601,   R8A7795_CLK_S2D1),
        DEF_MOD("fcpvd1",                602,   R8A7795_CLK_S2D1),
@@ -578,6 +592,18 @@ struct clk * __init r8a7795_cpg_clk_register(struct device *dev,
        case CLK_TYPE_GEN3_SD:
                return cpg_sd_clk_register(core, base, __clk_get_name(parent));
 
+       case CLK_TYPE_GEN3_R:
+               /* RINT is default. Only if EXTALR is populated, we switch to it */
+               value = readl(base + CPG_RCKCR) & 0x3f;
+
+               if (clk_get_rate(clks[CLK_EXTALR])) {
+                       parent = clks[CLK_EXTALR];
+                       value |= BIT(15);
+               }
+
+               writel(value, base + CPG_RCKCR);
+               break;
+
        default:
                return ERR_PTR(-EINVAL);
        }
index 58e24b326a48bb810cfee9dfb519ea504409404d..1f2dc3629f0e02a037318b9b53fd3fc01af2c2d6 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/clk/renesas.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/mod_devicetable.h>
@@ -253,7 +254,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 {
        struct clk *clk = NULL, *parent;
        struct device *dev = priv->dev;
-       unsigned int id = core->id;
+       unsigned int id = core->id, div = core->div;
        const char *parent_name;
 
        WARN_DEBUG(id >= priv->num_core_clks);
@@ -266,6 +267,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 
        case CLK_TYPE_FF:
        case CLK_TYPE_DIV6P1:
+       case CLK_TYPE_DIV6_RO:
                WARN_DEBUG(core->parent >= priv->num_core_clks);
                parent = priv->clks[core->parent];
                if (IS_ERR(parent)) {
@@ -274,13 +276,18 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
                }
 
                parent_name = __clk_get_name(parent);
-               if (core->type == CLK_TYPE_FF) {
-                       clk = clk_register_fixed_factor(NULL, core->name,
-                                                       parent_name, 0,
-                                                       core->mult, core->div);
-               } else {
+
+               if (core->type == CLK_TYPE_DIV6_RO)
+                       /* Multiply with the DIV6 register value */
+                       div *= (readl(priv->base + core->offset) & 0x3f) + 1;
+
+               if (core->type == CLK_TYPE_DIV6P1) {
                        clk = cpg_div6_register(core->name, 1, &parent_name,
                                                priv->base + core->offset);
+               } else {
+                       clk = clk_register_fixed_factor(NULL, core->name,
+                                                       parent_name, 0,
+                                                       core->mult, div);
                }
                break;
 
@@ -375,8 +382,6 @@ fail:
        kfree(clock);
 }
 
-
-#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
 struct cpg_mssr_clk_domain {
        struct generic_pm_domain genpd;
        struct device_node *np;
@@ -384,6 +389,8 @@ struct cpg_mssr_clk_domain {
        unsigned int core_pm_clks[0];
 };
 
+static struct cpg_mssr_clk_domain *cpg_mssr_clk_domain;
+
 static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
                               struct cpg_mssr_clk_domain *pd)
 {
@@ -407,17 +414,20 @@ static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec,
        }
 }
 
-static int cpg_mssr_attach_dev(struct generic_pm_domain *genpd,
-                              struct device *dev)
+int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev)
 {
-       struct cpg_mssr_clk_domain *pd =
-               container_of(genpd, struct cpg_mssr_clk_domain, genpd);
+       struct cpg_mssr_clk_domain *pd = cpg_mssr_clk_domain;
        struct device_node *np = dev->of_node;
        struct of_phandle_args clkspec;
        struct clk *clk;
        int i = 0;
        int error;
 
+       if (!pd) {
+               dev_dbg(dev, "CPG/MSSR clock domain not yet available\n");
+               return -EPROBE_DEFER;
+       }
+
        while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
                                           &clkspec)) {
                if (cpg_mssr_is_pm_clk(&clkspec, pd))
@@ -457,8 +467,7 @@ fail_put:
        return error;
 }
 
-static void cpg_mssr_detach_dev(struct generic_pm_domain *genpd,
-                               struct device *dev)
+void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
 {
        if (!list_empty(&dev->power.subsys_data->clock_list))
                pm_clk_destroy(dev);
@@ -487,19 +496,11 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
        pm_genpd_init(genpd, &simple_qos_governor, false);
        genpd->attach_dev = cpg_mssr_attach_dev;
        genpd->detach_dev = cpg_mssr_detach_dev;
+       cpg_mssr_clk_domain = pd;
 
        of_genpd_add_provider_simple(np, genpd);
        return 0;
 }
-#else
-static inline int cpg_mssr_add_clk_domain(struct device *dev,
-                                         const unsigned int *core_pm_clks,
-                                         unsigned int num_core_pm_clks)
-{
-       return 0;
-}
-#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
-
 
 static const struct of_device_id cpg_mssr_match[] = {
 #ifdef CONFIG_ARCH_R8A7795
index 952b6957233b46be624afde93c8a37598dd3ea95..0d1e3e811e79bf431c0640667af9343b92a3cbf0 100644 (file)
@@ -37,6 +37,7 @@ enum clk_types {
        CLK_TYPE_IN,            /* External Clock Input */
        CLK_TYPE_FF,            /* Fixed Factor Clock */
        CLK_TYPE_DIV6P1,        /* DIV6 Clock with 1 parent clock */
+       CLK_TYPE_DIV6_RO,       /* DIV6 Clock read only with extra divisor */
 
        /* Custom definitions start here */
        CLK_TYPE_CUSTOM,
@@ -53,9 +54,8 @@ enum clk_types {
        DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
 #define DEF_DIV6P1(_name, _id, _parent, _offset)       \
        DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
-#define DEF_SD(_name, _id, _parent, _offset)   \
-       DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
-
+#define DEF_DIV6_RO(_name, _id, _parent, _offset, _div)        \
+       DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
 
     /*
      * Definitions of Module Clocks
index 80b9a379beb403d86b62ade7880f847e5c353325..f47a2fa962d2e881d004bbc0067502ce6cc07704 100644 (file)
@@ -15,3 +15,4 @@ obj-y += clk-rk3188.o
 obj-y  += clk-rk3228.o
 obj-y  += clk-rk3288.o
 obj-y  += clk-rk3368.o
+obj-y  += clk-rk3399.o
index 4e73ed5cab5801110574f9846015e073b321c01b..4bb130cd006275f5c70e27bcda7a746a00c76d34 100644 (file)
@@ -158,12 +158,16 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
 
                writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
                                              reg_data->div_core_shift) |
-                      HIWORD_UPDATE(1, 1, reg_data->mux_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 {
                /* select alternate parent */
-               writel(HIWORD_UPDATE(1, 1, reg_data->mux_core_shift),
-                       cpuclk->reg_base + reg_data->core_reg);
+               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);
        }
 
        spin_unlock_irqrestore(cpuclk->lock, flags);
@@ -198,7 +202,9 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
 
        writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
                                reg_data->div_core_shift) |
-              HIWORD_UPDATE(0, 1, reg_data->mux_core_shift),
+              HIWORD_UPDATE(reg_data->mux_core_main,
+                               reg_data->mux_core_mask,
+                               reg_data->mux_core_shift),
               cpuclk->reg_base + reg_data->core_reg);
 
        if (ndata->old_rate > ndata->new_rate)
@@ -252,7 +258,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
                return ERR_PTR(-ENOMEM);
 
        init.name = name;
-       init.parent_names = &parent_names[0];
+       init.parent_names = &parent_names[reg_data->mux_core_main];
        init.num_parents = 1;
        init.ops = &rockchip_cpuclk_ops;
 
@@ -270,10 +276,10 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
        cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb;
        cpuclk->hw.init = &init;
 
-       cpuclk->alt_parent = __clk_lookup(parent_names[1]);
+       cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]);
        if (!cpuclk->alt_parent) {
-               pr_err("%s: could not lookup alternate parent\n",
-                      __func__);
+               pr_err("%s: could not lookup alternate parent: (%d)\n",
+                      __func__, reg_data->mux_core_alt);
                ret = -EINVAL;
                goto free_cpuclk;
        }
@@ -285,10 +291,11 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
                goto free_cpuclk;
        }
 
-       clk = __clk_lookup(parent_names[0]);
+       clk = __clk_lookup(parent_names[reg_data->mux_core_main]);
        if (!clk) {
-               pr_err("%s: could not lookup parent clock %s\n",
-                      __func__, parent_names[0]);
+               pr_err("%s: could not lookup parent clock: (%d) %s\n",
+                      __func__, reg_data->mux_core_main,
+                      parent_names[reg_data->mux_core_main]);
                ret = -EINVAL;
                goto free_alt_parent;
        }
index e0dc7e83403a90118a47102577962c55e88fa614..bc856f21f6b20d35e2c421c51a54e1718274302e 100644 (file)
@@ -123,7 +123,8 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
        raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
        raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
        raw_value |= nineties;
-       writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg);
+       writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift),
+              mmc_clock->reg);
 
        pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
                clk_hw_get_name(hw), degrees, delay_num,
index 5de797e34d545881f87346f242acb71cb5769c23..8ac73bc7f93d8a0bdace04519bf2118e906ca2ed 100644 (file)
@@ -46,6 +46,8 @@ struct rockchip_clk_pll {
        const struct rockchip_pll_rate_table *rate_table;
        unsigned int            rate_count;
        spinlock_t              *lock;
+
+       struct rockchip_clk_provider *ctx;
 };
 
 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
@@ -90,7 +92,7 @@ static long rockchip_pll_round_rate(struct clk_hw *hw,
  */
 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 {
-       struct regmap *grf = rockchip_clk_get_grf();
+       struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
        unsigned int val;
        int delay = 24000000, ret;
 
@@ -234,7 +236,7 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
        /* wait for the pll to lock */
        ret = rockchip_pll_wait_lock(pll);
        if (ret) {
-               pr_warn("%s: pll update unsucessful, trying to restore old params\n",
+               pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
                        __func__);
                rockchip_rk3036_pll_set_params(pll, &cur);
        }
@@ -251,7 +253,7 @@ static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
        unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
-       struct regmap *grf = rockchip_clk_get_grf();
+       struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
 
        if (IS_ERR(grf)) {
                pr_debug("%s: grf regmap not available, aborting rate change\n",
@@ -473,7 +475,7 @@ static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
        /* wait for the pll to lock */
        ret = rockchip_pll_wait_lock(pll);
        if (ret) {
-               pr_warn("%s: pll update unsucessful, trying to restore old params\n",
+               pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
                        __func__);
                rockchip_rk3066_pll_set_params(pll, &cur);
        }
@@ -490,7 +492,7 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
        unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
-       struct regmap *grf = rockchip_clk_get_grf();
+       struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
 
        if (IS_ERR(grf)) {
                pr_debug("%s: grf regmap not available, aborting rate change\n",
@@ -563,7 +565,7 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
                 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
        if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
                                                     || rate->nb != cur.nb) {
-               struct regmap *grf = rockchip_clk_get_grf();
+               struct regmap *grf = rockchip_clk_get_grf(pll->ctx);
 
                if (IS_ERR(grf))
                        return;
@@ -591,16 +593,278 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
        .init = rockchip_rk3066_pll_init,
 };
 
+/**
+ * PLL used in RK3399
+ */
+
+#define RK3399_PLLCON(i)                       (i * 0x4)
+#define RK3399_PLLCON0_FBDIV_MASK              0xfff
+#define RK3399_PLLCON0_FBDIV_SHIFT             0
+#define RK3399_PLLCON1_REFDIV_MASK             0x3f
+#define RK3399_PLLCON1_REFDIV_SHIFT            0
+#define RK3399_PLLCON1_POSTDIV1_MASK           0x7
+#define RK3399_PLLCON1_POSTDIV1_SHIFT          8
+#define RK3399_PLLCON1_POSTDIV2_MASK           0x7
+#define RK3399_PLLCON1_POSTDIV2_SHIFT          12
+#define RK3399_PLLCON2_FRAC_MASK               0xffffff
+#define RK3399_PLLCON2_FRAC_SHIFT              0
+#define RK3399_PLLCON2_LOCK_STATUS             BIT(31)
+#define RK3399_PLLCON3_PWRDOWN                 BIT(0)
+#define RK3399_PLLCON3_DSMPD_MASK              0x1
+#define RK3399_PLLCON3_DSMPD_SHIFT             3
+
+static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+       u32 pllcon;
+       int delay = 24000000;
+
+       /* poll check the lock status in rk3399 xPLLCON2 */
+       while (delay > 0) {
+               pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
+               if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
+                       return 0;
+
+               delay--;
+       }
+
+       pr_err("%s: timeout waiting for pll to lock\n", __func__);
+       return -ETIMEDOUT;
+}
+
+static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
+                                       struct rockchip_pll_rate_table *rate)
+{
+       u32 pllcon;
+
+       pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
+       rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
+                               & RK3399_PLLCON0_FBDIV_MASK);
+
+       pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
+       rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
+                               & RK3399_PLLCON1_REFDIV_MASK);
+       rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
+                               & RK3399_PLLCON1_POSTDIV1_MASK);
+       rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
+                               & RK3399_PLLCON1_POSTDIV2_MASK);
+
+       pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
+       rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
+                               & RK3399_PLLCON2_FRAC_MASK);
+
+       pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
+       rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
+                               & RK3399_PLLCON3_DSMPD_MASK);
+}
+
+static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
+                                                    unsigned long prate)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+       struct rockchip_pll_rate_table cur;
+       u64 rate64 = prate;
+
+       rockchip_rk3399_pll_get_params(pll, &cur);
+
+       rate64 *= cur.fbdiv;
+       do_div(rate64, cur.refdiv);
+
+       if (cur.dsmpd == 0) {
+               /* fractional mode */
+               u64 frac_rate64 = prate * cur.frac;
+
+               do_div(frac_rate64, cur.refdiv);
+               rate64 += frac_rate64 >> 24;
+       }
+
+       do_div(rate64, cur.postdiv1);
+       do_div(rate64, cur.postdiv2);
+
+       return (unsigned long)rate64;
+}
+
+static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
+                               const struct rockchip_pll_rate_table *rate)
+{
+       const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+       struct clk_mux *pll_mux = &pll->pll_mux;
+       struct rockchip_pll_rate_table cur;
+       u32 pllcon;
+       int rate_change_remuxed = 0;
+       int cur_parent;
+       int ret;
+
+       pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+               __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
+               rate->postdiv2, rate->dsmpd, rate->frac);
+
+       rockchip_rk3399_pll_get_params(pll, &cur);
+       cur.rate = 0;
+
+       cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
+       if (cur_parent == PLL_MODE_NORM) {
+               pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
+               rate_change_remuxed = 1;
+       }
+
+       /* update pll values */
+       writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
+                                                 RK3399_PLLCON0_FBDIV_SHIFT),
+                      pll->reg_base + RK3399_PLLCON(0));
+
+       writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
+                                                  RK3399_PLLCON1_REFDIV_SHIFT) |
+                      HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
+                                                    RK3399_PLLCON1_POSTDIV1_SHIFT) |
+                      HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
+                                                    RK3399_PLLCON1_POSTDIV2_SHIFT),
+                      pll->reg_base + RK3399_PLLCON(1));
+
+       /* xPLL CON2 is not HIWORD_MASK */
+       pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
+       pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
+       pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
+       writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
+
+       writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
+                                           RK3399_PLLCON3_DSMPD_SHIFT),
+                      pll->reg_base + RK3399_PLLCON(3));
+
+       /* wait for the pll to lock */
+       ret = rockchip_rk3399_pll_wait_lock(pll);
+       if (ret) {
+               pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
+                       __func__);
+               rockchip_rk3399_pll_set_params(pll, &cur);
+       }
+
+       if (rate_change_remuxed)
+               pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
+
+       return ret;
+}
+
+static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+                                       unsigned long prate)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+       const struct rockchip_pll_rate_table *rate;
+       unsigned long old_rate = rockchip_rk3399_pll_recalc_rate(hw, prate);
+
+       pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+                __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
+
+       /* Get required rate settings from table */
+       rate = rockchip_get_pll_settings(pll, drate);
+       if (!rate) {
+               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+                       drate, __clk_get_name(hw->clk));
+               return -EINVAL;
+       }
+
+       return rockchip_rk3399_pll_set_params(pll, rate);
+}
+
+static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+       writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
+              pll->reg_base + RK3399_PLLCON(3));
+
+       return 0;
+}
+
+static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+       writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
+                            RK3399_PLLCON3_PWRDOWN, 0),
+              pll->reg_base + RK3399_PLLCON(3));
+}
+
+static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+       u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
+
+       return !(pllcon & RK3399_PLLCON3_PWRDOWN);
+}
+
+static void rockchip_rk3399_pll_init(struct clk_hw *hw)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+       const struct rockchip_pll_rate_table *rate;
+       struct rockchip_pll_rate_table cur;
+       unsigned long drate;
+
+       if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
+               return;
+
+       drate = clk_hw_get_rate(hw);
+       rate = rockchip_get_pll_settings(pll, drate);
+
+       /* when no rate setting for the current rate, rely on clk_set_rate */
+       if (!rate)
+               return;
+
+       rockchip_rk3399_pll_get_params(pll, &cur);
+
+       pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
+                drate);
+       pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+                cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
+                cur.dsmpd, cur.frac);
+       pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+                rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
+                rate->dsmpd, rate->frac);
+
+       if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
+               rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
+               rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
+               struct clk *parent = clk_get_parent(hw->clk);
+
+               if (!parent) {
+                       pr_warn("%s: parent of %s not available\n",
+                               __func__, __clk_get_name(hw->clk));
+                       return;
+               }
+
+               pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
+                        __func__, __clk_get_name(hw->clk));
+               rockchip_rk3399_pll_set_params(pll, rate);
+       }
+}
+
+static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
+       .recalc_rate = rockchip_rk3399_pll_recalc_rate,
+       .enable = rockchip_rk3399_pll_enable,
+       .disable = rockchip_rk3399_pll_disable,
+       .is_enabled = rockchip_rk3399_pll_is_enabled,
+};
+
+static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
+       .recalc_rate = rockchip_rk3399_pll_recalc_rate,
+       .round_rate = rockchip_pll_round_rate,
+       .set_rate = rockchip_rk3399_pll_set_rate,
+       .enable = rockchip_rk3399_pll_enable,
+       .disable = rockchip_rk3399_pll_disable,
+       .is_enabled = rockchip_rk3399_pll_is_enabled,
+       .init = rockchip_rk3399_pll_init,
+};
+
 /*
  * Common registering of pll clocks
  */
 
-struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
+struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+               enum rockchip_pll_type pll_type,
                const char *name, const char *const *parent_names,
-               u8 num_parents, void __iomem *base, int con_offset,
-               int grf_lock_offset, int lock_shift, int mode_offset,
-               int mode_shift, struct rockchip_pll_rate_table *rate_table,
-               u8 clk_pll_flags, spinlock_t *lock)
+               u8 num_parents, int con_offset, int grf_lock_offset,
+               int lock_shift, int mode_offset, int mode_shift,
+               struct rockchip_pll_rate_table *rate_table,
+               u8 clk_pll_flags)
 {
        const char *pll_parents[3];
        struct clk_init_data init;
@@ -624,14 +888,16 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
        /* create the mux on top of the real pll */
        pll->pll_mux_ops = &clk_mux_ops;
        pll_mux = &pll->pll_mux;
-       pll_mux->reg = base + mode_offset;
+       pll_mux->reg = ctx->reg_base + mode_offset;
        pll_mux->shift = mode_shift;
        pll_mux->mask = PLL_MODE_MASK;
        pll_mux->flags = 0;
-       pll_mux->lock = lock;
+       pll_mux->lock = &ctx->lock;
        pll_mux->hw.init = &init;
 
-       if (pll_type == pll_rk3036 || pll_type == pll_rk3066)
+       if (pll_type == pll_rk3036 ||
+           pll_type == pll_rk3066 ||
+           pll_type == pll_rk3399)
                pll_mux->flags |= CLK_MUX_HIWORD_MASK;
 
        /* the actual muxing is xin24m, pll-output, xin32k */
@@ -688,6 +954,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
                else
                        init.ops = &rockchip_rk3066_pll_clk_ops;
                break;
+       case pll_rk3399:
+               if (!pll->rate_table)
+                       init.ops = &rockchip_rk3399_pll_clk_norate_ops;
+               else
+                       init.ops = &rockchip_rk3399_pll_clk_ops;
+               break;
        default:
                pr_warn("%s: Unknown pll type for pll clk %s\n",
                        __func__, name);
@@ -695,11 +967,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 
        pll->hw.init = &init;
        pll->type = pll_type;
-       pll->reg_base = base + con_offset;
+       pll->reg_base = ctx->reg_base + con_offset;
        pll->lock_offset = grf_lock_offset;
        pll->lock_shift = lock_shift;
        pll->flags = clk_pll_flags;
-       pll->lock = lock;
+       pll->lock = &ctx->lock;
+       pll->ctx = ctx;
 
        pll_clk = clk_register(NULL, &pll->hw);
        if (IS_ERR(pll_clk)) {
index 7cdb2d61f3e0666075ac25d6eb83b7fba88e872d..924f560dcf80e8a5681fba4c670524b2b20b01ee 100644 (file)
@@ -113,7 +113,10 @@ static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
        .core_reg = RK2928_CLKSEL_CON(0),
        .div_core_shift = 0,
        .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .mux_core_shift = 7,
+       .mux_core_mask = 0x1,
 };
 
 PNAME(mux_pll_p)               = { "xin24m", "xin24m" };
@@ -437,6 +440,7 @@ static const char *const rk3036_critical_clocks[] __initconst = {
 
 static void __init rk3036_clk_init(struct device_node *np)
 {
+       struct rockchip_clk_provider *ctx;
        void __iomem *reg_base;
        struct clk *clk;
 
@@ -446,22 +450,27 @@ static void __init rk3036_clk_init(struct device_node *np)
                return;
        }
 
-       rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(reg_base);
+               return;
+       }
 
        clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
        if (IS_ERR(clk))
                pr_warn("%s: could not register clock usb480m: %ld\n",
                        __func__, PTR_ERR(clk));
 
-       rockchip_clk_register_plls(rk3036_pll_clks,
+       rockchip_clk_register_plls(ctx, rk3036_pll_clks,
                                   ARRAY_SIZE(rk3036_pll_clks),
                                   RK3036_GRF_SOC_STATUS0);
-       rockchip_clk_register_branches(rk3036_clk_branches,
+       rockchip_clk_register_branches(ctx, rk3036_clk_branches,
                                  ARRAY_SIZE(rk3036_clk_branches));
        rockchip_clk_protect_critical(rk3036_critical_clocks,
                                      ARRAY_SIZE(rk3036_critical_clocks));
 
-       rockchip_clk_register_armclk(ARMCLK, "armclk",
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
                        mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
                        &rk3036_cpuclk_data, rk3036_cpuclk_rates,
                        ARRAY_SIZE(rk3036_cpuclk_rates));
@@ -469,6 +478,8 @@ static void __init rk3036_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
+       rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
+
+       rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
index 40bab39014915087e691257caf0b063b72fd04bf..d0e722a0e8cff9afb79f7c22535042fe2332ce61 100644 (file)
@@ -155,7 +155,10 @@ static const struct rockchip_cpuclk_reg_data rk3066_cpuclk_data = {
        .core_reg = RK2928_CLKSEL_CON(0),
        .div_core_shift = 0,
        .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .mux_core_shift = 8,
+       .mux_core_mask = 0x1,
 };
 
 #define RK3188_DIV_ACLK_CORE_MASK      0x7
@@ -191,7 +194,10 @@ static const struct rockchip_cpuclk_reg_data rk3188_cpuclk_data = {
        .core_reg = RK2928_CLKSEL_CON(0),
        .div_core_shift = 9,
        .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .mux_core_shift = 8,
+       .mux_core_mask = 0x1,
 };
 
 PNAME(mux_pll_p)               = { "xin24m", "xin32k" };
@@ -753,57 +759,75 @@ static const char *const rk3188_critical_clocks[] __initconst = {
        "hclk_cpubus"
 };
 
-static void __init rk3188_common_clk_init(struct device_node *np)
+static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
 {
+       struct rockchip_clk_provider *ctx;
        void __iomem *reg_base;
 
        reg_base = of_iomap(np, 0);
        if (!reg_base) {
                pr_err("%s: could not map cru region\n", __func__);
-               return;
+               return ERR_PTR(-ENOMEM);
        }
 
-       rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(reg_base);
+               return ERR_PTR(-ENOMEM);
+       }
 
-       rockchip_clk_register_branches(common_clk_branches,
+       rockchip_clk_register_branches(ctx, common_clk_branches,
                                  ARRAY_SIZE(common_clk_branches));
 
        rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
+       rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
+
+       return ctx;
 }
 
 static void __init rk3066a_clk_init(struct device_node *np)
 {
-       rk3188_common_clk_init(np);
-       rockchip_clk_register_plls(rk3066_pll_clks,
+       struct rockchip_clk_provider *ctx;
+
+       ctx = rk3188_common_clk_init(np);
+       if (IS_ERR(ctx))
+               return;
+
+       rockchip_clk_register_plls(ctx, rk3066_pll_clks,
                                   ARRAY_SIZE(rk3066_pll_clks),
                                   RK3066_GRF_SOC_STATUS);
-       rockchip_clk_register_branches(rk3066a_clk_branches,
+       rockchip_clk_register_branches(ctx, rk3066a_clk_branches,
                                  ARRAY_SIZE(rk3066a_clk_branches));
-       rockchip_clk_register_armclk(ARMCLK, "armclk",
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
                        mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
                        &rk3066_cpuclk_data, rk3066_cpuclk_rates,
                        ARRAY_SIZE(rk3066_cpuclk_rates));
        rockchip_clk_protect_critical(rk3188_critical_clocks,
                                      ARRAY_SIZE(rk3188_critical_clocks));
+       rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
 
 static void __init rk3188a_clk_init(struct device_node *np)
 {
+       struct rockchip_clk_provider *ctx;
        struct clk *clk1, *clk2;
        unsigned long rate;
        int ret;
 
-       rk3188_common_clk_init(np);
-       rockchip_clk_register_plls(rk3188_pll_clks,
+       ctx = rk3188_common_clk_init(np);
+       if (IS_ERR(ctx))
+               return;
+
+       rockchip_clk_register_plls(ctx, rk3188_pll_clks,
                                   ARRAY_SIZE(rk3188_pll_clks),
                                   RK3188_GRF_SOC_STATUS);
-       rockchip_clk_register_branches(rk3188_clk_branches,
+       rockchip_clk_register_branches(ctx, rk3188_clk_branches,
                                  ARRAY_SIZE(rk3188_clk_branches));
-       rockchip_clk_register_armclk(ARMCLK, "armclk",
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
                                  mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
                                  &rk3188_cpuclk_data, rk3188_cpuclk_rates,
                                  ARRAY_SIZE(rk3188_cpuclk_rates));
@@ -827,6 +851,7 @@ static void __init rk3188a_clk_init(struct device_node *np)
 
        rockchip_clk_protect_critical(rk3188_critical_clocks,
                                      ARRAY_SIZE(rk3188_critical_clocks));
+       rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
 
index 7702d2855e9cf476bd0b2672679aa73057729fd9..016bdb0b793ab94501fa59f1e185cf3c9f44dc87 100644 (file)
@@ -111,7 +111,10 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = {
        .core_reg = RK2928_CLKSEL_CON(0),
        .div_core_shift = 0,
        .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .mux_core_shift = 6,
+       .mux_core_mask = 0x1,
 };
 
 PNAME(mux_pll_p)               = { "clk_24m", "xin24m" };
@@ -625,6 +628,7 @@ static const char *const rk3228_critical_clocks[] __initconst = {
 
 static void __init rk3228_clk_init(struct device_node *np)
 {
+       struct rockchip_clk_provider *ctx;
        void __iomem *reg_base;
 
        reg_base = of_iomap(np, 0);
@@ -633,17 +637,22 @@ static void __init rk3228_clk_init(struct device_node *np)
                return;
        }
 
-       rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(reg_base);
+               return;
+       }
 
-       rockchip_clk_register_plls(rk3228_pll_clks,
+       rockchip_clk_register_plls(ctx, rk3228_pll_clks,
                                   ARRAY_SIZE(rk3228_pll_clks),
                                   RK3228_GRF_SOC_STATUS0);
-       rockchip_clk_register_branches(rk3228_clk_branches,
+       rockchip_clk_register_branches(ctx, rk3228_clk_branches,
                                  ARRAY_SIZE(rk3228_clk_branches));
        rockchip_clk_protect_critical(rk3228_critical_clocks,
                                      ARRAY_SIZE(rk3228_critical_clocks));
 
-       rockchip_clk_register_armclk(ARMCLK, "armclk",
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
                        mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
                        &rk3228_cpuclk_data, rk3228_cpuclk_rates,
                        ARRAY_SIZE(rk3228_cpuclk_rates));
@@ -651,6 +660,8 @@ static void __init rk3228_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL);
+       rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, NULL);
+
+       rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
index 3cb72163a5122ba9ef7695f0c5ba5d679afa9bd7..39af05a589b3c59a25902e83bf660ce7d409b7ca 100644 (file)
@@ -165,7 +165,10 @@ static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {
        .core_reg = RK3288_CLKSEL_CON(0),
        .div_core_shift = 8,
        .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .mux_core_shift = 15,
+       .mux_core_mask = 0x1,
 };
 
 PNAME(mux_pll_p)               = { "xin24m", "xin32k" };
@@ -878,6 +881,7 @@ static struct syscore_ops rk3288_clk_syscore_ops = {
 
 static void __init rk3288_clk_init(struct device_node *np)
 {
+       struct rockchip_clk_provider *ctx;
        struct clk *clk;
 
        rk3288_cru_base = of_iomap(np, 0);
@@ -886,7 +890,12 @@ static void __init rk3288_clk_init(struct device_node *np)
                return;
        }
 
-       rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
+       ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(rk3288_cru_base);
+               return;
+       }
 
        /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
        clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
@@ -894,17 +903,17 @@ static void __init rk3288_clk_init(struct device_node *np)
                pr_warn("%s: could not register clock pclk_wdt: %ld\n",
                        __func__, PTR_ERR(clk));
        else
-               rockchip_clk_add_lookup(clk, PCLK_WDT);
+               rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
 
-       rockchip_clk_register_plls(rk3288_pll_clks,
+       rockchip_clk_register_plls(ctx, rk3288_pll_clks,
                                   ARRAY_SIZE(rk3288_pll_clks),
                                   RK3288_GRF_SOC_STATUS1);
-       rockchip_clk_register_branches(rk3288_clk_branches,
+       rockchip_clk_register_branches(ctx, rk3288_clk_branches,
                                  ARRAY_SIZE(rk3288_clk_branches));
        rockchip_clk_protect_critical(rk3288_critical_clocks,
                                      ARRAY_SIZE(rk3288_critical_clocks));
 
-       rockchip_clk_register_armclk(ARMCLK, "armclk",
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
                        mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
                        &rk3288_cpuclk_data, rk3288_cpuclk_rates,
                        ARRAY_SIZE(rk3288_cpuclk_rates));
@@ -913,8 +922,10 @@ static void __init rk3288_clk_init(struct device_node *np)
                                  rk3288_cru_base + RK3288_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK3288_GLB_SRST_FST,
+       rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST,
                                           rk3288_clk_shutdown);
        register_syscore_ops(&rk3288_clk_syscore_ops);
+
+       rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
index a2bb12200465cf34483eeaa0045b517e63747d17..6cb474c593e7b111fa9da58e93bce5412b586422 100644 (file)
@@ -165,14 +165,20 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = {
        .core_reg = RK3368_CLKSEL_CON(0),
        .div_core_shift = 0,
        .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .mux_core_shift = 7,
+       .mux_core_mask = 0x1,
 };
 
 static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = {
        .core_reg = RK3368_CLKSEL_CON(2),
        .div_core_shift = 0,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
        .div_core_mask = 0x1f,
        .mux_core_shift = 7,
+       .mux_core_mask = 0x1,
 };
 
 #define RK3368_DIV_ACLKM_MASK          0x1f
@@ -856,6 +862,7 @@ static const char *const rk3368_critical_clocks[] __initconst = {
 
 static void __init rk3368_clk_init(struct device_node *np)
 {
+       struct rockchip_clk_provider *ctx;
        void __iomem *reg_base;
        struct clk *clk;
 
@@ -865,7 +872,12 @@ static void __init rk3368_clk_init(struct device_node *np)
                return;
        }
 
-       rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(reg_base);
+               return;
+       }
 
        /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */
        clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
@@ -873,22 +885,22 @@ static void __init rk3368_clk_init(struct device_node *np)
                pr_warn("%s: could not register clock pclk_wdt: %ld\n",
                        __func__, PTR_ERR(clk));
        else
-               rockchip_clk_add_lookup(clk, PCLK_WDT);
+               rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
 
-       rockchip_clk_register_plls(rk3368_pll_clks,
+       rockchip_clk_register_plls(ctx, rk3368_pll_clks,
                                   ARRAY_SIZE(rk3368_pll_clks),
                                   RK3368_GRF_SOC_STATUS0);
-       rockchip_clk_register_branches(rk3368_clk_branches,
+       rockchip_clk_register_branches(ctx, rk3368_clk_branches,
                                  ARRAY_SIZE(rk3368_clk_branches));
        rockchip_clk_protect_critical(rk3368_critical_clocks,
                                      ARRAY_SIZE(rk3368_critical_clocks));
 
-       rockchip_clk_register_armclk(ARMCLKB, "armclkb",
+       rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb",
                        mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
                        &rk3368_cpuclkb_data, rk3368_cpuclkb_rates,
                        ARRAY_SIZE(rk3368_cpuclkb_rates));
 
-       rockchip_clk_register_armclk(ARMCLKL, "armclkl",
+       rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl",
                        mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
                        &rk3368_cpuclkl_data, rk3368_cpuclkl_rates,
                        ARRAY_SIZE(rk3368_cpuclkl_rates));
@@ -896,6 +908,8 @@ static void __init rk3368_clk_init(struct device_node *np)
        rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
-       rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL);
+       rockchip_register_restart_notifier(ctx, RK3368_GLB_SRST_FST, NULL);
+
+       rockchip_clk_of_add_provider(np, ctx);
 }
 CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
new file mode 100644 (file)
index 0000000..5248726
--- /dev/null
@@ -0,0 +1,1573 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <dt-bindings/clock/rk3399-cru.h>
+#include "clk.h"
+
+enum rk3399_plls {
+       lpll, bpll, dpll, cpll, gpll, npll, vpll,
+};
+
+enum rk3399_pmu_plls {
+       ppll,
+};
+
+static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
+       /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+       RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2136000000, 1, 89, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2112000000, 1, 88, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0),
+       RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1968000000, 1, 82, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1944000000, 1, 81, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1872000000, 1, 78, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1848000000, 1, 77, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1824000000, 1, 76, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1776000000, 1, 74, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1752000000, 1, 73, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1728000000, 1, 72, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1680000000, 1, 70, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 676000000, 3, 169, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
+       RK3036_PLL_RATE( 594000000, 1, 99, 4, 1, 1, 0),
+       RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
+       RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
+       RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
+       RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
+       RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0),
+       RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
+       RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0),
+       RK3036_PLL_RATE(  96000000, 1, 64, 4, 4, 1, 0),
+       RK3036_PLL_RATE(  74250000, 2, 99, 4, 4, 1, 0),
+       RK3036_PLL_RATE(  54000000, 1, 54, 6, 4, 1, 0),
+       RK3036_PLL_RATE(  27000000, 1, 27, 6, 4, 1, 0),
+       { /* sentinel */ },
+};
+
+/* CRU parents */
+PNAME(mux_pll_p)                               = { "xin24m", "xin32k" };
+
+PNAME(mux_armclkl_p)                           = { "clk_core_l_lpll_src",
+                                                   "clk_core_l_bpll_src",
+                                                   "clk_core_l_dpll_src",
+                                                   "clk_core_l_gpll_src" };
+PNAME(mux_armclkb_p)                           = { "clk_core_b_lpll_src",
+                                                   "clk_core_b_bpll_src",
+                                                   "clk_core_b_dpll_src",
+                                                   "clk_core_b_gpll_src" };
+PNAME(mux_aclk_cci_p)                          = { "cpll_aclk_cci_src",
+                                                   "gpll_aclk_cci_src",
+                                                   "npll_aclk_cci_src",
+                                                   "vpll_aclk_cci_src" };
+PNAME(mux_cci_trace_p)                         = { "cpll_cci_trace",
+                                                   "gpll_cci_trace" };
+PNAME(mux_cs_p)                                        = { "cpll_cs", "gpll_cs",
+                                                   "npll_cs"};
+PNAME(mux_aclk_perihp_p)                       = { "cpll_aclk_perihp_src",
+                                                   "gpll_aclk_perihp_src" };
+
+PNAME(mux_pll_src_cpll_gpll_p)                 = { "cpll", "gpll" };
+PNAME(mux_pll_src_cpll_gpll_npll_p)            = { "cpll", "gpll", "npll" };
+PNAME(mux_pll_src_cpll_gpll_ppll_p)            = { "cpll", "gpll", "ppll" };
+PNAME(mux_pll_src_cpll_gpll_upll_p)            = { "cpll", "gpll", "upll" };
+PNAME(mux_pll_src_npll_cpll_gpll_p)            = { "npll", "cpll", "gpll" };
+PNAME(mux_pll_src_cpll_gpll_npll_ppll_p)       = { "cpll", "gpll", "npll",
+                                                   "ppll" };
+PNAME(mux_pll_src_cpll_gpll_npll_24m_p)                = { "cpll", "gpll", "npll",
+                                                   "xin24m" };
+PNAME(mux_pll_src_cpll_gpll_npll_usbphy480m_p) = { "cpll", "gpll", "npll",
+                                                   "clk_usbphy_480m" };
+PNAME(mux_pll_src_ppll_cpll_gpll_npll_p)       = { "ppll", "cpll", "gpll",
+                                                   "npll", "upll" };
+PNAME(mux_pll_src_cpll_gpll_npll_upll_24m_p)   = { "cpll", "gpll", "npll",
+                                                   "upll", "xin24m" };
+PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "cpll", "gpll", "npll",
+                                                   "ppll", "upll", "xin24m" };
+
+PNAME(mux_pll_src_vpll_cpll_gpll_p)            = { "vpll", "cpll", "gpll" };
+PNAME(mux_pll_src_vpll_cpll_gpll_npll_p)       = { "vpll", "cpll", "gpll",
+                                                   "npll" };
+PNAME(mux_pll_src_vpll_cpll_gpll_24m_p)                = { "vpll", "cpll", "gpll",
+                                                   "xin24m" };
+
+PNAME(mux_dclk_vop0_p)                 = { "dclk_vop0_div",
+                                           "dclk_vop0_frac" };
+PNAME(mux_dclk_vop1_p)                 = { "dclk_vop1_div",
+                                           "dclk_vop1_frac" };
+
+PNAME(mux_clk_cif_p)                   = { "clk_cifout_src", "xin24m" };
+
+PNAME(mux_pll_src_24m_usbphy480m_p)    = { "xin24m", "clk_usbphy_480m" };
+PNAME(mux_pll_src_24m_pciephy_p)       = { "xin24m", "clk_pciephy_ref100m" };
+PNAME(mux_pll_src_24m_32k_cpll_gpll_p) = { "xin24m", "xin32k",
+                                           "cpll", "gpll" };
+PNAME(mux_pciecore_cru_phy_p)          = { "clk_pcie_core_cru",
+                                           "clk_pcie_core_phy" };
+
+PNAME(mux_aclk_emmc_p)                 = { "cpll_aclk_emmc_src",
+                                           "gpll_aclk_emmc_src" };
+
+PNAME(mux_aclk_perilp0_p)              = { "cpll_aclk_perilp0_src",
+                                           "gpll_aclk_perilp0_src" };
+
+PNAME(mux_fclk_cm0s_p)                 = { "cpll_fclk_cm0s_src",
+                                           "gpll_fclk_cm0s_src" };
+
+PNAME(mux_hclk_perilp1_p)              = { "cpll_hclk_perilp1_src",
+                                           "gpll_hclk_perilp1_src" };
+
+PNAME(mux_clk_testout1_p)              = { "clk_testout1_pll_src", "xin24m" };
+PNAME(mux_clk_testout2_p)              = { "clk_testout2_pll_src", "xin24m" };
+
+PNAME(mux_usbphy_480m_p)               = { "clk_usbphy0_480m_src",
+                                           "clk_usbphy1_480m_src" };
+PNAME(mux_aclk_gmac_p)                 = { "cpll_aclk_gmac_src",
+                                           "gpll_aclk_gmac_src" };
+PNAME(mux_rmii_p)                      = { "clk_gmac", "clkin_gmac" };
+PNAME(mux_spdif_p)                     = { "clk_spdif_div", "clk_spdif_frac",
+                                           "clkin_i2s", "xin12m" };
+PNAME(mux_i2s0_p)                      = { "clk_i2s0_div", "clk_i2s0_frac",
+                                           "clkin_i2s", "xin12m" };
+PNAME(mux_i2s1_p)                      = { "clk_i2s1_div", "clk_i2s1_frac",
+                                           "clkin_i2s", "xin12m" };
+PNAME(mux_i2s2_p)                      = { "clk_i2s2_div", "clk_i2s2_frac",
+                                           "clkin_i2s", "xin12m" };
+PNAME(mux_i2sch_p)                     = { "clk_i2s0", "clk_i2s1",
+                                           "clk_i2s2" };
+PNAME(mux_i2sout_p)                    = { "clk_i2sout_src", "xin12m" };
+
+PNAME(mux_uart0_p)     = { "clk_uart0_div", "clk_uart0_frac", "xin24m" };
+PNAME(mux_uart1_p)     = { "clk_uart1_div", "clk_uart1_frac", "xin24m" };
+PNAME(mux_uart2_p)     = { "clk_uart2_div", "clk_uart2_frac", "xin24m" };
+PNAME(mux_uart3_p)     = { "clk_uart3_div", "clk_uart3_frac", "xin24m" };
+
+/* PMU CRU parents */
+PNAME(mux_ppll_24m_p)          = { "ppll", "xin24m" };
+PNAME(mux_24m_ppll_p)          = { "xin24m", "ppll" };
+PNAME(mux_fclk_cm0s_pmu_ppll_p)        = { "fclk_cm0s_pmu_ppll_src", "xin24m" };
+PNAME(mux_wifi_pmu_p)          = { "clk_wifi_div", "clk_wifi_frac" };
+PNAME(mux_uart4_pmu_p)         = { "clk_uart4_div", "clk_uart4_frac",
+                                   "xin24m" };
+PNAME(mux_clk_testout2_2io_p)  = { "clk_testout2", "clk_32k_suspend_pmu" };
+
+static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = {
+       [lpll] = PLL(pll_rk3399, PLL_APLLL, "lpll", mux_pll_p, 0, RK3399_PLL_CON(0),
+                    RK3399_PLL_CON(3), 8, 31, 0, rk3399_pll_rates),
+       [bpll] = PLL(pll_rk3399, PLL_APLLB, "bpll", mux_pll_p, 0, RK3399_PLL_CON(8),
+                    RK3399_PLL_CON(11), 8, 31, 0, rk3399_pll_rates),
+       [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RK3399_PLL_CON(16),
+                    RK3399_PLL_CON(19), 8, 31, 0, NULL),
+       [cpll] = PLL(pll_rk3399, PLL_CPLL, "cpll", mux_pll_p, 0, RK3399_PLL_CON(24),
+                    RK3399_PLL_CON(27), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
+       [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RK3399_PLL_CON(32),
+                    RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
+       [npll] = PLL(pll_rk3399, PLL_NPLL, "npll",  mux_pll_p, 0, RK3399_PLL_CON(40),
+                    RK3399_PLL_CON(43), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
+       [vpll] = PLL(pll_rk3399, PLL_VPLL, "vpll",  mux_pll_p, 0, RK3399_PLL_CON(48),
+                    RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
+};
+
+static struct rockchip_pll_clock rk3399_pmu_pll_clks[] __initdata = {
+       [ppll] = PLL(pll_rk3399, PLL_PPLL, "ppll",  mux_pll_p, 0, RK3399_PMU_PLL_CON(0),
+                    RK3399_PMU_PLL_CON(3), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+#define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK
+
+static struct rockchip_clk_branch rk3399_spdif_fracmux __initdata =
+       MUX(0, "clk_spdif_mux", mux_spdif_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(32), 13, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_i2s0_fracmux __initdata =
+       MUX(0, "clk_i2s0_mux", mux_i2s0_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(28), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_i2s1_fracmux __initdata =
+       MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(29), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_i2s2_fracmux __initdata =
+       MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(30), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_uart0_fracmux __initdata =
+       MUX(SCLK_UART0, "clk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(33), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_uart1_fracmux __initdata =
+       MUX(SCLK_UART1, "clk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(34), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_uart2_fracmux __initdata =
+       MUX(SCLK_UART2, "clk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(35), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_uart3_fracmux __initdata =
+       MUX(SCLK_UART3, "clk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(36), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_uart4_pmu_fracmux __initdata =
+       MUX(SCLK_UART4_PMU, "clk_uart4_pmu", mux_uart4_pmu_p, CLK_SET_RATE_PARENT,
+                       RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_dclk_vop0_fracmux __initdata =
+       MUX(DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(49), 11, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_dclk_vop1_fracmux __initdata =
+       MUX(DCLK_VOP1, "dclk_vop1", mux_dclk_vop1_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(50), 11, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata =
+       MUX(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT,
+                       RK3399_PMU_CLKSEL_CON(1), 14, 1, MFLAGS);
+
+static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = {
+       .core_reg = RK3399_CLKSEL_CON(0),
+       .div_core_shift = 0,
+       .div_core_mask = 0x1f,
+       .mux_core_alt = 3,
+       .mux_core_main = 0,
+       .mux_core_shift = 6,
+       .mux_core_mask = 0x3,
+};
+
+static const struct rockchip_cpuclk_reg_data rk3399_cpuclkb_data = {
+       .core_reg = RK3399_CLKSEL_CON(2),
+       .div_core_shift = 0,
+       .div_core_mask = 0x1f,
+       .mux_core_alt = 3,
+       .mux_core_main = 1,
+       .mux_core_shift = 6,
+       .mux_core_mask = 0x3,
+};
+
+#define RK3399_DIV_ACLKM_MASK          0x1f
+#define RK3399_DIV_ACLKM_SHIFT         8
+#define RK3399_DIV_ATCLK_MASK          0x1f
+#define RK3399_DIV_ATCLK_SHIFT         0
+#define RK3399_DIV_PCLK_DBG_MASK       0x1f
+#define RK3399_DIV_PCLK_DBG_SHIFT      8
+
+#define RK3399_CLKSEL0(_offs, _aclkm)                                  \
+       {                                                               \
+               .reg = RK3399_CLKSEL_CON(0 + _offs),                    \
+               .val = HIWORD_UPDATE(_aclkm, RK3399_DIV_ACLKM_MASK,     \
+                               RK3399_DIV_ACLKM_SHIFT),                \
+       }
+#define RK3399_CLKSEL1(_offs, _atclk, _pdbg)                           \
+       {                                                               \
+               .reg = RK3399_CLKSEL_CON(1 + _offs),                    \
+               .val = HIWORD_UPDATE(_atclk, RK3399_DIV_ATCLK_MASK,     \
+                               RK3399_DIV_ATCLK_SHIFT) |               \
+                      HIWORD_UPDATE(_pdbg, RK3399_DIV_PCLK_DBG_MASK,   \
+                               RK3399_DIV_PCLK_DBG_SHIFT),             \
+       }
+
+/* cluster_l: aclkm in clksel0, rest in clksel1 */
+#define RK3399_CPUCLKL_RATE(_prate, _aclkm, _atclk, _pdbg)             \
+       {                                                               \
+               .prate = _prate##U,                                     \
+               .divs = {                                               \
+                       RK3399_CLKSEL0(0, _aclkm),                      \
+                       RK3399_CLKSEL1(0, _atclk, _pdbg),               \
+               },                                                      \
+       }
+
+/* cluster_b: aclkm in clksel2, rest in clksel3 */
+#define RK3399_CPUCLKB_RATE(_prate, _aclkm, _atclk, _pdbg)             \
+       {                                                               \
+               .prate = _prate##U,                                     \
+               .divs = {                                               \
+                       RK3399_CLKSEL0(2, _aclkm),                      \
+                       RK3399_CLKSEL1(2, _atclk, _pdbg),               \
+               },                                                      \
+       }
+
+static struct rockchip_cpuclk_rate_table rk3399_cpuclkl_rates[] __initdata = {
+       RK3399_CPUCLKL_RATE(1800000000, 1, 8, 8),
+       RK3399_CPUCLKL_RATE(1704000000, 1, 8, 8),
+       RK3399_CPUCLKL_RATE(1608000000, 1, 7, 7),
+       RK3399_CPUCLKL_RATE(1512000000, 1, 7, 7),
+       RK3399_CPUCLKL_RATE(1488000000, 1, 6, 6),
+       RK3399_CPUCLKL_RATE(1416000000, 1, 6, 6),
+       RK3399_CPUCLKL_RATE(1200000000, 1, 5, 5),
+       RK3399_CPUCLKL_RATE(1008000000, 1, 5, 5),
+       RK3399_CPUCLKL_RATE( 816000000, 1, 4, 4),
+       RK3399_CPUCLKL_RATE( 696000000, 1, 3, 3),
+       RK3399_CPUCLKL_RATE( 600000000, 1, 3, 3),
+       RK3399_CPUCLKL_RATE( 408000000, 1, 2, 2),
+       RK3399_CPUCLKL_RATE( 312000000, 1, 1, 1),
+       RK3399_CPUCLKL_RATE( 216000000, 1, 1, 1),
+       RK3399_CPUCLKL_RATE(  96000000, 1, 1, 1),
+};
+
+static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = {
+       RK3399_CPUCLKB_RATE(2208000000, 1, 11, 11),
+       RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11),
+       RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10),
+       RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10),
+       RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9),
+       RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9),
+       RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8),
+       RK3399_CPUCLKB_RATE(1704000000, 1, 8, 8),
+       RK3399_CPUCLKB_RATE(1608000000, 1, 7, 7),
+       RK3399_CPUCLKB_RATE(1512000000, 1, 7, 7),
+       RK3399_CPUCLKB_RATE(1488000000, 1, 6, 6),
+       RK3399_CPUCLKB_RATE(1416000000, 1, 6, 6),
+       RK3399_CPUCLKB_RATE(1200000000, 1, 5, 5),
+       RK3399_CPUCLKB_RATE(1008000000, 1, 5, 5),
+       RK3399_CPUCLKB_RATE( 816000000, 1, 4, 4),
+       RK3399_CPUCLKB_RATE( 696000000, 1, 3, 3),
+       RK3399_CPUCLKB_RATE( 600000000, 1, 3, 3),
+       RK3399_CPUCLKB_RATE( 408000000, 1, 2, 2),
+       RK3399_CPUCLKB_RATE( 312000000, 1, 1, 1),
+       RK3399_CPUCLKB_RATE( 216000000, 1, 1, 1),
+       RK3399_CPUCLKB_RATE(  96000000, 1, 1, 1),
+};
+
+static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
+       /*
+        * CRU Clock-Architecture
+        */
+
+       /* usbphy */
+       GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 5, GFLAGS),
+       GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 6, GFLAGS),
+
+       GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(13), 12, GFLAGS),
+       GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(13), 12, GFLAGS),
+       MUX(0, "clk_usbphy_480m", mux_usbphy_480m_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(14), 6, 1, MFLAGS),
+
+       MUX(0, "upll", mux_pll_src_24m_usbphy480m_p, 0,
+                       RK3399_CLKSEL_CON(14), 15, 1, MFLAGS),
+
+       COMPOSITE_NODIV(SCLK_HSICPHY, "clk_hsicphy", mux_pll_src_cpll_gpll_npll_usbphy480m_p, 0,
+                       RK3399_CLKSEL_CON(19), 0, 2, MFLAGS,
+                       RK3399_CLKGATE_CON(6), 4, GFLAGS),
+
+       COMPOSITE(ACLK_USB3, "aclk_usb3", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 0, GFLAGS),
+       GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(30), 0, GFLAGS),
+       GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb3", 0,
+                       RK3399_CLKGATE_CON(30), 1, GFLAGS),
+       GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb3", 0,
+                       RK3399_CLKGATE_CON(30), 2, GFLAGS),
+       GATE(ACLK_USB3_RKSOC_AXI_PERF, "aclk_usb3_rksoc_axi_perf", "aclk_usb3", 0,
+                       RK3399_CLKGATE_CON(30), 3, GFLAGS),
+       GATE(ACLK_USB3_GRF, "aclk_usb3_grf", "aclk_usb3", 0,
+                       RK3399_CLKGATE_CON(30), 4, GFLAGS),
+
+       GATE(SCLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0,
+                       RK3399_CLKGATE_CON(12), 1, GFLAGS),
+       GATE(SCLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0,
+                       RK3399_CLKGATE_CON(12), 2, GFLAGS),
+
+       COMPOSITE(SCLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", mux_pll_p, 0,
+                       RK3399_CLKSEL_CON(40), 15, 1, MFLAGS, 0, 10, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 3, GFLAGS),
+
+       COMPOSITE(SCLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", mux_pll_p, 0,
+                       RK3399_CLKSEL_CON(41), 15, 1, MFLAGS, 0, 10, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 4, GFLAGS),
+
+       COMPOSITE(SCLK_UPHY0_TCPDPHY_REF, "clk_uphy0_tcpdphy_ref", mux_pll_p, 0,
+                       RK3399_CLKSEL_CON(64), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 4, GFLAGS),
+
+       COMPOSITE(SCLK_UPHY0_TCPDCORE, "clk_uphy0_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(64), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 5, GFLAGS),
+
+       COMPOSITE(SCLK_UPHY1_TCPDPHY_REF, "clk_uphy1_tcpdphy_ref", mux_pll_p, 0,
+                       RK3399_CLKSEL_CON(65), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 6, GFLAGS),
+
+       COMPOSITE(SCLK_UPHY1_TCPDCORE, "clk_uphy1_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(65), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 7, GFLAGS),
+
+       /* little core */
+       GATE(0, "clk_core_l_lpll_src", "lpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(0), 0, GFLAGS),
+       GATE(0, "clk_core_l_bpll_src", "bpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(0), 1, GFLAGS),
+       GATE(0, "clk_core_l_dpll_src", "dpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(0), 2, GFLAGS),
+       GATE(0, "clk_core_l_gpll_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(0), 3, GFLAGS),
+
+       COMPOSITE_NOMUX(0, "aclkm_core_l", "armclkl", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(0), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK3399_CLKGATE_CON(0), 4, GFLAGS),
+       COMPOSITE_NOMUX(0, "atclk_core_l", "armclkl", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(1), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK3399_CLKGATE_CON(0), 5, GFLAGS),
+       COMPOSITE_NOMUX(0, "pclk_dbg_core_l", "armclkl", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(1), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK3399_CLKGATE_CON(0), 6, GFLAGS),
+
+       GATE(ACLK_CORE_ADB400_CORE_L_2_CCI500, "aclk_core_adb400_core_l_2_cci500", "aclkm_core_l", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 12, GFLAGS),
+       GATE(ACLK_PERF_CORE_L, "aclk_perf_core_l", "aclkm_core_l", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 13, GFLAGS),
+
+       GATE(0, "clk_dbg_pd_core_l", "armclkl", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 9, GFLAGS),
+       GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_core_adb400_gic_2_core_l", "armclkl", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 10, GFLAGS),
+       GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_core_adb400_core_l_2_gic", "armclkl", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 11, GFLAGS),
+       GATE(SCLK_PVTM_CORE_L, "clk_pvtm_core_l", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(0), 7, GFLAGS),
+
+       /* big core */
+       GATE(0, "clk_core_b_lpll_src", "lpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(1), 0, GFLAGS),
+       GATE(0, "clk_core_b_bpll_src", "bpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(1), 1, GFLAGS),
+       GATE(0, "clk_core_b_dpll_src", "dpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(1), 2, GFLAGS),
+       GATE(0, "clk_core_b_gpll_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(1), 3, GFLAGS),
+
+       COMPOSITE_NOMUX(0, "aclkm_core_b", "armclkb", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(2), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK3399_CLKGATE_CON(1), 4, GFLAGS),
+       COMPOSITE_NOMUX(0, "atclk_core_b", "armclkb", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK3399_CLKGATE_CON(1), 5, GFLAGS),
+       COMPOSITE_NOMUX(0, "pclk_dbg_core_b", "armclkb", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK3399_CLKGATE_CON(1), 6, GFLAGS),
+
+       GATE(ACLK_CORE_ADB400_CORE_B_2_CCI500, "aclk_core_adb400_core_b_2_cci500", "aclkm_core_b", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 5, GFLAGS),
+       GATE(ACLK_PERF_CORE_B, "aclk_perf_core_b", "aclkm_core_b", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 6, GFLAGS),
+
+       GATE(0, "clk_dbg_pd_core_b", "armclkb", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 1, GFLAGS),
+       GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_core_adb400_gic_2_core_b", "armclkb", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 3, GFLAGS),
+       GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_core_adb400_core_b_2_gic", "armclkb", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 4, GFLAGS),
+
+       DIV(0, "pclken_dbg_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(3), 13, 2, DFLAGS | CLK_DIVIDER_READ_ONLY),
+
+       GATE(0, "pclk_dbg_cxcs_pd_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(14), 2, GFLAGS),
+
+       GATE(SCLK_PVTM_CORE_B, "clk_pvtm_core_b", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(1), 7, GFLAGS),
+
+       /* gmac */
+       GATE(0, "cpll_aclk_gmac_src", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 9, GFLAGS),
+       GATE(0, "gpll_aclk_gmac_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 8, GFLAGS),
+       COMPOSITE(0, "aclk_gmac_pre", mux_aclk_gmac_p, 0,
+                       RK3399_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 10, GFLAGS),
+
+       GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", 0,
+                       RK3399_CLKGATE_CON(32), 0, GFLAGS),
+       GATE(ACLK_GMAC_NOC, "aclk_gmac_noc", "aclk_gmac_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(32), 1, GFLAGS),
+       GATE(ACLK_PERF_GMAC, "aclk_perf_gmac", "aclk_gmac_pre", 0,
+                       RK3399_CLKGATE_CON(32), 4, GFLAGS),
+
+       COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0,
+                       RK3399_CLKSEL_CON(19), 8, 3, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 11, GFLAGS),
+       GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", 0,
+                       RK3399_CLKGATE_CON(32), 2, GFLAGS),
+       GATE(PCLK_GMAC_NOC, "pclk_gmac_noc", "pclk_gmac_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(32), 3, GFLAGS),
+
+       COMPOSITE(SCLK_MAC, "clk_gmac", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(5), 5, GFLAGS),
+
+       MUX(SCLK_RMII_SRC, "clk_rmii_src", mux_rmii_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(19), 4, 1, MFLAGS),
+       GATE(SCLK_MACREF_OUT, "clk_mac_refout", "clk_rmii_src", 0,
+                       RK3399_CLKGATE_CON(5), 6, GFLAGS),
+       GATE(SCLK_MACREF, "clk_mac_ref", "clk_rmii_src", 0,
+                       RK3399_CLKGATE_CON(5), 7, GFLAGS),
+       GATE(SCLK_MAC_RX, "clk_rmii_rx", "clk_rmii_src", 0,
+                       RK3399_CLKGATE_CON(5), 8, GFLAGS),
+       GATE(SCLK_MAC_TX, "clk_rmii_tx", "clk_rmii_src", 0,
+                       RK3399_CLKGATE_CON(5), 9, GFLAGS),
+
+       /* spdif */
+       COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(8), 13, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(99), 0,
+                       RK3399_CLKGATE_CON(8), 14, GFLAGS,
+                       &rk3399_spdif_fracmux),
+       GATE(SCLK_SPDIF_8CH, "clk_spdif", "clk_spdif_mux", CLK_SET_RATE_PARENT,
+                       RK3399_CLKGATE_CON(8), 15, GFLAGS),
+
+       COMPOSITE(SCLK_SPDIF_REC_DPTX, "clk_spdif_rec_dptx", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 6, GFLAGS),
+       /* i2s */
+       COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(8), 3, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(96), 0,
+                       RK3399_CLKGATE_CON(8), 4, GFLAGS,
+                       &rk3399_i2s0_fracmux),
+       GATE(SCLK_I2S0_8CH, "clk_i2s0", "clk_i2s0_mux", CLK_SET_RATE_PARENT,
+                       RK3399_CLKGATE_CON(8), 5, GFLAGS),
+
+       COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(8), 6, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(97), 0,
+                       RK3399_CLKGATE_CON(8), 7, GFLAGS,
+                       &rk3399_i2s1_fracmux),
+       GATE(SCLK_I2S1_8CH, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT,
+                       RK3399_CLKGATE_CON(8), 8, GFLAGS),
+
+       COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(8), 9, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(98), 0,
+                       RK3399_CLKGATE_CON(8), 10, GFLAGS,
+                       &rk3399_i2s2_fracmux),
+       GATE(SCLK_I2S2_8CH, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT,
+                       RK3399_CLKGATE_CON(8), 11, GFLAGS),
+
+       MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(31), 0, 2, MFLAGS),
+       COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(30), 8, 2, MFLAGS,
+                       RK3399_CLKGATE_CON(8), 12, GFLAGS),
+
+       /* uart */
+       MUX(0, "clk_uart0_src", mux_pll_src_cpll_gpll_upll_p, 0,
+                       RK3399_CLKSEL_CON(33), 12, 2, MFLAGS),
+       COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0,
+                       RK3399_CLKSEL_CON(33), 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 0, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(100), 0,
+                       RK3399_CLKGATE_CON(9), 1, GFLAGS,
+                       &rk3399_uart0_fracmux),
+
+       MUX(0, "clk_uart_src", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(33), 15, 1, MFLAGS),
+       COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0,
+                       RK3399_CLKSEL_CON(34), 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 2, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(101), 0,
+                       RK3399_CLKGATE_CON(9), 3, GFLAGS,
+                       &rk3399_uart1_fracmux),
+
+       COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0,
+                       RK3399_CLKSEL_CON(35), 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 4, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(102), 0,
+                       RK3399_CLKGATE_CON(9), 5, GFLAGS,
+                       &rk3399_uart2_fracmux),
+
+       COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0,
+                       RK3399_CLKSEL_CON(36), 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 6, GFLAGS),
+       COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(103), 0,
+                       RK3399_CLKGATE_CON(9), 7, GFLAGS,
+                       &rk3399_uart3_fracmux),
+
+       COMPOSITE(0, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(6), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(3), 4, GFLAGS),
+
+       GATE(PCLK_CENTER_MAIN_NOC, "pclk_center_main_noc", "pclk_ddr", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(18), 10, GFLAGS),
+       GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(18), 12, GFLAGS),
+       GATE(PCLK_CIC, "pclk_cic", "pclk_ddr", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(18), 15, GFLAGS),
+       GATE(PCLK_DDR_SGRF, "pclk_ddr_sgrf", "pclk_ddr", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(19), 2, GFLAGS),
+
+       GATE(SCLK_PVTM_DDR, "clk_pvtm_ddr", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(4), 11, GFLAGS),
+       GATE(SCLK_DFIMON0_TIMER, "clk_dfimon0_timer", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(3), 5, GFLAGS),
+       GATE(SCLK_DFIMON1_TIMER, "clk_dfimon1_timer", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(3), 6, GFLAGS),
+
+       /* cci */
+       GATE(0, "cpll_aclk_cci_src", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(0, "gpll_aclk_cci_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 1, GFLAGS),
+       GATE(0, "npll_aclk_cci_src", "npll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 2, GFLAGS),
+       GATE(0, "vpll_aclk_cci_src", "vpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 3, GFLAGS),
+
+       COMPOSITE(0, "aclk_cci_pre", mux_aclk_cci_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(2), 4, GFLAGS),
+
+       GATE(ACLK_ADB400M_PD_CORE_L, "aclk_adb400m_pd_core_l", "aclk_cci_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 0, GFLAGS),
+       GATE(ACLK_ADB400M_PD_CORE_B, "aclk_adb400m_pd_core_b", "aclk_cci_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 1, GFLAGS),
+       GATE(ACLK_CCI, "aclk_cci", "aclk_cci_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 2, GFLAGS),
+       GATE(ACLK_CCI_NOC0, "aclk_cci_noc0", "aclk_cci_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 3, GFLAGS),
+       GATE(ACLK_CCI_NOC1, "aclk_cci_noc1", "aclk_cci_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 4, GFLAGS),
+       GATE(ACLK_CCI_GRF, "aclk_cci_grf", "aclk_cci_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 7, GFLAGS),
+
+       GATE(0, "cpll_cci_trace", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 5, GFLAGS),
+       GATE(0, "gpll_cci_trace", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 6, GFLAGS),
+       COMPOSITE(SCLK_CCI_TRACE, "clk_cci_trace", mux_cci_trace_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(2), 7, GFLAGS),
+
+       GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 8, GFLAGS),
+       GATE(0, "gpll_cs", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 9, GFLAGS),
+       GATE(0, "npll_cs", "npll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(2), 10, GFLAGS),
+       COMPOSITE_NOGATE(0, "clk_cs", mux_cs_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS),
+       GATE(0, "clk_dbg_cxcs", "clk_cs", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 5, GFLAGS),
+       GATE(0, "clk_dbg_noc", "clk_cs", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(15), 6, GFLAGS),
+
+       /* vcodec */
+       COMPOSITE(0, "aclk_vcodec_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(7), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 0, GFLAGS),
+       COMPOSITE_NOMUX(0, "hclk_vcodec_pre", "aclk_vcodec_pre", 0,
+                       RK3399_CLKSEL_CON(7), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 1, GFLAGS),
+       GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0,
+                       RK3399_CLKGATE_CON(17), 2, GFLAGS),
+       GATE(0, "hclk_vcodec_noc", "hclk_vcodec_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(17), 3, GFLAGS),
+
+       GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
+                       RK3399_CLKGATE_CON(17), 0, GFLAGS),
+       GATE(0, "aclk_vcodec_noc", "aclk_vcodec_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(17), 1, GFLAGS),
+
+       /* vdu */
+       COMPOSITE(SCLK_VDU_CORE, "clk_vdu_core", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 4, GFLAGS),
+       COMPOSITE(SCLK_VDU_CA, "clk_vdu_ca", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(9), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 5, GFLAGS),
+
+       COMPOSITE(0, "aclk_vdu_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(8), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 2, GFLAGS),
+       COMPOSITE_NOMUX(0, "hclk_vdu_pre", "aclk_vdu_pre", 0,
+                       RK3399_CLKSEL_CON(8), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 3, GFLAGS),
+       GATE(HCLK_VDU, "hclk_vdu", "hclk_vdu_pre", 0,
+                       RK3399_CLKGATE_CON(17), 10, GFLAGS),
+       GATE(HCLK_VDU_NOC, "hclk_vdu_noc", "hclk_vdu_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(17), 11, GFLAGS),
+
+       GATE(ACLK_VDU, "aclk_vdu", "aclk_vdu_pre", 0,
+                       RK3399_CLKGATE_CON(17), 8, GFLAGS),
+       GATE(ACLK_VDU_NOC, "aclk_vdu_noc", "aclk_vdu_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(17), 9, GFLAGS),
+
+       /* iep */
+       COMPOSITE(0, "aclk_iep_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 6, GFLAGS),
+       COMPOSITE_NOMUX(0, "hclk_iep_pre", "aclk_iep_pre", 0,
+                       RK3399_CLKSEL_CON(10), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 7, GFLAGS),
+       GATE(HCLK_IEP, "hclk_iep", "hclk_iep_pre", 0,
+                       RK3399_CLKGATE_CON(16), 2, GFLAGS),
+       GATE(HCLK_IEP_NOC, "hclk_iep_noc", "hclk_iep_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(16), 3, GFLAGS),
+
+       GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0,
+                       RK3399_CLKGATE_CON(16), 0, GFLAGS),
+       GATE(ACLK_IEP_NOC, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(16), 1, GFLAGS),
+
+       /* rga */
+       COMPOSITE(SCLK_RGA_CORE, "clk_rga_core", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 10, GFLAGS),
+
+       COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 8, GFLAGS),
+       COMPOSITE_NOMUX(0, "hclk_rga_pre", "aclk_rga_pre", 0,
+                       RK3399_CLKSEL_CON(11), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(4), 9, GFLAGS),
+       GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0,
+                       RK3399_CLKGATE_CON(16), 10, GFLAGS),
+       GATE(HCLK_RGA_NOC, "hclk_rga_noc", "hclk_rga_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(16), 11, GFLAGS),
+
+       GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0,
+                       RK3399_CLKGATE_CON(16), 8, GFLAGS),
+       GATE(ACLK_RGA_NOC, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(16), 9, GFLAGS),
+
+       /* center */
+       COMPOSITE(0, "aclk_center", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(3), 7, GFLAGS),
+       GATE(ACLK_CENTER_MAIN_NOC, "aclk_center_main_noc", "aclk_center", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(19), 0, GFLAGS),
+       GATE(ACLK_CENTER_PERI_NOC, "aclk_center_peri_noc", "aclk_center", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(19), 1, GFLAGS),
+
+       /* gpu */
+       COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_ppll_cpll_gpll_npll_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 0, GFLAGS),
+       GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0,
+                       RK3399_CLKGATE_CON(30), 8, GFLAGS),
+       GATE(ACLK_PERF_GPU, "aclk_perf_gpu", "aclk_gpu_pre", 0,
+                       RK3399_CLKGATE_CON(30), 10, GFLAGS),
+       GATE(ACLK_GPU_GRF, "aclk_gpu_grf", "aclk_gpu_pre", 0,
+                       RK3399_CLKGATE_CON(30), 11, GFLAGS),
+       GATE(SCLK_PVTM_GPU, "aclk_pvtm_gpu", "xin24m", 0,
+                       RK3399_CLKGATE_CON(13), 1, GFLAGS),
+
+       /* perihp */
+       GATE(0, "cpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(5), 0, GFLAGS),
+       GATE(0, "gpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(5), 1, GFLAGS),
+       COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(5), 2, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_PERIHP, "hclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(14), 8, 2, DFLAGS,
+                       RK3399_CLKGATE_CON(5), 3, GFLAGS),
+       COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
+                       RK3399_CLKGATE_CON(5), 4, GFLAGS),
+
+       GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 2, GFLAGS),
+       GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 10, GFLAGS),
+       GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 12, GFLAGS),
+
+       GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0,
+                       RK3399_CLKGATE_CON(20), 5, GFLAGS),
+       GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0,
+                       RK3399_CLKGATE_CON(20), 6, GFLAGS),
+       GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", 0,
+                       RK3399_CLKGATE_CON(20), 7, GFLAGS),
+       GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", 0,
+                       RK3399_CLKGATE_CON(20), 8, GFLAGS),
+       GATE(HCLK_HSIC, "hclk_hsic", "hclk_perihp", 0,
+                       RK3399_CLKGATE_CON(20), 9, GFLAGS),
+       GATE(0, "hclk_perihp_noc", "hclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 13, GFLAGS),
+       GATE(0, "hclk_ahb1tom", "hclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 15, GFLAGS),
+
+       GATE(PCLK_PERIHP_GRF, "pclk_perihp_grf", "pclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 4, GFLAGS),
+       GATE(PCLK_PCIE, "pclk_pcie", "pclk_perihp", 0,
+                       RK3399_CLKGATE_CON(20), 11, GFLAGS),
+       GATE(0, "pclk_perihp_noc", "pclk_perihp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(20), 14, GFLAGS),
+       GATE(PCLK_HSICPHY, "pclk_hsicphy", "pclk_perihp", 0,
+                       RK3399_CLKGATE_CON(31), 8, GFLAGS),
+
+       /* sdio & sdmmc */
+       COMPOSITE(0, "hclk_sd", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(13), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 13, GFLAGS),
+       GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0,
+                       RK3399_CLKGATE_CON(33), 8, GFLAGS),
+       GATE(0, "hclk_sdmmc_noc", "hclk_sd", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(33), 9, GFLAGS),
+
+       COMPOSITE(SCLK_SDIO, "clk_sdio", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, 0,
+                       RK3399_CLKSEL_CON(15), 8, 3, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 0, GFLAGS),
+
+       COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, 0,
+                       RK3399_CLKSEL_CON(16), 8, 3, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 1, GFLAGS),
+
+       MMC(SCLK_SDMMC_DRV,     "emmc_drv",    "clk_sdmmc", RK3399_SDMMC_CON0, 1),
+       MMC(SCLK_SDMMC_SAMPLE,  "emmc_sample", "clk_sdmmc", RK3399_SDMMC_CON1, 1),
+
+       MMC(SCLK_SDIO_DRV,      "sdio_drv",    "clk_sdio",  RK3399_SDIO_CON0,  1),
+       MMC(SCLK_SDIO_SAMPLE,   "sdio_sample", "clk_sdio",  RK3399_SDIO_CON1,  1),
+
+       /* pcie */
+       COMPOSITE(SCLK_PCIE_PM, "clk_pcie_pm", mux_pll_src_cpll_gpll_npll_24m_p, 0,
+                       RK3399_CLKSEL_CON(17), 8, 3, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 2, GFLAGS),
+
+       COMPOSITE_NOMUX(SCLK_PCIEPHY_REF100M, "clk_pciephy_ref100m", "npll", 0,
+                       RK3399_CLKSEL_CON(18), 11, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 6, GFLAGS),
+       MUX(SCLK_PCIEPHY_REF, "clk_pciephy_ref", mux_pll_src_24m_pciephy_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(18), 10, 1, MFLAGS),
+
+       COMPOSITE(0, "clk_pcie_core_cru", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 3, GFLAGS),
+       MUX(SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(18), 7, 1, MFLAGS),
+
+       /* emmc */
+       COMPOSITE(SCLK_EMMC, "clk_emmc", mux_pll_src_cpll_gpll_npll_upll_24m_p, 0,
+                       RK3399_CLKSEL_CON(22), 8, 3, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(6), 14, GFLAGS),
+
+       GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 12, GFLAGS),
+       GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 13, GFLAGS),
+       COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS),
+       GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(32), 8, GFLAGS),
+       GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(32), 9, GFLAGS),
+       GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(32), 10, GFLAGS),
+
+       /* perilp0 */
+       GATE(0, "cpll_aclk_perilp0_src", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(7), 1, GFLAGS),
+       GATE(0, "gpll_aclk_perilp0_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(7), 0, GFLAGS),
+       COMPOSITE(ACLK_PERILP0, "aclk_perilp0", mux_aclk_perilp0_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(23), 7, 1, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(7), 2, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_PERILP0, "hclk_perilp0", "aclk_perilp0", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(23), 8, 2, DFLAGS,
+                       RK3399_CLKGATE_CON(7), 3, GFLAGS),
+       COMPOSITE_NOMUX(PCLK_PERILP0, "pclk_perilp0", "aclk_perilp0", 0,
+                       RK3399_CLKSEL_CON(23), 12, 3, DFLAGS,
+                       RK3399_CLKGATE_CON(7), 4, GFLAGS),
+
+       /* aclk_perilp0 gates */
+       GATE(ACLK_INTMEM, "aclk_intmem", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 0, GFLAGS),
+       GATE(ACLK_TZMA, "aclk_tzma", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 1, GFLAGS),
+       GATE(SCLK_INTMEM0, "clk_intmem0", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 2, GFLAGS),
+       GATE(SCLK_INTMEM1, "clk_intmem1", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 3, GFLAGS),
+       GATE(SCLK_INTMEM2, "clk_intmem2", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 4, GFLAGS),
+       GATE(SCLK_INTMEM3, "clk_intmem3", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 5, GFLAGS),
+       GATE(SCLK_INTMEM4, "clk_intmem4", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 6, GFLAGS),
+       GATE(SCLK_INTMEM5, "clk_intmem5", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 7, GFLAGS),
+       GATE(ACLK_DCF, "aclk_dcf", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 8, GFLAGS),
+       GATE(ACLK_DMAC0_PERILP, "aclk_dmac0_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 5, GFLAGS),
+       GATE(ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 6, GFLAGS),
+       GATE(ACLK_PERILP0_NOC, "aclk_perilp0_noc", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 7, GFLAGS),
+
+       /* hclk_perilp0 gates */
+       GATE(HCLK_ROM, "hclk_rom", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 4, GFLAGS),
+       GATE(HCLK_M_CRYPTO0, "hclk_m_crypto0", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 5, GFLAGS),
+       GATE(HCLK_S_CRYPTO0, "hclk_s_crypto0", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 6, GFLAGS),
+       GATE(HCLK_M_CRYPTO1, "hclk_m_crypto1", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 14, GFLAGS),
+       GATE(HCLK_S_CRYPTO1, "hclk_s_crypto1", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 15, GFLAGS),
+       GATE(HCLK_PERILP0_NOC, "hclk_perilp0_noc", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 8, GFLAGS),
+
+       /* pclk_perilp0 gates */
+       GATE(PCLK_DCF, "pclk_dcf", "pclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 9, GFLAGS),
+
+       /* crypto */
+       COMPOSITE(SCLK_CRYPTO0, "clk_crypto0", mux_pll_src_cpll_gpll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(24), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(7), 7, GFLAGS),
+
+       COMPOSITE(SCLK_CRYPTO1, "clk_crypto1", mux_pll_src_cpll_gpll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(26), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(7), 8, GFLAGS),
+
+       /* cm0s_perilp */
+       GATE(0, "cpll_fclk_cm0s_src", "cpll", 0,
+                       RK3399_CLKGATE_CON(7), 6, GFLAGS),
+       GATE(0, "gpll_fclk_cm0s_src", "gpll", 0,
+                       RK3399_CLKGATE_CON(7), 5, GFLAGS),
+       COMPOSITE(FCLK_CM0S, "fclk_cm0s", mux_fclk_cm0s_p, 0,
+                       RK3399_CLKSEL_CON(24), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(7), 9, GFLAGS),
+
+       /* fclk_cm0s gates */
+       GATE(SCLK_M0_PERILP, "sclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 8, GFLAGS),
+       GATE(HCLK_M0_PERILP, "hclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 9, GFLAGS),
+       GATE(DCLK_M0_PERILP, "dclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 10, GFLAGS),
+       GATE(SCLK_M0_PERILP_DEC, "clk_m0_perilp_dec", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 11, GFLAGS),
+       GATE(HCLK_M0_PERILP_NOC, "hclk_m0_perilp_noc", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 11, GFLAGS),
+
+       /* perilp1 */
+       GATE(0, "cpll_hclk_perilp1_src", "cpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(8), 1, GFLAGS),
+       GATE(0, "gpll_hclk_perilp1_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(8), 0, GFLAGS),
+       COMPOSITE_NOGATE(HCLK_PERILP1, "hclk_perilp1", mux_hclk_perilp1_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 5, DFLAGS),
+       COMPOSITE_NOMUX(PCLK_PERILP1, "pclk_perilp1", "hclk_perilp1", CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(25), 8, 3, DFLAGS,
+                       RK3399_CLKGATE_CON(8), 2, GFLAGS),
+
+       /* hclk_perilp1 gates */
+       GATE(0, "hclk_perilp1_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 9, GFLAGS),
+       GATE(0, "hclk_sdio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 12, GFLAGS),
+       GATE(HCLK_I2S0_8CH, "hclk_i2s0", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 0, GFLAGS),
+       GATE(HCLK_I2S1_8CH, "hclk_i2s1", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 1, GFLAGS),
+       GATE(HCLK_I2S2_8CH, "hclk_i2s2", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 2, GFLAGS),
+       GATE(HCLK_SPDIF, "hclk_spdif", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 3, GFLAGS),
+       GATE(HCLK_SDIO, "hclk_sdio", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 4, GFLAGS),
+       GATE(PCLK_SPI5, "pclk_spi5", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 5, GFLAGS),
+       GATE(0, "hclk_sdioaudio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 6, GFLAGS),
+
+       /* pclk_perilp1 gates */
+       GATE(PCLK_UART0, "pclk_uart0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 0, GFLAGS),
+       GATE(PCLK_UART1, "pclk_uart1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 1, GFLAGS),
+       GATE(PCLK_UART2, "pclk_uart2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 2, GFLAGS),
+       GATE(PCLK_UART3, "pclk_uart3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 3, GFLAGS),
+       GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 5, GFLAGS),
+       GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 6, GFLAGS),
+       GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 7, GFLAGS),
+       GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 8, GFLAGS),
+       GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 9, GFLAGS),
+       GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 10, GFLAGS),
+       GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 11, GFLAGS),
+       GATE(PCLK_SARADC, "pclk_saradc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 12, GFLAGS),
+       GATE(PCLK_TSADC, "pclk_tsadc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 13, GFLAGS),
+       GATE(PCLK_EFUSE1024NS, "pclk_efuse1024ns", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 14, GFLAGS),
+       GATE(PCLK_EFUSE1024S, "pclk_efuse1024s", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 15, GFLAGS),
+       GATE(PCLK_SPI0, "pclk_spi0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 10, GFLAGS),
+       GATE(PCLK_SPI1, "pclk_spi1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 11, GFLAGS),
+       GATE(PCLK_SPI2, "pclk_spi2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 12, GFLAGS),
+       GATE(PCLK_SPI4, "pclk_spi4", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 13, GFLAGS),
+       GATE(PCLK_PERIHP_GRF, "pclk_perilp_sgrf", "pclk_perilp1", 0, RK3399_CLKGATE_CON(24), 13, GFLAGS),
+       GATE(0, "pclk_perilp1_noc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(25), 10, GFLAGS),
+
+       /* saradc */
+       COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0,
+                       RK3399_CLKSEL_CON(26), 8, 8, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 11, GFLAGS),
+
+       /* tsadc */
+       COMPOSITE(SCLK_TSADC, "clk_tsadc", mux_pll_p, 0,
+                       RK3399_CLKSEL_CON(27), 15, 1, MFLAGS, 0, 10, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 10, GFLAGS),
+
+       /* cif_testout */
+       MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(38), 6, 2, MFLAGS),
+       COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0,
+                       RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 14, GFLAGS),
+
+       MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(38), 14, 2, MFLAGS),
+       COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0,
+                       RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 15, GFLAGS),
+
+       /* vio */
+       COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 10, GFLAGS),
+       COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0,
+                       RK3399_CLKSEL_CON(43), 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 1, GFLAGS),
+
+       GATE(ACLK_VIO_NOC, "aclk_vio_noc", "aclk_vio", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(29), 0, GFLAGS),
+
+       GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "pclk_vio", 0,
+                       RK3399_CLKGATE_CON(29), 1, GFLAGS),
+       GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "pclk_vio", 0,
+                       RK3399_CLKGATE_CON(29), 2, GFLAGS),
+       GATE(PCLK_VIO_GRF, "pclk_vio_grf", "pclk_vio", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(29), 12, GFLAGS),
+
+       /* hdcp */
+       COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 12, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_HDCP, "hclk_hdcp", "aclk_hdcp", 0,
+                       RK3399_CLKSEL_CON(43), 5, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 3, GFLAGS),
+       COMPOSITE_NOMUX(PCLK_HDCP, "pclk_hdcp", "aclk_hdcp", 0,
+                       RK3399_CLKSEL_CON(43), 10, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 10, GFLAGS),
+
+       GATE(ACLK_HDCP_NOC, "aclk_hdcp_noc", "aclk_hdcp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(29), 4, GFLAGS),
+       GATE(ACLK_HDCP22, "aclk_hdcp22", "aclk_hdcp", 0,
+                       RK3399_CLKGATE_CON(29), 10, GFLAGS),
+
+       GATE(HCLK_HDCP_NOC, "hclk_hdcp_noc", "hclk_hdcp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(29), 5, GFLAGS),
+       GATE(HCLK_HDCP22, "hclk_hdcp22", "hclk_hdcp", 0,
+                       RK3399_CLKGATE_CON(29), 9, GFLAGS),
+
+       GATE(PCLK_HDCP_NOC, "pclk_hdcp_noc", "pclk_hdcp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(29), 3, GFLAGS),
+       GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_hdcp", 0,
+                       RK3399_CLKGATE_CON(29), 6, GFLAGS),
+       GATE(PCLK_DP_CTRL, "pclk_dp_ctrl", "pclk_hdcp", 0,
+                       RK3399_CLKGATE_CON(29), 7, GFLAGS),
+       GATE(PCLK_HDCP22, "pclk_hdcp22", "pclk_hdcp", 0,
+                       RK3399_CLKGATE_CON(29), 8, GFLAGS),
+       GATE(PCLK_GASKET, "pclk_gasket", "pclk_hdcp", 0,
+                       RK3399_CLKGATE_CON(29), 11, GFLAGS),
+
+       /* edp */
+       COMPOSITE(SCLK_DP_CORE, "clk_dp_core", mux_pll_src_npll_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(46), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 8, GFLAGS),
+
+       COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 11, GFLAGS),
+       GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(32), 12, GFLAGS),
+       GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_edp", 0,
+                       RK3399_CLKGATE_CON(32), 13, GFLAGS),
+
+       /* hdmi */
+       GATE(SCLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0,
+                       RK3399_CLKGATE_CON(11), 6, GFLAGS),
+
+       COMPOSITE(SCLK_HDMI_CEC, "clk_hdmi_cec", mux_pll_p, 0,
+                       RK3399_CLKSEL_CON(45), 15, 1, MFLAGS, 0, 10, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 7, GFLAGS),
+
+       /* vop0 */
+       COMPOSITE(ACLK_VOP0_PRE, "aclk_vop0_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(47), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 8, GFLAGS),
+       COMPOSITE_NOMUX(0, "hclk_vop0_pre", "aclk_vop0_pre", 0,
+                       RK3399_CLKSEL_CON(47), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 9, GFLAGS),
+
+       GATE(ACLK_VOP0, "aclk_vop0", "aclk_vop0_pre", 0,
+                       RK3399_CLKGATE_CON(28), 3, GFLAGS),
+       GATE(ACLK_VOP0_NOC, "aclk_vop0_noc", "aclk_vop0_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(28), 1, GFLAGS),
+
+       GATE(HCLK_VOP0, "hclk_vop0", "hclk_vop0_pre", 0,
+                       RK3399_CLKGATE_CON(28), 2, GFLAGS),
+       GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(28), 0, GFLAGS),
+
+       COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 12, GFLAGS),
+
+       COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(106), 0,
+                       &rk3399_dclk_vop0_fracmux),
+
+       COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, 0,
+                       RK3399_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 14, GFLAGS),
+
+       /* vop1 */
+       COMPOSITE(ACLK_VOP1_PRE, "aclk_vop1_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 10, GFLAGS),
+       COMPOSITE_NOMUX(0, "hclk_vop1_pre", "aclk_vop1_pre", 0,
+                       RK3399_CLKSEL_CON(48), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 11, GFLAGS),
+
+       GATE(ACLK_VOP1, "aclk_vop1", "aclk_vop1_pre", 0,
+                       RK3399_CLKGATE_CON(28), 7, GFLAGS),
+       GATE(ACLK_VOP1_NOC, "aclk_vop1_noc", "aclk_vop1_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(28), 5, GFLAGS),
+
+       GATE(HCLK_VOP1, "hclk_vop1", "hclk_vop1_pre", 0,
+                       RK3399_CLKGATE_CON(28), 6, GFLAGS),
+       GATE(HCLK_VOP1_NOC, "hclk_vop1_noc", "hclk_vop1_pre", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(28), 4, GFLAGS),
+
+       COMPOSITE(DCLK_VOP1_DIV, "dclk_vop1_div", mux_pll_src_vpll_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 13, GFLAGS),
+
+       COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(107), 0,
+                       &rk3399_dclk_vop1_fracmux),
+
+       COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 15, GFLAGS),
+
+       /* isp */
+       COMPOSITE(ACLK_ISP0, "aclk_isp0", mux_pll_src_cpll_gpll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(53), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 8, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_ISP0, "hclk_isp0", "aclk_isp0", 0,
+                       RK3399_CLKSEL_CON(53), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 9, GFLAGS),
+
+       GATE(ACLK_ISP0_NOC, "aclk_isp0_noc", "aclk_isp0", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(27), 1, GFLAGS),
+       GATE(ACLK_ISP0_WRAPPER, "aclk_isp0_wrapper", "aclk_isp0", 0,
+                       RK3399_CLKGATE_CON(27), 5, GFLAGS),
+       GATE(HCLK_ISP1_WRAPPER, "hclk_isp1_wrapper", "aclk_isp0", 0,
+                       RK3399_CLKGATE_CON(27), 7, GFLAGS),
+
+       GATE(HCLK_ISP0_NOC, "hclk_isp0_noc", "hclk_isp0", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(27), 0, GFLAGS),
+       GATE(HCLK_ISP0_WRAPPER, "hclk_isp0_wrapper", "hclk_isp0", 0,
+                       RK3399_CLKGATE_CON(27), 4, GFLAGS),
+
+       COMPOSITE(SCLK_ISP0, "clk_isp0", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(55), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 4, GFLAGS),
+
+       COMPOSITE(ACLK_ISP1, "aclk_isp1", mux_pll_src_cpll_gpll_ppll_p, 0,
+                       RK3399_CLKSEL_CON(54), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 10, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_ISP1, "hclk_isp1", "aclk_isp1", 0,
+                       RK3399_CLKSEL_CON(54), 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 11, GFLAGS),
+
+       GATE(ACLK_ISP1_NOC, "aclk_isp1_noc", "aclk_isp1", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(27), 3, GFLAGS),
+
+       GATE(HCLK_ISP1_NOC, "hclk_isp1_noc", "hclk_isp1", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(27), 2, GFLAGS),
+       GATE(ACLK_ISP1_WRAPPER, "aclk_isp1_wrapper", "hclk_isp1", 0,
+                       RK3399_CLKGATE_CON(27), 8, GFLAGS),
+
+       COMPOSITE(SCLK_ISP1, "clk_isp1", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(55), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(11), 5, GFLAGS),
+
+       /*
+        * We use pclkin_cifinv by default GRF_SOC_CON20[9] (GSC20_9) setting in system,
+        * so we ignore the mux and make clocks nodes as following,
+        *
+        * pclkin_cifinv --|-------\
+        *                 |GSC20_9|-- pclkin_cifmux -- |G27_6| -- pclkin_isp1_wrapper
+        * pclkin_cif    --|-------/
+        */
+       GATE(PCLK_ISP1_WRAPPER, "pclkin_isp1_wrapper", "pclkin_cif", 0,
+                       RK3399_CLKGATE_CON(27), 6, GFLAGS),
+
+       /* cif */
+       COMPOSITE_NODIV(0, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0,
+                       RK3399_CLKSEL_CON(56), 6, 2, MFLAGS,
+                       RK3399_CLKGATE_CON(10), 7, GFLAGS),
+
+       COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0,
+                        RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS),
+
+       /* gic */
+       COMPOSITE(ACLK_GIC_PRE, "aclk_gic_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
+                       RK3399_CLKSEL_CON(56), 15, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_CLKGATE_CON(12), 12, GFLAGS),
+
+       GATE(ACLK_GIC, "aclk_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 0, GFLAGS),
+       GATE(ACLK_GIC_NOC, "aclk_gic_noc", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 1, GFLAGS),
+       GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_gic_adb400_core_l_2_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 2, GFLAGS),
+       GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_gic_adb400_core_b_2_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 3, GFLAGS),
+       GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_gic_adb400_gic_2_core_l", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 4, GFLAGS),
+       GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_gic_adb400_gic_2_core_b", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 5, GFLAGS),
+
+       /* alive */
+       /* pclk_alive_gpll_src is controlled by PMUGRF_SOC_CON0[6] */
+       DIV(PCLK_ALIVE, "pclk_alive", "gpll", 0,
+                       RK3399_CLKSEL_CON(57), 0, 5, DFLAGS),
+
+       GATE(PCLK_USBPHY_MUX_G, "pclk_usbphy_mux_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 4, GFLAGS),
+       GATE(PCLK_UPHY0_TCPHY_G, "pclk_uphy0_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 5, GFLAGS),
+       GATE(PCLK_UPHY0_TCPD_G, "pclk_uphy0_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 6, GFLAGS),
+       GATE(PCLK_UPHY1_TCPHY_G, "pclk_uphy1_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 8, GFLAGS),
+       GATE(PCLK_UPHY1_TCPD_G, "pclk_uphy1_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 9, GFLAGS),
+
+       GATE(PCLK_GRF, "pclk_grf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 1, GFLAGS),
+       GATE(PCLK_INTR_ARB, "pclk_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 2, GFLAGS),
+       GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 3, GFLAGS),
+       GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 4, GFLAGS),
+       GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 5, GFLAGS),
+       GATE(PCLK_TIMER0, "pclk_timer0", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 6, GFLAGS),
+       GATE(PCLK_TIMER1, "pclk_timer1", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 7, GFLAGS),
+       GATE(PCLK_PMU_INTR_ARB, "pclk_pmu_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 9, GFLAGS),
+       GATE(PCLK_SGRF, "pclk_sgrf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 10, GFLAGS),
+
+       GATE(SCLK_MIPIDPHY_REF, "clk_mipidphy_ref", "xin24m", 0, RK3399_CLKGATE_CON(11), 14, GFLAGS),
+       GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 0, GFLAGS),
+
+       GATE(SCLK_MIPIDPHY_CFG, "clk_mipidphy_cfg", "xin24m", 0, RK3399_CLKGATE_CON(11), 15, GFLAGS),
+       GATE(SCLK_DPHY_TX0_CFG, "clk_dphy_tx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 1, GFLAGS),
+       GATE(SCLK_DPHY_TX1RX1_CFG, "clk_dphy_tx1rx1_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 2, GFLAGS),
+       GATE(SCLK_DPHY_RX0_CFG, "clk_dphy_rx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 3, GFLAGS),
+
+       /* testout */
+       MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(58), 7, 1, MFLAGS),
+       COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT,
+                       RK3399_CLKSEL_CON(105), 0,
+                       RK3399_CLKGATE_CON(13), 9, GFLAGS),
+
+       DIV(0, "clk_test_24m", "xin24m", 0,
+                       RK3399_CLKSEL_CON(57), 6, 10, DFLAGS),
+
+       /* spi */
+       COMPOSITE(SCLK_SPI0, "clk_spi0", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(59), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 12, GFLAGS),
+
+       COMPOSITE(SCLK_SPI1, "clk_spi1", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(59), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 13, GFLAGS),
+
+       COMPOSITE(SCLK_SPI2, "clk_spi2", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(60), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 14, GFLAGS),
+
+       COMPOSITE(SCLK_SPI4, "clk_spi4", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(60), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(9), 15, GFLAGS),
+
+       COMPOSITE(SCLK_SPI5, "clk_spi5", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(58), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(13), 13, GFLAGS),
+
+       /* i2c */
+       COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(61), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 0, GFLAGS),
+
+       COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(62), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 2, GFLAGS),
+
+       COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(63), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 4, GFLAGS),
+
+       COMPOSITE(SCLK_I2C5, "clk_i2c5", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(61), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 1, GFLAGS),
+
+       COMPOSITE(SCLK_I2C6, "clk_i2c6", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(62), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 3, GFLAGS),
+
+       COMPOSITE(SCLK_I2C7, "clk_i2c7", mux_pll_src_cpll_gpll_p, 0,
+                       RK3399_CLKSEL_CON(63), 15, 1, MFLAGS, 8, 7, DFLAGS,
+                       RK3399_CLKGATE_CON(10), 5, GFLAGS),
+
+       /* timer */
+       GATE(SCLK_TIMER00, "clk_timer00", "xin24m", 0, RK3399_CLKGATE_CON(26), 0, GFLAGS),
+       GATE(SCLK_TIMER01, "clk_timer01", "xin24m", 0, RK3399_CLKGATE_CON(26), 1, GFLAGS),
+       GATE(SCLK_TIMER02, "clk_timer02", "xin24m", 0, RK3399_CLKGATE_CON(26), 2, GFLAGS),
+       GATE(SCLK_TIMER03, "clk_timer03", "xin24m", 0, RK3399_CLKGATE_CON(26), 3, GFLAGS),
+       GATE(SCLK_TIMER04, "clk_timer04", "xin24m", 0, RK3399_CLKGATE_CON(26), 4, GFLAGS),
+       GATE(SCLK_TIMER05, "clk_timer05", "xin24m", 0, RK3399_CLKGATE_CON(26), 5, GFLAGS),
+       GATE(SCLK_TIMER06, "clk_timer06", "xin24m", 0, RK3399_CLKGATE_CON(26), 6, GFLAGS),
+       GATE(SCLK_TIMER07, "clk_timer07", "xin24m", 0, RK3399_CLKGATE_CON(26), 7, GFLAGS),
+       GATE(SCLK_TIMER08, "clk_timer08", "xin24m", 0, RK3399_CLKGATE_CON(26), 8, GFLAGS),
+       GATE(SCLK_TIMER09, "clk_timer09", "xin24m", 0, RK3399_CLKGATE_CON(26), 9, GFLAGS),
+       GATE(SCLK_TIMER10, "clk_timer10", "xin24m", 0, RK3399_CLKGATE_CON(26), 10, GFLAGS),
+       GATE(SCLK_TIMER11, "clk_timer11", "xin24m", 0, RK3399_CLKGATE_CON(26), 11, GFLAGS),
+
+       /* clk_test */
+       /* clk_test_pre is controlled by CRU_MISC_CON[3] */
+       COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
+                       RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
+                       RK3368_CLKGATE_CON(13), 11, GFLAGS),
+};
+
+static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
+       /*
+        * PMU CRU Clock-Architecture
+        */
+
+       GATE(0, "fclk_cm0s_pmu_ppll_src", "ppll", 0,
+                       RK3399_PMU_CLKGATE_CON(0), 1, GFLAGS),
+
+       COMPOSITE_NOGATE(FCLK_CM0S_SRC_PMU, "fclk_cm0s_src_pmu", mux_fclk_cm0s_pmu_ppll_p, 0,
+                       RK3399_PMU_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS),
+
+       COMPOSITE(SCLK_SPI3_PMU, "clk_spi3_pmu", mux_24m_ppll_p, 0,
+                       RK3399_PMU_CLKSEL_CON(1), 7, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_PMU_CLKGATE_CON(0), 2, GFLAGS),
+
+       COMPOSITE(0, "clk_wifi_div", mux_ppll_24m_p, CLK_IGNORE_UNUSED,
+                       RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
+                       RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS),
+
+       COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT,
+                       RK3399_PMU_CLKSEL_CON(7), 0,
+                       &rk3399_pmuclk_wifi_fracmux),
+
+       MUX(0, "clk_timer_src_pmu", mux_pll_p, CLK_IGNORE_UNUSED,
+                       RK3399_PMU_CLKSEL_CON(1), 15, 1, MFLAGS),
+
+       COMPOSITE_NOMUX(SCLK_I2C0_PMU, "clk_i2c0_pmu", "ppll", 0,
+                       RK3399_PMU_CLKSEL_CON(2), 0, 7, DFLAGS,
+                       RK3399_PMU_CLKGATE_CON(0), 9, GFLAGS),
+
+       COMPOSITE_NOMUX(SCLK_I2C4_PMU, "clk_i2c4_pmu", "ppll", 0,
+                       RK3399_PMU_CLKSEL_CON(3), 0, 7, DFLAGS,
+                       RK3399_PMU_CLKGATE_CON(0), 10, GFLAGS),
+
+       COMPOSITE_NOMUX(SCLK_I2C8_PMU, "clk_i2c8_pmu", "ppll", 0,
+                       RK3399_PMU_CLKSEL_CON(2), 8, 7, DFLAGS,
+                       RK3399_PMU_CLKGATE_CON(0), 11, GFLAGS),
+
+       DIV(0, "clk_32k_suspend_pmu", "xin24m", CLK_IGNORE_UNUSED,
+                       RK3399_PMU_CLKSEL_CON(4), 0, 10, DFLAGS),
+       MUX(0, "clk_testout_2io", mux_clk_testout2_2io_p, CLK_IGNORE_UNUSED,
+                       RK3399_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
+
+       COMPOSITE(0, "clk_uart4_div", mux_24m_ppll_p, 0,
+                       RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
+                       RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS),
+
+       COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT,
+                       RK3399_PMU_CLKSEL_CON(6), 0,
+                       RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS,
+                       &rk3399_uart4_pmu_fracmux),
+
+       DIV(PCLK_SRC_PMU, "pclk_pmu_src", "ppll", CLK_IGNORE_UNUSED,
+                       RK3399_PMU_CLKSEL_CON(0), 0, 5, DFLAGS),
+
+       /* pmu clock gates */
+       GATE(SCLK_TIMER12_PMU, "clk_timer0_pmu", "clk_timer_src_pmu", 0, RK3399_PMU_CLKGATE_CON(0), 3, GFLAGS),
+       GATE(SCLK_TIMER13_PMU, "clk_timer1_pmu", "clk_timer_src_pmu", 0, RK3399_PMU_CLKGATE_CON(0), 4, GFLAGS),
+
+       GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 7, GFLAGS),
+
+       GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 0, GFLAGS),
+       GATE(PCLK_PMUGRF_PMU, "pclk_pmugrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 1, GFLAGS),
+       GATE(PCLK_INTMEM1_PMU, "pclk_intmem1_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 2, GFLAGS),
+       GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 3, GFLAGS),
+       GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 4, GFLAGS),
+       GATE(PCLK_SGRF_PMU, "pclk_sgrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 5, GFLAGS),
+       GATE(PCLK_NOC_PMU, "pclk_noc_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 6, GFLAGS),
+       GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 7, GFLAGS),
+       GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 8, GFLAGS),
+       GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 9, GFLAGS),
+       GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 10, GFLAGS),
+       GATE(PCLK_SPI3_PMU, "pclk_spi3_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 11, GFLAGS),
+       GATE(PCLK_TIMER_PMU, "pclk_timer_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 12, GFLAGS),
+       GATE(PCLK_MAILBOX_PMU, "pclk_mailbox_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 13, GFLAGS),
+       GATE(PCLK_UART4_PMU, "pclk_uart4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 14, GFLAGS),
+       GATE(PCLK_WDT_M0_PMU, "pclk_wdt_m0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 15, GFLAGS),
+
+       GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 1, GFLAGS),
+       GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 2, GFLAGS),
+       GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 3, GFLAGS),
+       GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 5, GFLAGS),
+};
+
+static const char *const rk3399_cru_critical_clocks[] __initconst = {
+       "aclk_cci_pre",
+       "pclk_perilp0",
+       "pclk_perilp0",
+       "hclk_perilp0",
+       "hclk_perilp0_noc",
+       "pclk_perilp1",
+       "pclk_perilp1_noc",
+       "pclk_perihp",
+       "pclk_perihp_noc",
+       "hclk_perihp",
+       "aclk_perihp",
+       "aclk_perihp_noc",
+       "aclk_perilp0",
+       "aclk_perilp0_noc",
+       "hclk_perilp1",
+       "hclk_perilp1_noc",
+       "aclk_dmac0_perilp",
+       "gpll_hclk_perilp1_src",
+       "gpll_aclk_perilp0_src",
+       "gpll_aclk_perihp_src",
+};
+
+static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
+       "ppll",
+       "pclk_pmu_src",
+       "fclk_cm0s_src_pmu",
+       "clk_timer_src_pmu",
+};
+
+static void __init rk3399_clk_init(struct device_node *np)
+{
+       struct rockchip_clk_provider *ctx;
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base) {
+               pr_err("%s: could not map cru region\n", __func__);
+               return;
+       }
+
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               return;
+       }
+
+       rockchip_clk_register_plls(ctx, rk3399_pll_clks,
+                                  ARRAY_SIZE(rk3399_pll_clks), -1);
+
+       rockchip_clk_register_branches(ctx, rk3399_clk_branches,
+                                 ARRAY_SIZE(rk3399_clk_branches));
+
+       rockchip_clk_protect_critical(rk3399_cru_critical_clocks,
+                                     ARRAY_SIZE(rk3399_cru_critical_clocks));
+
+       rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl",
+                       mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
+                       &rk3399_cpuclkl_data, rk3399_cpuclkl_rates,
+                       ARRAY_SIZE(rk3399_cpuclkl_rates));
+
+       rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb",
+                       mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
+                       &rk3399_cpuclkb_data, rk3399_cpuclkb_rates,
+                       ARRAY_SIZE(rk3399_cpuclkb_rates));
+
+       rockchip_register_softrst(np, 21, reg_base + RK3399_SOFTRST_CON(0),
+                                 ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+       rockchip_register_restart_notifier(ctx, RK3399_GLB_SRST_FST, NULL);
+
+       rockchip_clk_of_add_provider(np, ctx);
+}
+CLK_OF_DECLARE(rk3399_cru, "rockchip,rk3399-cru", rk3399_clk_init);
+
+static void __init rk3399_pmu_clk_init(struct device_node *np)
+{
+       struct rockchip_clk_provider *ctx;
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base) {
+               pr_err("%s: could not map cru pmu region\n", __func__);
+               return;
+       }
+
+       ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip pmu clk init failed\n", __func__);
+               return;
+       }
+
+       rockchip_clk_register_plls(ctx, rk3399_pmu_pll_clks,
+                                  ARRAY_SIZE(rk3399_pmu_pll_clks), -1);
+
+       rockchip_clk_register_branches(ctx, rk3399_clk_pmu_branches,
+                                 ARRAY_SIZE(rk3399_clk_pmu_branches));
+
+       rockchip_clk_protect_critical(rk3399_pmucru_critical_clocks,
+                                 ARRAY_SIZE(rk3399_pmucru_critical_clocks));
+
+       rockchip_register_softrst(np, 2, reg_base + RK3399_PMU_SOFTRST_CON(0),
+                                 ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+       rockchip_clk_of_add_provider(np, ctx);
+}
+CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init);
index ec06350c78c4808c7dc6a849f157428402cccf0f..f0a8be1553b09e3e18c887d72ccc003d1aaec51e 100644 (file)
@@ -2,6 +2,9 @@
  * Copyright (c) 2014 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
  *
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing@rock-chips.com>
+ *
  * based on
  *
  * samsung/clk.c
@@ -39,7 +42,8 @@
  * sometimes without one of those components.
  */
 static struct clk *rockchip_clk_register_branch(const char *name,
-               const char *const *parent_names, u8 num_parents, void __iomem *base,
+               const char *const *parent_names, u8 num_parents,
+               void __iomem *base,
                int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
                u8 div_shift, u8 div_width, u8 div_flags,
                struct clk_div_table *div_table, int gate_offset,
@@ -136,9 +140,11 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
        pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
                 __func__, event, ndata->old_rate, ndata->new_rate);
        if (event == PRE_RATE_CHANGE) {
-               frac->rate_change_idx = frac->mux_ops->get_parent(&frac_mux->hw);
+               frac->rate_change_idx =
+                               frac->mux_ops->get_parent(&frac_mux->hw);
                if (frac->rate_change_idx != frac->mux_frac_idx) {
-                       frac->mux_ops->set_parent(&frac_mux->hw, frac->mux_frac_idx);
+                       frac->mux_ops->set_parent(&frac_mux->hw,
+                                                 frac->mux_frac_idx);
                        frac->rate_change_remuxed = 1;
                }
        } else if (event == POST_RATE_CHANGE) {
@@ -149,7 +155,8 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
                 * reaches the mux itself.
                 */
                if (frac->rate_change_remuxed) {
-                       frac->mux_ops->set_parent(&frac_mux->hw, frac->rate_change_idx);
+                       frac->mux_ops->set_parent(&frac_mux->hw,
+                                                 frac->rate_change_idx);
                        frac->rate_change_remuxed = 0;
                }
        }
@@ -157,7 +164,8 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
        return notifier_from_errno(ret);
 }
 
-static struct clk *rockchip_clk_register_frac_branch(const char *name,
+static struct clk *rockchip_clk_register_frac_branch(
+               struct rockchip_clk_provider *ctx, const char *name,
                const char *const *parent_names, u8 num_parents,
                void __iomem *base, int muxdiv_offset, u8 div_flags,
                int gate_offset, u8 gate_shift, u8 gate_flags,
@@ -250,7 +258,7 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
                if (IS_ERR(mux_clk))
                        return clk;
 
-               rockchip_clk_add_lookup(mux_clk, child->id);
+               rockchip_clk_add_lookup(ctx, mux_clk, child->id);
 
                /* notifier on the fraction divider to catch rate changes */
                if (frac->mux_frac_idx >= 0) {
@@ -314,66 +322,87 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
        return clk;
 }
 
-static DEFINE_SPINLOCK(clk_lock);
-static struct clk **clk_table;
-static void __iomem *reg_base;
-static struct clk_onecell_data clk_data;
-static struct device_node *cru_node;
-static struct regmap *grf;
-
-void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
-                             unsigned long nr_clks)
+struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np,
+                       void __iomem *base, unsigned long nr_clks)
 {
-       reg_base = base;
-       cru_node = np;
-       grf = ERR_PTR(-EPROBE_DEFER);
+       struct rockchip_clk_provider *ctx;
+       struct clk **clk_table;
+       int i;
+
+       ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL);
+       if (!ctx)
+               return ERR_PTR(-ENOMEM);
 
        clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
        if (!clk_table)
-               pr_err("%s: could not allocate clock lookup table\n", __func__);
+               goto err_free;
+
+       for (i = 0; i < nr_clks; ++i)
+               clk_table[i] = ERR_PTR(-ENOENT);
 
-       clk_data.clks = clk_table;
-       clk_data.clk_num = nr_clks;
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       ctx->reg_base = base;
+       ctx->clk_data.clks = clk_table;
+       ctx->clk_data.clk_num = nr_clks;
+       ctx->cru_node = np;
+       ctx->grf = ERR_PTR(-EPROBE_DEFER);
+       spin_lock_init(&ctx->lock);
+
+       return ctx;
+
+err_free:
+       kfree(ctx);
+       return ERR_PTR(-ENOMEM);
+}
+
+void __init rockchip_clk_of_add_provider(struct device_node *np,
+                               struct rockchip_clk_provider *ctx)
+{
+       if (of_clk_add_provider(np, of_clk_src_onecell_get,
+                               &ctx->clk_data))
+               pr_err("%s: could not register clk provider\n", __func__);
 }
 
-struct regmap *rockchip_clk_get_grf(void)
+struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx)
 {
-       if (IS_ERR(grf))
-               grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf");
-       return grf;
+       if (IS_ERR(ctx->grf))
+               ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
+                                                          "rockchip,grf");
+       return ctx->grf;
 }
 
-void rockchip_clk_add_lookup(struct clk *clk, unsigned int id)
+void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
+                            struct clk *clk, unsigned int id)
 {
-       if (clk_table && id)
-               clk_table[id] = clk;
+       if (ctx->clk_data.clks && id)
+               ctx->clk_data.clks[id] = clk;
 }
 
-void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list,
+void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
+                               struct rockchip_pll_clock *list,
                                unsigned int nr_pll, int grf_lock_offset)
 {
        struct clk *clk;
        int idx;
 
        for (idx = 0; idx < nr_pll; idx++, list++) {
-               clk = rockchip_clk_register_pll(list->type, list->name,
+               clk = rockchip_clk_register_pll(ctx, list->type, list->name,
                                list->parent_names, list->num_parents,
-                               reg_base, list->con_offset, grf_lock_offset,
+                               list->con_offset, grf_lock_offset,
                                list->lock_shift, list->mode_offset,
                                list->mode_shift, list->rate_table,
-                               list->pll_flags, &clk_lock);
+                               list->pll_flags);
                if (IS_ERR(clk)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
                        continue;
                }
 
-               rockchip_clk_add_lookup(clk, list->id);
+               rockchip_clk_add_lookup(ctx, clk, list->id);
        }
 }
 
 void __init rockchip_clk_register_branches(
+                                     struct rockchip_clk_provider *ctx,
                                      struct rockchip_clk_branch *list,
                                      unsigned int nr_clk)
 {
@@ -389,56 +418,59 @@ void __init rockchip_clk_register_branches(
                case branch_mux:
                        clk = clk_register_mux(NULL, list->name,
                                list->parent_names, list->num_parents,
-                               flags, reg_base + list->muxdiv_offset,
+                               flags, ctx->reg_base + list->muxdiv_offset,
                                list->mux_shift, list->mux_width,
-                               list->mux_flags, &clk_lock);
+                               list->mux_flags, &ctx->lock);
                        break;
                case branch_divider:
                        if (list->div_table)
                                clk = clk_register_divider_table(NULL,
                                        list->name, list->parent_names[0],
-                                       flags, reg_base + list->muxdiv_offset,
+                                       flags,
+                                       ctx->reg_base + list->muxdiv_offset,
                                        list->div_shift, list->div_width,
                                        list->div_flags, list->div_table,
-                                       &clk_lock);
+                                       &ctx->lock);
                        else
                                clk = clk_register_divider(NULL, list->name,
                                        list->parent_names[0], flags,
-                                       reg_base + list->muxdiv_offset,
+                                       ctx->reg_base + list->muxdiv_offset,
                                        list->div_shift, list->div_width,
-                                       list->div_flags, &clk_lock);
+                                       list->div_flags, &ctx->lock);
                        break;
                case branch_fraction_divider:
-                       clk = rockchip_clk_register_frac_branch(list->name,
+                       clk = rockchip_clk_register_frac_branch(ctx, list->name,
                                list->parent_names, list->num_parents,
-                               reg_base, list->muxdiv_offset, list->div_flags,
+                               ctx->reg_base, list->muxdiv_offset,
+                               list->div_flags,
                                list->gate_offset, list->gate_shift,
                                list->gate_flags, flags, list->child,
-                               &clk_lock);
+                               &ctx->lock);
                        break;
                case branch_gate:
                        flags |= CLK_SET_RATE_PARENT;
 
                        clk = clk_register_gate(NULL, list->name,
                                list->parent_names[0], flags,
-                               reg_base + list->gate_offset,
-                               list->gate_shift, list->gate_flags, &clk_lock);
+                               ctx->reg_base + list->gate_offset,
+                               list->gate_shift, list->gate_flags, &ctx->lock);
                        break;
                case branch_composite:
                        clk = rockchip_clk_register_branch(list->name,
                                list->parent_names, list->num_parents,
-                               reg_base, list->muxdiv_offset, list->mux_shift,
+                               ctx->reg_base, list->muxdiv_offset,
+                               list->mux_shift,
                                list->mux_width, list->mux_flags,
                                list->div_shift, list->div_width,
                                list->div_flags, list->div_table,
                                list->gate_offset, list->gate_shift,
-                               list->gate_flags, flags, &clk_lock);
+                               list->gate_flags, flags, &ctx->lock);
                        break;
                case branch_mmc:
                        clk = rockchip_clk_register_mmc(
                                list->name,
                                list->parent_names, list->num_parents,
-                               reg_base + list->muxdiv_offset,
+                               ctx->reg_base + list->muxdiv_offset,
                                list->div_shift
                        );
                        break;
@@ -446,16 +478,16 @@ void __init rockchip_clk_register_branches(
                        clk = rockchip_clk_register_inverter(
                                list->name, list->parent_names,
                                list->num_parents,
-                               reg_base + list->muxdiv_offset,
-                               list->div_shift, list->div_flags, &clk_lock);
+                               ctx->reg_base + list->muxdiv_offset,
+                               list->div_shift, list->div_flags, &ctx->lock);
                        break;
                case branch_factor:
                        clk = rockchip_clk_register_factor_branch(
                                list->name, list->parent_names,
-                               list->num_parents, reg_base,
+                               list->num_parents, ctx->reg_base,
                                list->div_shift, list->div_width,
                                list->gate_offset, list->gate_shift,
-                               list->gate_flags, flags, &clk_lock);
+                               list->gate_flags, flags, &ctx->lock);
                        break;
                }
 
@@ -472,11 +504,12 @@ void __init rockchip_clk_register_branches(
                        continue;
                }
 
-               rockchip_clk_add_lookup(clk, list->id);
+               rockchip_clk_add_lookup(ctx, clk, list->id);
        }
 }
 
-void __init rockchip_clk_register_armclk(unsigned int lookup_id,
+void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
+                       unsigned int lookup_id,
                        const char *name, const char *const *parent_names,
                        u8 num_parents,
                        const struct rockchip_cpuclk_reg_data *reg_data,
@@ -486,15 +519,15 @@ void __init rockchip_clk_register_armclk(unsigned int lookup_id,
        struct clk *clk;
 
        clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
-                                          reg_data, rates, nrates, reg_base,
-                                          &clk_lock);
+                                          reg_data, rates, nrates,
+                                          ctx->reg_base, &ctx->lock);
        if (IS_ERR(clk)) {
                pr_err("%s: failed to register clock %s: %ld\n",
                       __func__, name, PTR_ERR(clk));
                return;
        }
 
-       rockchip_clk_add_lookup(clk, lookup_id);
+       rockchip_clk_add_lookup(ctx, clk, lookup_id);
 }
 
 void __init rockchip_clk_protect_critical(const char *const clocks[],
@@ -511,6 +544,7 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
        }
 }
 
+static void __iomem *rst_base;
 static unsigned int reg_restart;
 static void (*cb_restart)(void);
 static int rockchip_restart_notify(struct notifier_block *this,
@@ -519,7 +553,7 @@ static int rockchip_restart_notify(struct notifier_block *this,
        if (cb_restart)
                cb_restart();
 
-       writel(0xfdb9, reg_base + reg_restart);
+       writel(0xfdb9, rst_base + reg_restart);
        return NOTIFY_DONE;
 }
 
@@ -528,10 +562,14 @@ static struct notifier_block rockchip_restart_handler = {
        .priority = 128,
 };
 
-void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void))
+void __init
+rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
+                                              unsigned int reg,
+                                              void (*cb)(void))
 {
        int ret;
 
+       rst_base = ctx->reg_base;
        reg_restart = reg;
        cb_restart = cb;
        ret = register_restart_handler(&rockchip_restart_handler);
index 39c198bbcbee7be22f47b0c3f4f30bb297eea772..1abb7d05d1c78a0ea3dd52daae3faeb79a39cc7f 100644 (file)
 #define CLK_ROCKCHIP_CLK_H
 
 #include <linux/io.h>
+#include <linux/clk-provider.h>
 
 struct clk;
 
 #define HIWORD_UPDATE(val, mask, shift) \
                ((val) << (shift) | (mask) << ((shift) + 16))
 
-/* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */
 #define RK2928_PLL_CON(x)              ((x) * 0x4)
 #define RK2928_MODE_CON                0x40
 #define RK2928_CLKSEL_CON(x)   ((x) * 0x4 + 0x44)
@@ -92,9 +92,30 @@ struct clk;
 #define RK3368_EMMC_CON0               0x418
 #define RK3368_EMMC_CON1               0x41c
 
+#define RK3399_PLL_CON(x)              RK2928_PLL_CON(x)
+#define RK3399_CLKSEL_CON(x)           ((x) * 0x4 + 0x100)
+#define RK3399_CLKGATE_CON(x)          ((x) * 0x4 + 0x300)
+#define RK3399_SOFTRST_CON(x)          ((x) * 0x4 + 0x400)
+#define RK3399_GLB_SRST_FST            0x500
+#define RK3399_GLB_SRST_SND            0x504
+#define RK3399_GLB_CNT_TH              0x508
+#define RK3399_MISC_CON                        0x50c
+#define RK3399_RST_CON                 0x510
+#define RK3399_RST_ST                  0x514
+#define RK3399_SDMMC_CON0              0x580
+#define RK3399_SDMMC_CON1              0x584
+#define RK3399_SDIO_CON0               0x588
+#define RK3399_SDIO_CON1               0x58c
+
+#define RK3399_PMU_PLL_CON(x)          RK2928_PLL_CON(x)
+#define RK3399_PMU_CLKSEL_CON(x)       ((x) * 0x4 + 0x80)
+#define RK3399_PMU_CLKGATE_CON(x)      ((x) * 0x4 + 0x100)
+#define RK3399_PMU_SOFTRST_CON(x)      ((x) * 0x4 + 0x110)
+
 enum rockchip_pll_type {
        pll_rk3036,
        pll_rk3066,
+       pll_rk3399,
 };
 
 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,     \
@@ -127,13 +148,29 @@ enum rockchip_pll_type {
        .nb = _nb,                                              \
 }
 
+/**
+ * struct rockchip_clk_provider - information about clock provider
+ * @reg_base: virtual address for the register base.
+ * @clk_data: holds clock related data like clk* and number of clocks.
+ * @cru_node: device-node of the clock-provider
+ * @grf: regmap of the general-register-files syscon
+ * @lock: maintains exclusion between callbacks for a given clock-provider.
+ */
+struct rockchip_clk_provider {
+       void __iomem *reg_base;
+       struct clk_onecell_data clk_data;
+       struct device_node *cru_node;
+       struct regmap *grf;
+       spinlock_t lock;
+};
+
 struct rockchip_pll_rate_table {
        unsigned long rate;
        unsigned int nr;
        unsigned int nf;
        unsigned int no;
        unsigned int nb;
-       /* for RK3036 */
+       /* for RK3036/RK3399 */
        unsigned int fbdiv;
        unsigned int postdiv1;
        unsigned int refdiv;
@@ -143,10 +180,11 @@ struct rockchip_pll_rate_table {
 };
 
 /**
- * struct rockchip_pll_clock: information about pll clock
+ * struct rockchip_pll_clock - information about pll clock
  * @id: platform specific id of the clock.
  * @name: name of this pll clock.
- * @parent_name: name of the parent clock.
+ * @parent_names: name of the parent clock.
+ * @num_parents: number of parents
  * @flags: optional flags for basic clock.
  * @con_offset: offset of the register for configuring the PLL.
  * @mode_offset: offset of the register for configuring the PLL-mode.
@@ -194,12 +232,13 @@ struct rockchip_pll_clock {
                .rate_table     = _rtable,                              \
        }
 
-struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
+struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+               enum rockchip_pll_type pll_type,
                const char *name, const char *const *parent_names,
-               u8 num_parents, void __iomem *base, int con_offset,
-               int grf_lock_offset, int lock_shift, int reg_mode,
-               int mode_shift, struct rockchip_pll_rate_table *rate_table,
-               u8 clk_pll_flags, spinlock_t *lock);
+               u8 num_parents, int con_offset, int grf_lock_offset,
+               int lock_shift, int mode_offset, int mode_shift,
+               struct rockchip_pll_rate_table *rate_table,
+               u8 clk_pll_flags);
 
 struct rockchip_cpuclk_clksel {
        int reg;
@@ -213,18 +252,23 @@ struct rockchip_cpuclk_rate_table {
 };
 
 /**
- * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock
+ * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
  * @core_reg:          register offset of the core settings register
  * @div_core_shift:    core divider offset used to divide the pll value
  * @div_core_mask:     core divider mask
+ * @mux_core_alt:      mux value to select alternate parent
+ * @mux_core_main:     mux value to select main parent of core
  * @mux_core_shift:    offset of the core multiplexer
+ * @mux_core_mask:     core multiplexer mask
  */
 struct rockchip_cpuclk_reg_data {
        int             core_reg;
        u8              div_core_shift;
        u32             div_core_mask;
-       int             mux_core_reg;
+       u8              mux_core_alt;
+       u8              mux_core_main;
        u8              mux_core_shift;
+       u32             mux_core_mask;
 };
 
 struct clk *rockchip_clk_register_cpuclk(const char *name,
@@ -428,6 +472,22 @@ struct rockchip_clk_branch {
                .child          = ch,                           \
        }
 
+#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
+       {                                                       \
+               .id             = _id,                          \
+               .branch_type    = branch_fraction_divider,      \
+               .name           = cname,                        \
+               .parent_names   = (const char *[]){ pname },    \
+               .num_parents    = 1,                            \
+               .flags          = f,                            \
+               .muxdiv_offset  = mo,                           \
+               .div_shift      = 16,                           \
+               .div_width      = 16,                           \
+               .div_flags      = df,                           \
+               .gate_offset    = -1,                           \
+               .child          = ch,                           \
+       }
+
 #define MUX(_id, cname, pnames, f, o, s, w, mf)                        \
        {                                                       \
                .id             = _id,                          \
@@ -536,21 +596,28 @@ struct rockchip_clk_branch {
                .gate_flags     = gf,                           \
        }
 
-void rockchip_clk_init(struct device_node *np, void __iomem *base,
-                      unsigned long nr_clks);
-struct regmap *rockchip_clk_get_grf(void);
-void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
-void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
+struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
+                       void __iomem *base, unsigned long nr_clks);
+void rockchip_clk_of_add_provider(struct device_node *np,
+                               struct rockchip_clk_provider *ctx);
+struct regmap *rockchip_clk_get_grf(struct rockchip_clk_provider *ctx);
+void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
+                            struct clk *clk, unsigned int id);
+void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+                                   struct rockchip_clk_branch *list,
                                    unsigned int nr_clk);
-void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
+void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
+                               struct rockchip_pll_clock *pll_list,
                                unsigned int nr_pll, int grf_lock_offset);
-void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
+void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
+                       unsigned int lookup_id, const char *name,
                        const char *const *parent_names, u8 num_parents,
                        const struct rockchip_cpuclk_reg_data *reg_data,
                        const struct rockchip_cpuclk_rate_table *rates,
                        int nrates);
 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
-void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void));
+void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
+                                       unsigned int reg, void (*cb)(void));
 
 #define ROCKCHIP_SOFTRST_HIWORD_MASK   BIT(0)
 
index 552f7bb15bc5bf82a8678ecc084fe7c06e0cea81..21218987bbc3d55141c7f28fbb94aa03c2cdb90c 100644 (file)
@@ -81,7 +81,7 @@ static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev,
        return 0;
 }
 
-static struct reset_control_ops rockchip_softrst_ops = {
+static const struct reset_control_ops rockchip_softrst_ops = {
        .assert         = rockchip_softrst_assert,
        .deassert       = rockchip_softrst_deassert,
 };
index fdd41b17a24fc590254768e346f10d7e0b253321..16575ee874cbb9e633a575001406e10621602836 100644 (file)
@@ -302,10 +302,12 @@ static struct samsung_mux_clock mux_clks[] __initdata = {
 
        /* SRC_FSYS */
        MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4),
+       MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4),
        MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4),
        MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
 
        /* SRC_PERIL0 */
+       MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
        MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
        MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
 
@@ -389,7 +391,13 @@ static struct samsung_div_clock div_clks[] __initdata = {
                CLK_SET_RATE_PARENT, 0),
        DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
 
+       /* DIV_FSYS2 */
+       DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8,
+               CLK_SET_RATE_PARENT, 0),
+       DIV(CLK_DIV_MMC2, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
+
        /* DIV_PERIL0 */
+       DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
        DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
        DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
 
@@ -538,6 +546,8 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
                GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi",
                GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0),
+       GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre",
+               GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre",
                GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre",
@@ -552,6 +562,9 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
                GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
                GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
+
+       GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
+               GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
                GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
@@ -630,6 +643,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
        GATE(CLK_USBOTG, "usbotg", "div_aclk_200", GATE_IP_FSYS, 13, 0, 0),
        GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0),
        GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0),
+       GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0),
        GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0),
        GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0),
        GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0),
@@ -649,6 +663,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
        GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
        GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
        GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
+       GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
        GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
        GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
 };
index be03ed0fcb6be74e3674b878f9691b67928008ee..92382cef9f90a2cc23c0c74ed11cad6e404c37c4 100644 (file)
@@ -554,8 +554,8 @@ static struct samsung_mux_clock exynos5800_mux_clks[] __initdata = {
 };
 
 static struct samsung_div_clock exynos5800_div_clks[] __initdata = {
-       DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore", DIV_TOP0, 16, 3),
-
+       DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore",
+                       "mout_aclk400_wcore", DIV_TOP0, 16, 3),
        DIV(0, "dout_aclk550_cam", "mout_aclk550_cam",
                                DIV_TOP8, 16, 3),
        DIV(0, "dout_aclkfl1_550_cam", "mout_aclkfl1_550_cam",
@@ -607,8 +607,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
 };
 
 static struct samsung_div_clock exynos5420_div_clks[] __initdata = {
-       DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll",
-                       DIV_TOP0, 16, 3),
+       DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore",
+                       "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3),
 };
 
 static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
@@ -785,31 +785,47 @@ static struct samsung_div_clock exynos5x_div_clks[] __initdata = {
        DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3),
        DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3),
 
-       DIV(0, "dout_aclk400_isp", "mout_aclk400_isp", DIV_TOP0, 0, 3),
-       DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3),
-       DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3),
-       DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3),
-       DIV(0, "dout_aclk100_noc", "mout_aclk100_noc", DIV_TOP0, 20, 3),
-       DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3),
-       DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3),
-
-       DIV(0, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl",
-                       DIV_TOP1, 0, 3),
-       DIV(0, "dout_aclk333_432_isp", "mout_aclk333_432_isp",
-                       DIV_TOP1, 4, 3),
-       DIV(0, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6),
-       DIV(0, "dout_aclk333_432_isp0", "mout_aclk333_432_isp0",
-                       DIV_TOP1, 16, 3),
-       DIV(0, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3),
-       DIV(0, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3),
-       DIV(0, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3),
-
-       DIV(0, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3),
-       DIV(0, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3),
-       DIV(0, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3),
-       DIV(0, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3),
-       DIV(0, "dout_aclk300_disp1", "mout_aclk300_disp1", DIV_TOP2, 24, 3),
-       DIV(0, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3),
+       DIV(CLK_DOUT_ACLK400_ISP, "dout_aclk400_isp", "mout_aclk400_isp",
+                       DIV_TOP0, 0, 3),
+       DIV(CLK_DOUT_ACLK400_MSCL, "dout_aclk400_mscl", "mout_aclk400_mscl",
+                       DIV_TOP0, 4, 3),
+       DIV(CLK_DOUT_ACLK200, "dout_aclk200", "mout_aclk200",
+                       DIV_TOP0, 8, 3),
+       DIV(CLK_DOUT_ACLK200_FSYS2, "dout_aclk200_fsys2", "mout_aclk200_fsys2",
+                       DIV_TOP0, 12, 3),
+       DIV(CLK_DOUT_ACLK100_NOC, "dout_aclk100_noc", "mout_aclk100_noc",
+                       DIV_TOP0, 20, 3),
+       DIV(CLK_DOUT_PCLK200_FSYS, "dout_pclk200_fsys", "mout_pclk200_fsys",
+                       DIV_TOP0, 24, 3),
+       DIV(CLK_DOUT_ACLK200_FSYS, "dout_aclk200_fsys", "mout_aclk200_fsys",
+                       DIV_TOP0, 28, 3),
+       DIV(CLK_DOUT_ACLK333_432_GSCL, "dout_aclk333_432_gscl",
+                       "mout_aclk333_432_gscl", DIV_TOP1, 0, 3),
+       DIV(CLK_DOUT_ACLK333_432_ISP, "dout_aclk333_432_isp",
+                       "mout_aclk333_432_isp", DIV_TOP1, 4, 3),
+       DIV(CLK_DOUT_ACLK66, "dout_aclk66", "mout_aclk66",
+                       DIV_TOP1, 8, 6),
+       DIV(CLK_DOUT_ACLK333_432_ISP0, "dout_aclk333_432_isp0",
+                       "mout_aclk333_432_isp0", DIV_TOP1, 16, 3),
+       DIV(CLK_DOUT_ACLK266, "dout_aclk266", "mout_aclk266",
+                       DIV_TOP1, 20, 3),
+       DIV(CLK_DOUT_ACLK166, "dout_aclk166", "mout_aclk166",
+                       DIV_TOP1, 24, 3),
+       DIV(CLK_DOUT_ACLK333, "dout_aclk333", "mout_aclk333",
+                       DIV_TOP1, 28, 3),
+
+       DIV(CLK_DOUT_ACLK333_G2D, "dout_aclk333_g2d", "mout_aclk333_g2d",
+                       DIV_TOP2, 8, 3),
+       DIV(CLK_DOUT_ACLK266_G2D, "dout_aclk266_g2d", "mout_aclk266_g2d",
+                       DIV_TOP2, 12, 3),
+       DIV(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2,
+                       16, 3),
+       DIV(CLK_DOUT_ACLK300_JPEG, "dout_aclk300_jpeg", "mout_aclk300_jpeg",
+                       DIV_TOP2, 20, 3),
+       DIV(CLK_DOUT_ACLK300_DISP1, "dout_aclk300_disp1",
+                       "mout_aclk300_disp1", DIV_TOP2, 24, 3),
+       DIV(CLK_DOUT_ACLK300_GSCL, "dout_aclk300_gscl", "mout_aclk300_gscl",
+                       DIV_TOP2, 28, 3),
 
        /* DISP1 Block */
        DIV(0, "dout_fimd1", "mout_fimd1_final", DIV_DISP10, 0, 4),
@@ -817,7 +833,8 @@ static struct samsung_div_clock exynos5x_div_clks[] __initdata = {
        DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
        DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
        DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2),
-       DIV(0, "dout_aclk400_disp1", "mout_aclk400_disp1", DIV_TOP2, 4, 3),
+       DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1",
+                       "mout_aclk400_disp1", DIV_TOP2, 4, 3),
 
        /* Audio Block */
        DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
index c5eaa9d1624760f6db1347cdbeaf44c7b97a2049..665fa681b2e1e9a2ccb2f2f857d76e98c3e3da64 100644 (file)
@@ -130,10 +130,9 @@ static void __init atlas6_clk_init(struct device_node *np)
                panic("unable to map clkc registers\n");
 
        /* These are always available (RTC and 26MHz OSC)*/
-       atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
-               CLK_IS_ROOT, 32768);
-       atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
-               CLK_IS_ROOT, 26000000);
+       atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
+       atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0,
+                                                  26000000);
 
        for (i = pll1; i < maxclk; i++) {
                atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
index 957aae63e7cce2796417a96555ed5cf43bff11fd..d0c6c9a2d06ae7d87cc5fe6b1d5866e33508e314 100644 (file)
@@ -1423,7 +1423,7 @@ static int atlas7_reset_module(struct reset_controller_dev *rcdev,
        return 0;
 }
 
-static struct reset_control_ops atlas7_rst_ops = {
+static const struct reset_control_ops atlas7_rst_ops = {
        .reset = atlas7_reset_module,
 };
 
index f92c40264342574af6fbf2af02de0e3db4236602..aac1c8ec151a9aff5a962e447aeb46bf680f269b 100644 (file)
@@ -129,10 +129,9 @@ static void __init prima2_clk_init(struct device_node *np)
                panic("unable to map clkc registers\n");
 
        /* These are always available (RTC and 26MHz OSC)*/
-       prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
-               CLK_IS_ROOT, 32768);
-       prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
-               CLK_IS_ROOT, 26000000);
+       prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
+       prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0,
+                                                  26000000);
 
        for (i = pll1; i < maxclk; i++) {
                prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
index 6b598c6a02136d64bee24e23bc0d61ec8d8733c6..dca532431394d3010e801bf6207531e72eac6c26 100644 (file)
@@ -54,8 +54,7 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
                        NULL, 0,
                        NULL, NULL,
                        &fixed->hw, &clk_fixed_rate_ops,
-                       &gate->hw, &clk_gate_ops,
-                       CLK_IS_ROOT);
+                       &gate->hw, &clk_gate_ops, 0);
 
        if (IS_ERR(clk))
                goto err_free_gate;
index 044c1717b762a6568c22d5929fb0a5713094475b..d9ea22ec4e258b0dc29024d1549086b89a668852 100644 (file)
@@ -85,7 +85,7 @@ static int sunxi_ve_of_xlate(struct reset_controller_dev *rcdev,
        return 0;
 }
 
-static struct reset_control_ops sunxi_ve_reset_ops = {
+static const struct reset_control_ops sunxi_ve_reset_ops = {
        .assert         = sunxi_ve_reset_assert,
        .deassert       = sunxi_ve_reset_deassert,
 };
index a9b176139aca8b159329e25ef76b805825423229..028dd832a39f6f75b93021e4cd12ea5b7cc586f9 100644 (file)
@@ -83,7 +83,7 @@ static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev,
        return 0;
 }
 
-static struct reset_control_ops sun9i_mmc_reset_ops = {
+static const struct reset_control_ops sun9i_mmc_reset_ops = {
        .assert         = sun9i_mmc_reset_assert,
        .deassert       = sun9i_mmc_reset_deassert,
 };
index 5432b1c198a4e2fc77825d21f9382eee30b2249c..fe0c3d169377272bccde5f8464429a9ea5ef43de 100644 (file)
@@ -76,7 +76,7 @@ static int sunxi_usb_reset_deassert(struct reset_controller_dev *rcdev,
        return 0;
 }
 
-static struct reset_control_ops sunxi_usb_reset_ops = {
+static const struct reset_control_ops sunxi_usb_reset_ops = {
        .assert         = sunxi_usb_reset_assert,
        .deassert       = sunxi_usb_reset_deassert,
 };
index 98e65ca9f92566f58d396428c0145e3202df8d4f..b2cdd9a235f435355a18efd06601b8ddfde9bce1 100644 (file)
@@ -271,7 +271,7 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
        }
 }
 
-static struct reset_control_ops rst_ops = {
+static const struct reset_control_ops rst_ops = {
        .assert = tegra_clk_rst_assert,
        .deassert = tegra_clk_rst_deassert,
 };
index 59ce2fa2c104a3a79e1cd490962a04aca8f2ab28..294bc03ec067d58949e97d551200a92e7091ff0f 100644 (file)
@@ -210,6 +210,7 @@ static struct ti_dt_clk omap54xx_clks[] = {
        DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
        DT_CLK("omap_wdt", "ick", "dummy_ck"),
        DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
+       DT_CLK(NULL, "sys_clkin_ck", "sys_clkin"),
        DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin"),
        DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin"),
        DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin"),
index a911d7de33778d7bc7648e59f0ee60c1a6c83027..87a87b5089ea23152e6a25b4a90692bea4f508ad 100644 (file)
@@ -289,6 +289,7 @@ static struct ti_dt_clk dra7xx_clks[] = {
        DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
        DT_CLK("omap_wdt", "ick", "dummy_ck"),
        DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
+       DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"),
        DT_CLK("4ae18000.timer", "timer_sys_ck", "timer_sys_clk_div"),
        DT_CLK("48032000.timer", "timer_sys_ck", "timer_sys_clk_div"),
        DT_CLK("48034000.timer", "timer_sys_ck", "timer_sys_clk_div"),
index 2e14dfb588f445f7cb2a3d3c997c6786ca67a3de..c77333230bdf22d20dac90611aa4461a28c86321 100644 (file)
@@ -265,6 +265,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
 
                /* Get configuration for the ATL instances */
                snprintf(prop, sizeof(prop), "atl%u", i);
+               of_node_get(node);
                cfg_node = of_find_node_by_name(node, prop);
                if (cfg_node) {
                        ret = of_property_read_u32(cfg_node, "bws",
@@ -278,6 +279,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
                                atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i),
                                          cdesc->aws);
                        }
+                       of_node_put(cfg_node);
                }
 
                cdesc->probed = true;
index 1ddc288fce4eb123e63d941971bc94bff41f69a5..c6ae563801d716636da5b96b178ca40e45ec12fb 100644 (file)
@@ -222,7 +222,7 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
                }
        }
 
-       if (unlikely(IS_ERR(clk->enable_reg))) {
+       if (IS_ERR(clk->enable_reg)) {
                pr_err("%s: %s missing enable_reg\n", __func__,
                       clk_hw_get_name(hw));
                ret = -EINVAL;
index 032c658a5f5ef6619108f66458f119ad924160a3..b919fdfe82560ed96cab55995e1f83e968d08edb 100644 (file)
@@ -301,6 +301,9 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
 
        dd = clk->dpll_data;
 
+       if (dd->max_rate && target_rate > dd->max_rate)
+               target_rate = dd->max_rate;
+
        ref_rate = clk_hw_get_rate(dd->clk_ref);
        clk_name = clk_hw_get_name(hw);
        pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
index 3bc9959f71c39f78a8e28772fe4ae7548ca030bb..9fc8754a6e6160081c067a5a96b364b8bf0ec40a 100644 (file)
@@ -655,6 +655,7 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
                .max_multiplier = 2047,
                .max_divider = 128,
                .min_divider = 1,
+               .max_rate = 1000000000,
                .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
        };
 
@@ -674,6 +675,7 @@ static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
                .max_divider = 256,
                .min_divider = 2,
                .flags = DPLL_J_TYPE,
+               .max_rate = 2000000000,
                .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
        };
 
@@ -692,6 +694,7 @@ static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
                .max_multiplier = 2047,
                .max_divider = 128,
                .min_divider = 1,
+               .max_rate = 2000000000,
                .flags = DPLL_J_TYPE,
                .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
        };
@@ -712,6 +715,7 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node)
                .max_multiplier = 2047,
                .max_divider = 128,
                .min_divider = 1,
+               .max_rate = 1000000000,
                .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
        };
 
@@ -729,6 +733,7 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
                .max_multiplier = 2047,
                .max_divider = 128,
                .min_divider = 1,
+               .max_rate = 1000000000,
                .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
        };
 
index ebd20d852e733ea788269246f20f3ccb02acae6a..76e967c19775740238da5ecbab360d969cc08e3d 100644 (file)
@@ -234,8 +234,7 @@ static void __init zx296702_top_clocks_init(struct device_node *np)
        WARN_ON(!topcrm_base);
 
        clk[ZX296702_OSC] =
-               clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT,
-                               30000000);
+               clk_register_fixed_rate(NULL, "osc", NULL, 0, 30000000);
        clk[ZX296702_PLL_A9] =
                clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base
                                + 0x01c, pll_a9_config,
diff --git a/include/dt-bindings/clock/axis,artpec6-clkctrl.h b/include/dt-bindings/clock/axis,artpec6-clkctrl.h
new file mode 100644 (file)
index 0000000..f9f04dc
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * ARTPEC-6 clock controller indexes
+ *
+ * Copyright 2016 Axis Comunications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef DT_BINDINGS_CLK_ARTPEC6_CLKCTRL_H
+#define DT_BINDINGS_CLK_ARTPEC6_CLKCTRL_H
+
+#define ARTPEC6_CLK_CPU                        0
+#define ARTPEC6_CLK_CPU_PERIPH         1
+#define ARTPEC6_CLK_NAND_CLKA          2
+#define ARTPEC6_CLK_NAND_CLKB          3
+#define ARTPEC6_CLK_ETH_ACLK           4
+#define ARTPEC6_CLK_DMA_ACLK           5
+#define ARTPEC6_CLK_PTP_REF            6
+#define ARTPEC6_CLK_SD_PCLK            7
+#define ARTPEC6_CLK_SD_IMCLK           8
+#define ARTPEC6_CLK_I2S_HST            9
+#define ARTPEC6_CLK_I2S0_CLK           10
+#define ARTPEC6_CLK_I2S1_CLK           11
+#define ARTPEC6_CLK_UART_PCLK          12
+#define ARTPEC6_CLK_UART_REFCLK                13
+#define ARTPEC6_CLK_I2C                        14
+#define ARTPEC6_CLK_SPI_PCLK           15
+#define ARTPEC6_CLK_SPI_SSPCLK         16
+#define ARTPEC6_CLK_SYS_TIMER          17
+#define ARTPEC6_CLK_FRACDIV_IN         18
+#define ARTPEC6_CLK_DBG_PCLK           19
+
+/* This must be the highest clock index plus one. */
+#define ARTPEC6_CLK_NUMCLOCKS          20
+
+#endif
index 61f1d20c2a6735f2b90c69bcbc68b8a759e3981a..360e00cefd35679b49890234b5c369fb52b89e20 100644 (file)
 #define BCM2835_CLOCK_EMMC             28
 #define BCM2835_CLOCK_PERI_IMAGE       29
 #define BCM2835_CLOCK_PWM              30
+#define BCM2835_CLOCK_PCM              31
 
-#define BCM2835_CLOCK_COUNT            31
+#define BCM2835_PLLA_DSI0              32
+#define BCM2835_PLLA_CCP2              33
+#define BCM2835_PLLD_DSI0              34
+#define BCM2835_PLLD_DSI1              35
+
+#define BCM2835_CLOCK_AVEO             36
+#define BCM2835_CLOCK_DFT              37
+#define BCM2835_CLOCK_GP0              38
+#define BCM2835_CLOCK_GP1              39
+#define BCM2835_CLOCK_GP2              40
+#define BCM2835_CLOCK_SLIM             41
+#define BCM2835_CLOCK_SMI              42
+#define BCM2835_CLOCK_TEC              43
+#define BCM2835_CLOCK_DPI              44
+#define BCM2835_CLOCK_CAM0             45
+#define BCM2835_CLOCK_CAM1             46
+#define BCM2835_CLOCK_DSI0E            47
+#define BCM2835_CLOCK_DSI1E            48
index 63d01c15d2b368f63114622c2fac1eb51977eee7..c796ff02ceeb10829a70680adb4f585a0dee1752 100644 (file)
@@ -79,6 +79,8 @@
 #define CLK_MOUT_CORE                  58
 #define CLK_MOUT_APLL                  59
 #define CLK_MOUT_ACLK_266_SUB          60
+#define CLK_MOUT_UART2                 61
+#define CLK_MOUT_MMC2                  62
 
 /* Dividers */
 #define CLK_DIV_GPL                    64
 #define CLK_DIV_CORE                   107
 #define CLK_DIV_HPM                    108
 #define CLK_DIV_COPY                   109
+#define CLK_DIV_UART2                  110
+#define CLK_DIV_MMC2_PRE               111
+#define CLK_DIV_MMC2                   112
 
 /* Gates */
 #define CLK_ASYNC_G3D                  128
 #define CLK_BLOCK_MFC                  219
 #define CLK_BLOCK_CAM                  220
 #define CLK_SMIES                      221
+#define CLK_UART2                      222
+#define CLK_SDMMC2                     223
 
 /* Special clocks */
 #define CLK_SCLK_JPEG                  224
 #define CLK_SCLK_SPI0                  245
 #define CLK_SCLK_UART1                 246
 #define CLK_SCLK_UART0                 247
+#define CLK_SCLK_UART2                 248
+#define CLK_SCLK_MMC2                  249
 
 /*
  * Total number of clocks of main CMU.
  * NOTE: Must be equal to last clock ID increased by one.
  */
-#define CLK_NR_CLKS                    248
+#define CLK_NR_CLKS                    250
 
 /*
  * CMU DMC
index 7699ee9c16c02a6d3f63808a0720aeb073e70370..17ab8394bec7d8abf4d4448656d143cabeaf5651 100644 (file)
 
 /* divider clocks */
 #define CLK_DOUT_PIXEL         768
+#define CLK_DOUT_ACLK400_WCORE 769
+#define CLK_DOUT_ACLK400_ISP   770
+#define CLK_DOUT_ACLK400_MSCL  771
+#define CLK_DOUT_ACLK200       772
+#define CLK_DOUT_ACLK200_FSYS2 773
+#define CLK_DOUT_ACLK100_NOC   774
+#define CLK_DOUT_PCLK200_FSYS  775
+#define CLK_DOUT_ACLK200_FSYS  776
+#define CLK_DOUT_ACLK333_432_GSCL      777
+#define CLK_DOUT_ACLK333_432_ISP       778
+#define CLK_DOUT_ACLK66                779
+#define CLK_DOUT_ACLK333_432_ISP0      780
+#define CLK_DOUT_ACLK266       781
+#define CLK_DOUT_ACLK166       782
+#define CLK_DOUT_ACLK333       783
+#define CLK_DOUT_ACLK333_G2D   784
+#define CLK_DOUT_ACLK266_G2D   785
+#define CLK_DOUT_ACLK_G3D      786
+#define CLK_DOUT_ACLK300_JPEG  787
+#define CLK_DOUT_ACLK300_DISP1 788
+#define CLK_DOUT_ACLK300_GSCL  789
+#define CLK_DOUT_ACLK400_DISP1 790
 
 /* must be greater than maximal clock id */
-#define CLK_NR_CLKS            769
+#define CLK_NR_CLKS            791
 
 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */
index edca8985c50e82e3d1d495d773194ef045f6f036..1183347c383fe10d28f6c9171021283a2fefc4b8 100644 (file)
 #define IMX7D_PLL_DRAM_TEST_DIV                435
 #define IMX7D_ADC_ROOT_CLK             436
 #define IMX7D_CLK_ARM                  437
-#define IMX7D_CLK_END                  438
+#define IMX7D_CKIL                     438
+#define IMX7D_CLK_END                  439
 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
new file mode 100644 (file)
index 0000000..50a44cf
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3399_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3399_H
+
+/* core clocks */
+#define PLL_APLLL                      1
+#define PLL_APLLB                      2
+#define PLL_DPLL                       3
+#define PLL_CPLL                       4
+#define PLL_GPLL                       5
+#define PLL_NPLL                       6
+#define PLL_VPLL                       7
+#define ARMCLKL                                8
+#define ARMCLKB                                9
+
+/* sclk gates (special clocks) */
+#define SCLK_I2C1                      65
+#define SCLK_I2C2                      66
+#define SCLK_I2C3                      67
+#define SCLK_I2C5                      68
+#define SCLK_I2C6                      69
+#define SCLK_I2C7                      70
+#define SCLK_SPI0                      71
+#define SCLK_SPI1                      72
+#define SCLK_SPI2                      73
+#define SCLK_SPI4                      74
+#define SCLK_SPI5                      75
+#define SCLK_SDMMC                     76
+#define SCLK_SDIO                      77
+#define SCLK_EMMC                      78
+#define SCLK_TSADC                     79
+#define SCLK_SARADC                    80
+#define SCLK_UART0                     81
+#define SCLK_UART1                     82
+#define SCLK_UART2                     83
+#define SCLK_UART3                     84
+#define SCLK_SPDIF_8CH                 85
+#define SCLK_I2S0_8CH                  86
+#define SCLK_I2S1_8CH                  87
+#define SCLK_I2S2_8CH                  88
+#define SCLK_I2S_8CH_OUT               89
+#define SCLK_TIMER00                   90
+#define SCLK_TIMER01                   91
+#define SCLK_TIMER02                   92
+#define SCLK_TIMER03                   93
+#define SCLK_TIMER04                   94
+#define SCLK_TIMER05                   95
+#define SCLK_TIMER06                   96
+#define SCLK_TIMER07                   97
+#define SCLK_TIMER08                   98
+#define SCLK_TIMER09                   99
+#define SCLK_TIMER10                   100
+#define SCLK_TIMER11                   101
+#define SCLK_MACREF                    102
+#define SCLK_MAC_RX                    103
+#define SCLK_MAC_TX                    104
+#define SCLK_MAC                       105
+#define SCLK_MACREF_OUT                        106
+#define SCLK_VOP0_PWM                  107
+#define SCLK_VOP1_PWM                  108
+#define SCLK_RGA_CORE                  109
+#define SCLK_ISP0                      110
+#define SCLK_ISP1                      111
+#define SCLK_HDMI_CEC                  112
+#define SCLK_HDMI_SFR                  113
+#define SCLK_DP_CORE                   114
+#define SCLK_PVTM_CORE_L               115
+#define SCLK_PVTM_CORE_B               116
+#define SCLK_PVTM_GPU                  117
+#define SCLK_PVTM_DDR                  118
+#define SCLK_MIPIDPHY_REF              119
+#define SCLK_MIPIDPHY_CFG              120
+#define SCLK_HSICPHY                   121
+#define SCLK_USBPHY480M                        122
+#define SCLK_USB2PHY0_REF              123
+#define SCLK_USB2PHY1_REF              124
+#define SCLK_UPHY0_TCPDPHY_REF         125
+#define SCLK_UPHY0_TCPDCORE            126
+#define SCLK_UPHY1_TCPDPHY_REF         127
+#define SCLK_UPHY1_TCPDCORE            128
+#define SCLK_USB3OTG0_REF              129
+#define SCLK_USB3OTG1_REF              130
+#define SCLK_USB3OTG0_SUSPEND          131
+#define SCLK_USB3OTG1_SUSPEND          132
+#define SCLK_CRYPTO0                   133
+#define SCLK_CRYPTO1                   134
+#define SCLK_CCI_TRACE                 135
+#define SCLK_CS                                136
+#define SCLK_CIF_OUT                   137
+#define SCLK_PCIEPHY_REF               138
+#define SCLK_PCIE_CORE                 139
+#define SCLK_M0_PERILP                 140
+#define SCLK_M0_PERILP_DEC             141
+#define SCLK_CM0S                      142
+#define SCLK_DBG_NOC                   143
+#define SCLK_DBG_PD_CORE_B             144
+#define SCLK_DBG_PD_CORE_L             145
+#define SCLK_DFIMON0_TIMER             146
+#define SCLK_DFIMON1_TIMER             147
+#define SCLK_INTMEM0                   148
+#define SCLK_INTMEM1                   149
+#define SCLK_INTMEM2                   150
+#define SCLK_INTMEM3                   151
+#define SCLK_INTMEM4                   152
+#define SCLK_INTMEM5                   153
+#define SCLK_SDMMC_DRV                 154
+#define SCLK_SDMMC_SAMPLE              155
+#define SCLK_SDIO_DRV                  156
+#define SCLK_SDIO_SAMPLE               157
+#define SCLK_VDU_CORE                  158
+#define SCLK_VDU_CA                    159
+#define SCLK_PCIE_PM                   160
+#define SCLK_SPDIF_REC_DPTX            161
+#define SCLK_DPHY_PLL                  162
+#define SCLK_DPHY_TX0_CFG              163
+#define SCLK_DPHY_TX1RX1_CFG           164
+#define SCLK_DPHY_RX0_CFG              165
+#define SCLK_RMII_SRC                  166
+#define SCLK_PCIEPHY_REF100M           167
+
+#define DCLK_VOP0                      180
+#define DCLK_VOP1                      181
+#define DCLK_VOP0_DIV                  182
+#define DCLK_VOP1_DIV                  183
+#define DCLK_M0_PERILP                 184
+
+#define FCLK_CM0S                      190
+
+/* aclk gates */
+#define ACLK_PERIHP                    192
+#define ACLK_PERIHP_NOC                        193
+#define ACLK_PERILP0                   194
+#define ACLK_PERILP0_NOC               195
+#define ACLK_PERF_PCIE                 196
+#define ACLK_PCIE                      197
+#define ACLK_INTMEM                    198
+#define ACLK_TZMA                      199
+#define ACLK_DCF                       200
+#define ACLK_CCI                       201
+#define ACLK_CCI_NOC0                  202
+#define ACLK_CCI_NOC1                  203
+#define ACLK_CCI_GRF                   204
+#define ACLK_CENTER                    205
+#define ACLK_CENTER_MAIN_NOC           206
+#define ACLK_CENTER_PERI_NOC           207
+#define ACLK_GPU                       208
+#define ACLK_PERF_GPU                  209
+#define ACLK_GPU_GRF                   210
+#define ACLK_DMAC0_PERILP              211
+#define ACLK_DMAC1_PERILP              212
+#define ACLK_GMAC                      213
+#define ACLK_GMAC_NOC                  214
+#define ACLK_PERF_GMAC                 215
+#define ACLK_VOP0_NOC                  216
+#define ACLK_VOP0                      217
+#define ACLK_VOP1_NOC                  218
+#define ACLK_VOP1                      219
+#define ACLK_RGA                       220
+#define ACLK_RGA_NOC                   221
+#define ACLK_HDCP                      222
+#define ACLK_HDCP_NOC                  223
+#define ACLK_HDCP22                    224
+#define ACLK_IEP                       225
+#define ACLK_IEP_NOC                   226
+#define ACLK_VIO                       227
+#define ACLK_VIO_NOC                   228
+#define ACLK_ISP0                      229
+#define ACLK_ISP1                      230
+#define ACLK_ISP0_NOC                  231
+#define ACLK_ISP1_NOC                  232
+#define ACLK_ISP0_WRAPPER              233
+#define ACLK_ISP1_WRAPPER              234
+#define ACLK_VCODEC                    235
+#define ACLK_VCODEC_NOC                        236
+#define ACLK_VDU                       237
+#define ACLK_VDU_NOC                   238
+#define ACLK_PERI                      239
+#define ACLK_EMMC                      240
+#define ACLK_EMMC_CORE                 241
+#define ACLK_EMMC_NOC                  242
+#define ACLK_EMMC_GRF                  243
+#define ACLK_USB3                      244
+#define ACLK_USB3_NOC                  245
+#define ACLK_USB3OTG0                  246
+#define ACLK_USB3OTG1                  247
+#define ACLK_USB3_RKSOC_AXI_PERF       248
+#define ACLK_USB3_GRF                  249
+#define ACLK_GIC                       250
+#define ACLK_GIC_NOC                   251
+#define ACLK_GIC_ADB400_CORE_L_2_GIC   252
+#define ACLK_GIC_ADB400_CORE_B_2_GIC   253
+#define ACLK_GIC_ADB400_GIC_2_CORE_L   254
+#define ACLK_GIC_ADB400_GIC_2_CORE_B   255
+#define ACLK_CORE_ADB400_CORE_L_2_CCI500 256
+#define ACLK_CORE_ADB400_CORE_B_2_CCI500 257
+#define ACLK_ADB400M_PD_CORE_L         258
+#define ACLK_ADB400M_PD_CORE_B         259
+#define ACLK_PERF_CORE_L               260
+#define ACLK_PERF_CORE_B               261
+#define ACLK_GIC_PRE                   262
+#define ACLK_VOP0_PRE                  263
+#define ACLK_VOP1_PRE                  264
+
+/* pclk gates */
+#define PCLK_PERIHP                    320
+#define PCLK_PERIHP_NOC                        321
+#define PCLK_PERILP0                   322
+#define PCLK_PERILP1                   323
+#define PCLK_PERILP1_NOC               324
+#define PCLK_PERILP_SGRF               325
+#define PCLK_PERIHP_GRF                        326
+#define PCLK_PCIE                      327
+#define PCLK_SGRF                      328
+#define PCLK_INTR_ARB                  329
+#define PCLK_CENTER_MAIN_NOC           330
+#define PCLK_CIC                       331
+#define PCLK_COREDBG_B                 332
+#define PCLK_COREDBG_L                 333
+#define PCLK_DBG_CXCS_PD_CORE_B                334
+#define PCLK_DCF                       335
+#define PCLK_GPIO2                     336
+#define PCLK_GPIO3                     337
+#define PCLK_GPIO4                     338
+#define PCLK_GRF                       339
+#define PCLK_HSICPHY                   340
+#define PCLK_I2C1                      341
+#define PCLK_I2C2                      342
+#define PCLK_I2C3                      343
+#define PCLK_I2C5                      344
+#define PCLK_I2C6                      345
+#define PCLK_I2C7                      346
+#define PCLK_SPI0                      347
+#define PCLK_SPI1                      348
+#define PCLK_SPI2                      349
+#define PCLK_SPI4                      350
+#define PCLK_SPI5                      351
+#define PCLK_UART0                     352
+#define PCLK_UART1                     353
+#define PCLK_UART2                     354
+#define PCLK_UART3                     355
+#define PCLK_TSADC                     356
+#define PCLK_SARADC                    357
+#define PCLK_GMAC                      358
+#define PCLK_GMAC_NOC                  359
+#define PCLK_TIMER0                    360
+#define PCLK_TIMER1                    361
+#define PCLK_EDP                       362
+#define PCLK_EDP_NOC                   363
+#define PCLK_EDP_CTRL                  364
+#define PCLK_VIO                       365
+#define PCLK_VIO_NOC                   366
+#define PCLK_VIO_GRF                   367
+#define PCLK_MIPI_DSI0                 368
+#define PCLK_MIPI_DSI1                 369
+#define PCLK_HDCP                      370
+#define PCLK_HDCP_NOC                  371
+#define PCLK_HDMI_CTRL                 372
+#define PCLK_DP_CTRL                   373
+#define PCLK_HDCP22                    374
+#define PCLK_GASKET                    375
+#define PCLK_DDR                       376
+#define PCLK_DDR_MON                   377
+#define PCLK_DDR_SGRF                  378
+#define PCLK_ISP1_WRAPPER              379
+#define PCLK_WDT                       380
+#define PCLK_EFUSE1024NS               381
+#define PCLK_EFUSE1024S                        382
+#define PCLK_PMU_INTR_ARB              383
+#define PCLK_MAILBOX0                  384
+#define PCLK_USBPHY_MUX_G              385
+#define PCLK_UPHY0_TCPHY_G             386
+#define PCLK_UPHY0_TCPD_G              387
+#define PCLK_UPHY1_TCPHY_G             388
+#define PCLK_UPHY1_TCPD_G              389
+#define PCLK_ALIVE                     390
+
+/* hclk gates */
+#define HCLK_PERIHP                    448
+#define HCLK_PERILP0                   449
+#define HCLK_PERILP1                   450
+#define HCLK_PERILP0_NOC               451
+#define HCLK_PERILP1_NOC               452
+#define HCLK_M0_PERILP                 453
+#define HCLK_M0_PERILP_NOC             454
+#define HCLK_AHB1TOM                   455
+#define HCLK_HOST0                     456
+#define HCLK_HOST0_ARB                 457
+#define HCLK_HOST1                     458
+#define HCLK_HOST1_ARB                 459
+#define HCLK_HSIC                      460
+#define HCLK_SD                                461
+#define HCLK_SDMMC                     462
+#define HCLK_SDMMC_NOC                 463
+#define HCLK_M_CRYPTO0                 464
+#define HCLK_M_CRYPTO1                 465
+#define HCLK_S_CRYPTO0                 466
+#define HCLK_S_CRYPTO1                 467
+#define HCLK_I2S0_8CH                  468
+#define HCLK_I2S1_8CH                  469
+#define HCLK_I2S2_8CH                  470
+#define HCLK_SPDIF                     471
+#define HCLK_VOP0_NOC                  472
+#define HCLK_VOP0                      473
+#define HCLK_VOP1_NOC                  474
+#define HCLK_VOP1                      475
+#define HCLK_ROM                       476
+#define HCLK_IEP                       477
+#define HCLK_IEP_NOC                   478
+#define HCLK_ISP0                      479
+#define HCLK_ISP1                      480
+#define HCLK_ISP0_NOC                  481
+#define HCLK_ISP1_NOC                  482
+#define HCLK_ISP0_WRAPPER              483
+#define HCLK_ISP1_WRAPPER              484
+#define HCLK_RGA                       485
+#define HCLK_RGA_NOC                   486
+#define HCLK_HDCP                      487
+#define HCLK_HDCP_NOC                  488
+#define HCLK_HDCP22                    489
+#define HCLK_VCODEC                    490
+#define HCLK_VCODEC_NOC                        491
+#define HCLK_VDU                       492
+#define HCLK_VDU_NOC                   493
+#define HCLK_SDIO                      494
+#define HCLK_SDIO_NOC                  495
+#define HCLK_SDIOAUDIO_NOC             496
+
+#define CLK_NR_CLKS                    (HCLK_SDIOAUDIO_NOC + 1)
+
+/* pmu-clocks indices */
+
+#define PLL_PPLL                       1
+
+#define SCLK_32K_SUSPEND_PMU           2
+#define SCLK_SPI3_PMU                  3
+#define SCLK_TIMER12_PMU               4
+#define SCLK_TIMER13_PMU               5
+#define SCLK_UART4_PMU                 6
+#define SCLK_PVTM_PMU                  7
+#define SCLK_WIFI_PMU                  8
+#define SCLK_I2C0_PMU                  9
+#define SCLK_I2C4_PMU                  10
+#define SCLK_I2C8_PMU                  11
+
+#define PCLK_SRC_PMU                   19
+#define PCLK_PMU                       20
+#define PCLK_PMUGRF_PMU                        21
+#define PCLK_INTMEM1_PMU               22
+#define PCLK_GPIO0_PMU                 23
+#define PCLK_GPIO1_PMU                 24
+#define PCLK_SGRF_PMU                  25
+#define PCLK_NOC_PMU                   26
+#define PCLK_I2C0_PMU                  27
+#define PCLK_I2C4_PMU                  28
+#define PCLK_I2C8_PMU                  29
+#define PCLK_RKPWM_PMU                 30
+#define PCLK_SPI3_PMU                  31
+#define PCLK_TIMER_PMU                 32
+#define PCLK_MAILBOX_PMU               33
+#define PCLK_UART4_PMU                 34
+#define PCLK_WDT_M0_PMU                        35
+
+#define FCLK_CM0S_SRC_PMU              44
+#define FCLK_CM0S_PMU                  45
+#define SCLK_CM0S_PMU                  46
+#define HCLK_CM0S_PMU                  47
+#define DCLK_CM0S_PMU                  48
+#define PCLK_INTR_ARB_PMU              49
+#define HCLK_NOC_PMU                   50
+
+#define CLKPMU_NR_CLKS                 (HCLK_NOC_PMU + 1)
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_CORE_L0                   0
+#define SRST_CORE_B0                   1
+#define SRST_CORE_PO_L0                        2
+#define SRST_CORE_PO_B0                        3
+#define SRST_L2_L                      4
+#define SRST_L2_B                      5
+#define SRST_ADB_L                     6
+#define SRST_ADB_B                     7
+#define SRST_A_CCI                     8
+#define SRST_A_CCIM0_NOC               9
+#define SRST_A_CCIM1_NOC               10
+#define SRST_DBG_NOC                   11
+
+/* cru_softrst_con1 */
+#define SRST_CORE_L0_T                 16
+#define SRST_CORE_L1                   17
+#define SRST_CORE_L2                   18
+#define SRST_CORE_L3                   19
+#define SRST_CORE_PO_L0_T              20
+#define SRST_CORE_PO_L1                        21
+#define SRST_CORE_PO_L2                        22
+#define SRST_CORE_PO_L3                        23
+#define SRST_A_ADB400_GIC2COREL                24
+#define SRST_A_ADB400_COREL2GIC                25
+#define SRST_P_DBG_L                   26
+#define SRST_L2_L_T                    28
+#define SRST_ADB_L_T                   29
+#define SRST_A_RKPERF_L                        30
+#define SRST_PVTM_CORE_L               31
+
+/* cru_softrst_con2 */
+#define SRST_CORE_B0_T                 32
+#define SRST_CORE_B1                   33
+#define SRST_CORE_PO_B0_T              36
+#define SRST_CORE_PO_B1                        37
+#define SRST_A_ADB400_GIC2COREB                40
+#define SRST_A_ADB400_COREB2GIC                41
+#define SRST_P_DBG_B                   42
+#define SRST_L2_B_T                    43
+#define SRST_ADB_B_T                   45
+#define SRST_A_RKPERF_B                        46
+#define SRST_PVTM_CORE_B               47
+
+/* cru_softrst_con3 */
+#define SRST_A_CCI_T                   50
+#define SRST_A_CCIM0_NOC_T             51
+#define SRST_A_CCIM1_NOC_T             52
+#define SRST_A_ADB400M_PD_CORE_B_T     53
+#define SRST_A_ADB400M_PD_CORE_L_T     54
+#define SRST_DBG_NOC_T                 55
+#define SRST_DBG_CXCS                  56
+#define SRST_CCI_TRACE                 57
+#define SRST_P_CCI_GRF                 58
+
+/* cru_softrst_con4 */
+#define SRST_A_CENTER_MAIN_NOC         64
+#define SRST_A_CENTER_PERI_NOC         65
+#define SRST_P_CENTER_MAIN             66
+#define SRST_P_DDRMON                  67
+#define SRST_P_CIC                     68
+#define SRST_P_CENTER_SGRF             69
+#define SRST_DDR0_MSCH                 70
+#define SRST_DDRCFG0_MSCH              71
+#define SRST_DDR0                      72
+#define SRST_DDRPHY0                   73
+#define SRST_DDR1_MSCH                 74
+#define SRST_DDRCFG1_MSCH              75
+#define SRST_DDR1                      76
+#define SRST_DDRPHY1                   77
+#define SRST_DDR_CIC                   78
+#define SRST_PVTM_DDR                  79
+
+/* cru_softrst_con5 */
+#define SRST_A_VCODEC_NOC              80
+#define SRST_A_VCODEC                  81
+#define SRST_H_VCODEC_NOC              82
+#define SRST_H_VCODEC                  83
+#define SRST_A_VDU_NOC                 88
+#define SRST_A_VDU                     89
+#define SRST_H_VDU_NOC                 90
+#define SRST_H_VDU                     91
+#define SRST_VDU_CORE                  92
+#define SRST_VDU_CA                    93
+
+/* cru_softrst_con6 */
+#define SRST_A_IEP_NOC                 96
+#define SRST_A_VOP_IEP                 97
+#define SRST_A_IEP                     98
+#define SRST_H_IEP_NOC                 99
+#define SRST_H_IEP                     100
+#define SRST_A_RGA_NOC                 102
+#define SRST_A_RGA                     103
+#define SRST_H_RGA_NOC                 104
+#define SRST_H_RGA                     105
+#define SRST_RGA_CORE                  106
+#define SRST_EMMC_NOC                  108
+#define SRST_EMMC                      109
+#define SRST_EMMC_GRF                  110
+
+/* cru_softrst_con7 */
+#define SRST_A_PERIHP_NOC              112
+#define SRST_P_PERIHP_GRF              113
+#define SRST_H_PERIHP_NOC              114
+#define SRST_USBHOST0                  115
+#define SRST_HOSTC0_AUX                        116
+#define SRST_HOST0_ARB                 117
+#define SRST_USBHOST1                  118
+#define SRST_HOSTC1_AUX                        119
+#define SRST_HOST1_ARB                 120
+#define SRST_SDIO0                     121
+#define SRST_SDMMC                     122
+#define SRST_HSIC                      123
+#define SRST_HSIC_AUX                  124
+#define SRST_AHB1TOM                   125
+#define SRST_P_PERIHP_NOC              126
+#define SRST_HSICPHY                   127
+
+/* cru_softrst_con8 */
+#define SRST_A_PCIE                    128
+#define SRST_P_PCIE                    129
+#define SRST_PCIE_CORE                 130
+#define SRST_PCIE_MGMT                 131
+#define SRST_PCIE_MGMT_STICKY          132
+#define SRST_PCIE_PIPE                 133
+#define SRST_PCIE_PM                   134
+#define SRST_PCIEPHY                   135
+#define SRST_A_GMAC_NOC                        136
+#define SRST_A_GMAC                    137
+#define SRST_P_GMAC_NOC                        138
+#define SRST_P_GMAC_GRF                        140
+#define SRST_HSICPHY_POR               142
+#define SRST_HSICPHY_UTMI              143
+
+/* cru_softrst_con9 */
+#define SRST_USB2PHY0_POR              144
+#define SRST_USB2PHY0_UTMI_PORT0       145
+#define SRST_USB2PHY0_UTMI_PORT1       146
+#define SRST_USB2PHY0_EHCIPHY          147
+#define SRST_UPHY0_PIPE_L00            148
+#define SRST_UPHY0                     149
+#define SRST_UPHY0_TCPDPWRUP           150
+#define SRST_USB2PHY1_POR              152
+#define SRST_USB2PHY1_UTMI_PORT0       153
+#define SRST_USB2PHY1_UTMI_PORT1       154
+#define SRST_USB2PHY1_EHCIPHY          155
+#define SRST_UPHY1_PIPE_L00            156
+#define SRST_UPHY1                     157
+#define SRST_UPHY1_TCPDPWRUP           158
+
+/* cru_softrst_con10 */
+#define SRST_A_PERILP0_NOC             160
+#define SRST_A_DCF                     161
+#define SRST_GIC500                    162
+#define SRST_DMAC0_PERILP0             163
+#define SRST_DMAC1_PERILP0             164
+#define SRST_TZMA                      165
+#define SRST_INTMEM                    166
+#define SRST_ADB400_MST0               167
+#define SRST_ADB400_MST1               168
+#define SRST_ADB400_SLV0               169
+#define SRST_ADB400_SLV1               170
+#define SRST_H_PERILP0                 171
+#define SRST_H_PERILP0_NOC             172
+#define SRST_ROM                       173
+#define SRST_CRYPTO_S                  174
+#define SRST_CRYPTO_M                  175
+
+/* cru_softrst_con11 */
+#define SRST_P_DCF                     176
+#define SRST_CM0S_NOC                  177
+#define SRST_CM0S                      178
+#define SRST_CM0S_DBG                  179
+#define SRST_CM0S_PO                   180
+#define SRST_CRYPTO                    181
+#define SRST_P_PERILP1_SGRF            182
+#define SRST_P_PERILP1_GRF             183
+#define SRST_CRYPTO1_S                 184
+#define SRST_CRYPTO1_M                 185
+#define SRST_CRYPTO1                   186
+#define SRST_GIC_NOC                   188
+#define SRST_SD_NOC                    189
+#define SRST_SDIOAUDIO_BRG             190
+
+/* cru_softrst_con12 */
+#define SRST_H_PERILP1                 192
+#define SRST_H_PERILP1_NOC             193
+#define SRST_H_I2S0_8CH                        194
+#define SRST_H_I2S1_8CH                        195
+#define SRST_H_I2S2_8CH                        196
+#define SRST_H_SPDIF_8CH               197
+#define SRST_P_PERILP1_NOC             198
+#define SRST_P_EFUSE_1024              199
+#define SRST_P_EFUSE_1024S             200
+#define SRST_P_I2C0                    201
+#define SRST_P_I2C1                    202
+#define SRST_P_I2C2                    203
+#define SRST_P_I2C3                    204
+#define SRST_P_I2C4                    205
+#define SRST_P_I2C5                    206
+#define SRST_P_MAILBOX0                        207
+
+/* cru_softrst_con13 */
+#define SRST_P_UART0                   208
+#define SRST_P_UART1                   209
+#define SRST_P_UART2                   210
+#define SRST_P_UART3                   211
+#define SRST_P_SARADC                  212
+#define SRST_P_TSADC                   213
+#define SRST_P_SPI0                    214
+#define SRST_P_SPI1                    215
+#define SRST_P_SPI2                    216
+#define SRST_P_SPI3                    217
+#define SRST_P_SPI4                    218
+#define SRST_SPI0                      219
+#define SRST_SPI1                      220
+#define SRST_SPI2                      221
+#define SRST_SPI3                      222
+#define SRST_SPI4                      223
+
+/* cru_softrst_con14 */
+#define SRST_I2S0_8CH                  224
+#define SRST_I2S1_8CH                  225
+#define SRST_I2S2_8CH                  226
+#define SRST_SPDIF_8CH                 227
+#define SRST_UART0                     228
+#define SRST_UART1                     229
+#define SRST_UART2                     230
+#define SRST_UART3                     231
+#define SRST_TSADC                     232
+#define SRST_I2C0                      233
+#define SRST_I2C1                      234
+#define SRST_I2C2                      235
+#define SRST_I2C3                      236
+#define SRST_I2C4                      237
+#define SRST_I2C5                      238
+#define SRST_SDIOAUDIO_NOC             239
+
+/* cru_softrst_con15 */
+#define SRST_A_VIO_NOC                 240
+#define SRST_A_HDCP_NOC                        241
+#define SRST_A_HDCP                    242
+#define SRST_H_HDCP_NOC                        243
+#define SRST_H_HDCP                    244
+#define SRST_P_HDCP_NOC                        245
+#define SRST_P_HDCP                    246
+#define SRST_P_HDMI_CTRL               247
+#define SRST_P_DP_CTRL                 248
+#define SRST_S_DP_CTRL                 249
+#define SRST_C_DP_CTRL                 250
+#define SRST_P_MIPI_DSI0               251
+#define SRST_P_MIPI_DSI1               252
+#define SRST_DP_CORE                   253
+#define SRST_DP_I2S                    254
+
+/* cru_softrst_con16 */
+#define SRST_GASKET                    256
+#define SRST_VIO_GRF                   258
+#define SRST_DPTX_SPDIF_REC            259
+#define SRST_HDMI_CTRL                 260
+#define SRST_HDCP_CTRL                 261
+#define SRST_A_ISP0_NOC                        262
+#define SRST_A_ISP1_NOC                        263
+#define SRST_H_ISP0_NOC                        266
+#define SRST_H_ISP1_NOC                        267
+#define SRST_H_ISP0                    268
+#define SRST_H_ISP1                    269
+#define SRST_ISP0                      270
+#define SRST_ISP1                      271
+
+/* cru_softrst_con17 */
+#define SRST_A_VOP0_NOC                        272
+#define SRST_A_VOP1_NOC                        273
+#define SRST_A_VOP0                    274
+#define SRST_A_VOP1                    275
+#define SRST_H_VOP0_NOC                        276
+#define SRST_H_VOP1_NOC                        277
+#define SRST_H_VOP0                    278
+#define SRST_H_VOP1                    279
+#define SRST_D_VOP0                    280
+#define SRST_D_VOP1                    281
+#define SRST_VOP0_PWM                  282
+#define SRST_VOP1_PWM                  283
+#define SRST_P_EDP_NOC                 284
+#define SRST_P_EDP_CTRL                        285
+
+/* cru_softrst_con18 */
+#define SRST_A_GPU                     288
+#define SRST_A_GPU_NOC                 289
+#define SRST_A_GPU_GRF                 290
+#define SRST_PVTM_GPU                  291
+#define SRST_A_USB3_NOC                        292
+#define SRST_A_USB3_OTG0               293
+#define SRST_A_USB3_OTG1               294
+#define SRST_A_USB3_GRF                        295
+#define SRST_PMU                       296
+
+/* cru_softrst_con19 */
+#define SRST_P_TIMER0_5                        304
+#define SRST_TIMER0                    305
+#define SRST_TIMER1                    306
+#define SRST_TIMER2                    307
+#define SRST_TIMER3                    308
+#define SRST_TIMER4                    309
+#define SRST_TIMER5                    310
+#define SRST_P_TIMER6_11               311
+#define SRST_TIMER6                    312
+#define SRST_TIMER7                    313
+#define SRST_TIMER8                    314
+#define SRST_TIMER9                    315
+#define SRST_TIMER10                   316
+#define SRST_TIMER11                   317
+#define SRST_P_INTR_ARB_PMU            318
+#define SRST_P_ALIVE_SGRF              319
+
+/* cru_softrst_con20 */
+#define SRST_P_GPIO2                   320
+#define SRST_P_GPIO3                   321
+#define SRST_P_GPIO4                   322
+#define SRST_P_GRF                     323
+#define SRST_P_ALIVE_NOC               324
+#define SRST_P_WDT0                    325
+#define SRST_P_WDT1                    326
+#define SRST_P_INTR_ARB                        327
+#define SRST_P_UPHY0_DPTX              328
+#define SRST_P_UPHY0_APB               330
+#define SRST_P_UPHY0_TCPHY             332
+#define SRST_P_UPHY1_TCPHY             333
+#define SRST_P_UPHY0_TCPDCTRL          334
+#define SRST_P_UPHY1_TCPDCTRL          335
+
+/* pmu soft-reset indices */
+
+/* pmu_cru_softrst_con0 */
+#define SRST_P_NOC                     0
+#define SRST_P_INTMEM                  1
+#define SRST_H_CM0S                    2
+#define SRST_H_CM0S_NOC                        3
+#define SRST_DBG_CM0S                  4
+#define SRST_PO_CM0S                   5
+#define SRST_P_SPI6                    6
+#define SRST_SPI6                      7
+#define SRST_P_TIMER_0_1               8
+#define SRST_P_TIMER_0                 9
+#define SRST_P_TIMER_1                 10
+#define SRST_P_UART4                   11
+#define SRST_UART4                     12
+#define SRST_P_WDT                     13
+
+/* pmu_cru_softrst_con1 */
+#define SRST_P_I2C6                    16
+#define SRST_P_I2C7                    17
+#define SRST_P_I2C8                    18
+#define SRST_P_MAILBOX                 19
+#define SRST_P_RKPWM                   20
+#define SRST_P_PMUGRF                  21
+#define SRST_P_SGRF                    22
+#define SRST_P_GPIO0                   23
+#define SRST_P_GPIO1                   24
+#define SRST_P_CRU                     25
+#define SRST_P_INTR                    26
+#define SRST_PVTM                      27
+#define SRST_I2C6                      28
+#define SRST_I2C7                      29
+#define SRST_I2C8                      30
+
+#endif
index 56c16aaea112c776543f1548936c55e6db49cb2b..45997750c8a02a8e4bf75ee6d3da305d0668e922 100644 (file)
 #define VF610_PLL7_BYPASS              181
 #define VF610_CLK_SNVS                 182
 #define VF610_CLK_DAP                  183
-#define VF610_CLK_OCOTP         184
-#define VF610_CLK_END                  185
+#define VF610_CLK_OCOTP                        184
+#define VF610_CLK_DDRMC                        185
+#define VF610_CLK_WKPU                 186
+#define VF610_CLK_TCON0                        187
+#define VF610_CLK_TCON1                        188
+#define VF610_CLK_END                  189
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
index da95258127aace556dc32810c0b483bcda95198f..0c72204c75fc9428f08c9e63667bf75dee0bc153 100644 (file)
@@ -32,6 +32,7 @@
 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
 #define CLK_RECALC_NEW_RATES   BIT(9) /* recalc rates after notifications */
 #define CLK_SET_RATE_UNGATE    BIT(10) /* clock needs to run to set rate */
+#define CLK_IS_CRITICAL                BIT(11) /* do not gate, ever */
 
 struct clk;
 struct clk_hw;
@@ -282,10 +283,17 @@ extern const struct clk_ops clk_fixed_rate_ops;
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned long fixed_rate);
+struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate);
 struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
                const char *name, const char *parent_name, unsigned long flags,
                unsigned long fixed_rate, unsigned long fixed_accuracy);
 void clk_unregister_fixed_rate(struct clk *clk);
+struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate, unsigned long fixed_accuracy);
+
 void of_fixed_clk_setup(struct device_node *np);
 
 /**
@@ -326,7 +334,12 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 bit_idx,
+               u8 clk_gate_flags, spinlock_t *lock);
 void clk_unregister_gate(struct clk *clk);
+void clk_hw_unregister_gate(struct clk_hw *hw);
 
 struct clk_div_table {
        unsigned int    val;
@@ -407,12 +420,22 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, spinlock_t *lock);
 struct clk *clk_register_divider_table(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, const struct clk_div_table *table,
                spinlock_t *lock);
+struct clk_hw *clk_hw_register_divider_table(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, const struct clk_div_table *table,
+               spinlock_t *lock);
 void clk_unregister_divider(struct clk *clk);
+void clk_hw_unregister_divider(struct clk_hw *hw);
 
 /**
  * struct clk_mux - multiplexer clock
@@ -463,14 +486,25 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
                unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_mux_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags, spinlock_t *lock);
 
 struct clk *clk_register_mux_table(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
                unsigned long flags,
                void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock);
+struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents,
+               unsigned long flags,
+               void __iomem *reg, u8 shift, u32 mask,
+               u8 clk_mux_flags, u32 *table, spinlock_t *lock);
 
 void clk_unregister_mux(struct clk *clk);
+void clk_hw_unregister_mux(struct clk_hw *hw);
 
 void of_fixed_factor_clk_setup(struct device_node *node);
 
@@ -499,6 +533,10 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned int mult, unsigned int div);
 void clk_unregister_fixed_factor(struct clk *clk);
+struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               unsigned int mult, unsigned int div);
+void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
 
 /**
  * struct clk_fractional_divider - adjustable fractional divider clock
@@ -533,6 +571,11 @@ struct clk *clk_register_fractional_divider(struct device *dev,
                const char *name, const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
                u8 clk_divider_flags, spinlock_t *lock);
+struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
+               const char *name, const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
+               u8 clk_divider_flags, spinlock_t *lock);
+void clk_hw_unregister_fractional_divider(struct clk_hw *hw);
 
 /**
  * struct clk_multiplier - adjustable multiplier clock
@@ -603,6 +646,14 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
                struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
                struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
                unsigned long flags);
+void clk_unregister_composite(struct clk *clk);
+struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
+               const char * const *parent_names, int num_parents,
+               struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+               struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+               struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+               unsigned long flags);
+void clk_hw_unregister_composite(struct clk_hw *hw);
 
 /***
  * struct clk_gpio_gate - gpio gated clock
@@ -625,6 +676,10 @@ extern const struct clk_ops clk_gpio_gate_ops;
 struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned gpio, bool active_low,
                unsigned long flags);
+struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned gpio, bool active_low,
+               unsigned long flags);
+void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
 
 /**
  * struct clk_gpio_mux - gpio controlled clock multiplexer
@@ -640,6 +695,10 @@ extern const struct clk_ops clk_gpio_mux_ops;
 struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents, unsigned gpio,
                bool active_low, unsigned long flags);
+struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
+               const char * const *parent_names, u8 num_parents, unsigned gpio,
+               bool active_low, unsigned long flags);
+void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
 
 /**
  * clk_register - allocate a new clock, register it and return an opaque cookie
@@ -655,9 +714,15 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
 struct clk *clk_register(struct device *dev, struct clk_hw *hw);
 struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
 
+int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
+int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
+
 void clk_unregister(struct clk *clk);
 void devm_clk_unregister(struct device *dev, struct clk *clk);
 
+void clk_hw_unregister(struct clk_hw *hw);
+void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw);
+
 /* helper functions */
 const char *__clk_get_name(const struct clk *clk);
 const char *clk_hw_get_name(const struct clk_hw *hw);
@@ -703,6 +768,11 @@ struct clk_onecell_data {
        unsigned int clk_num;
 };
 
+struct clk_hw_onecell_data {
+       size_t num;
+       struct clk_hw *hws[];
+};
+
 extern struct of_device_id __clk_of_table;
 
 #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
@@ -712,15 +782,24 @@ int of_clk_add_provider(struct device_node *np,
                        struct clk *(*clk_src_get)(struct of_phandle_args *args,
                                                   void *data),
                        void *data);
+int of_clk_add_hw_provider(struct device_node *np,
+                          struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+                                                void *data),
+                          void *data);
 void of_clk_del_provider(struct device_node *np);
 struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
                                  void *data);
+struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
+                                   void *data);
 struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
+struct clk_hw *of_clk_hw_onecell_get(struct of_phandle_args *clkspec,
+                                    void *data);
 unsigned int of_clk_get_parent_count(struct device_node *np);
 int of_clk_parent_fill(struct device_node *np, const char **parents,
                       unsigned int size);
 const char *of_clk_get_parent_name(struct device_node *np, int index);
-
+int of_clk_detect_critical(struct device_node *np, int index,
+                           unsigned long *flags);
 void of_clk_init(const struct of_device_id *matches);
 
 #else /* !CONFIG_OF */
@@ -732,17 +811,34 @@ static inline int of_clk_add_provider(struct device_node *np,
 {
        return 0;
 }
+static inline int of_clk_add_hw_provider(struct device_node *np,
+                       struct clk_hw *(*get)(struct of_phandle_args *clkspec,
+                                             void *data),
+                       void *data)
+{
+       return 0;
+}
 static inline void of_clk_del_provider(struct device_node *np) {}
 static inline struct clk *of_clk_src_simple_get(
        struct of_phandle_args *clkspec, void *data)
 {
        return ERR_PTR(-ENOENT);
 }
+static inline struct clk_hw *
+of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
+{
+       return ERR_PTR(-ENOENT);
+}
 static inline struct clk *of_clk_src_onecell_get(
        struct of_phandle_args *clkspec, void *data)
 {
        return ERR_PTR(-ENOENT);
 }
+static inline struct clk_hw *
+of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
+{
+       return ERR_PTR(-ENOENT);
+}
 static inline int of_clk_get_parent_count(struct device_node *np)
 {
        return 0;
@@ -757,6 +853,11 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
 {
        return NULL;
 }
+static inline int of_clk_detect_critical(struct device_node *np, int index,
+                                         unsigned long *flags)
+{
+       return 0;
+}
 static inline void of_clk_init(const struct of_device_id *matches) {}
 #endif /* CONFIG_OF */
 
index 7adfd80fbf55d48499143de084171a0218b20f00..ba6fa4148515e5c9959c21767820fe7363bd9713 100644 (file)
@@ -24,12 +24,20 @@ void r8a7778_clocks_init(u32 mode);
 void r8a7779_clocks_init(u32 mode);
 void rcar_gen2_clocks_init(u32 mode);
 
-#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
 void cpg_mstp_add_clk_domain(struct device_node *np);
-int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev);
-void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev);
+#ifdef CONFIG_CLK_RENESAS_CPG_MSTP
+int cpg_mstp_attach_dev(struct generic_pm_domain *unused, struct device *dev);
+void cpg_mstp_detach_dev(struct generic_pm_domain *unused, struct device *dev);
 #else
-static inline void cpg_mstp_add_clk_domain(struct device_node *np) {}
+#define cpg_mstp_attach_dev    NULL
+#define cpg_mstp_detach_dev    NULL
 #endif
 
+#ifdef CONFIG_CLK_RENESAS_CPG_MSSR
+int cpg_mssr_attach_dev(struct generic_pm_domain *unused, struct device *dev);
+void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev);
+#else
+#define cpg_mssr_attach_dev    NULL
+#define cpg_mssr_detach_dev    NULL
+#endif
 #endif
index dc5164a6df2932f6c3f24e4287e46216f4c38c06..6110fe09ed18c289881e63d3b8e1ecb62dfb08c9 100644 (file)
@@ -37,6 +37,7 @@
  * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate()
  * @min_divider: minimum valid non-bypass divider value (actual)
  * @max_divider: maximum valid non-bypass divider value (actual)
+ * @max_rate: maximum clock rate for the DPLL
  * @modes: possible values of @enable_mask
  * @autoidle_reg: register containing the DPLL autoidle mode bitfield
  * @idlest_reg: register containing the DPLL idle status bitfield
@@ -81,6 +82,7 @@ struct dpll_data {
        u8                      last_rounded_n;
        u8                      min_divider;
        u16                     max_divider;
+       unsigned long           max_rate;
        u8                      modes;
        void __iomem            *autoidle_reg;
        void __iomem            *idlest_reg;
index c2c04f7cbe8ac4584dfa427f4f324c7bd0093396..2eabc862abdb04c59f4ea60d30ee6edcb5da9188 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/clkdev.h>
 
 struct clk;
+struct clk_hw;
 struct device;
 
 struct clk_lookup {
@@ -34,18 +35,22 @@ struct clk_lookup {
 
 struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
        const char *dev_fmt, ...) __printf(3, 4);
+struct clk_lookup *clkdev_hw_alloc(struct clk_hw *hw, const char *con_id,
+       const char *dev_fmt, ...) __printf(3, 4);
 
 void clkdev_add(struct clk_lookup *cl);
 void clkdev_drop(struct clk_lookup *cl);
 
 struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
        const char *dev_fmt, ...) __printf(3, 4);
+struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
+       const char *dev_fmt, ...) __printf(3, 4);
 
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, const char *, struct device *);
 
 int clk_register_clkdev(struct clk *, const char *, const char *);
-int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
+int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *);
 
 #ifdef CONFIG_COMMON_CLK
 int __clk_get(struct clk *clk);