summaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 23:18:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 23:18:12 -0400
commit0eff4589c36edd03d50b835d0768b2c2ef3f20bd (patch)
treef0a08e7ed4dac042d89d24bb4c79f66df70085ff /drivers/clk
parent087afe8aaf562dc7a53f2577049830d6a3245742 (diff)
parentef56b79b66faeeb0dc14213d3cc9e0534a960dee (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "It's the usual big pile of driver updates and additions, but we do have a couple core changes in here as well. Core: - CLK_IS_CRITICAL support has been added. This should allow drivers to properly express that a certain clk should stay on even if their prepare/enable count drops to 0 (and in turn the parents of these clks should stay enabled). - A clk registration API has been added, clk_hw_register(), and an OF clk provider API has been added, of_clk_add_hw_provider(). These APIs have been put in place to further split clk providers from clk consumers, with the goal being to have clk providers never deal with struct clk pointers at all. Conversion of provider drivers is on going. clkdev has also gained support for registering clk_hw pointers directly so we can convert drivers that don't use devicetree. New Drivers: - Marvell ap806 and cp110 system controllers (with clks inside!) - Hisilicon Hi3519 clock and reset controller - Axis ARTPEC-6 clock controllers - Oxford Semiconductor OXNAS clock controllers - AXS10X I2S PLL - Rockchip RK3399 clock and reset controller Updates: - MMC2 and UART2 clks on Samsung Exynos 3250, ACLK on Samsung Exynos 542x SoCs, and some more clk ID exporting for bus frequency scaling - Proper BCM2835 PCM clk support and various other clks - i.MX clk updates for i.MX6SX, i.MX7, and VF610 - Renesas updates for R-Car H3 - Tegra210 got updates for DisplayPort and HDMI 2.0 - Rockchip driver refactorings and fixes due to adding RK3399 support" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (139 commits) clk: fix critical clock locking clk: qcom: mmcc-8996: Remove clocks that should be controlled by RPM clk: ingenic: Allow divider value to be divided clk: sunxi: Add display and TCON0 clocks driver clk: rockchip: drop old_rate calculation on pll rate changes clk: rockchip: simplify GRF handling in pll clocks clk: rockchip: lookup General Register Files in rockchip_clk_init clk: rockchip: fix the rk3399 sdmmc sample / drv name clk: mvebu: new driver for Armada CP110 system controller dt-bindings: arm: add DT binding for Marvell CP110 system controller clk: mvebu: new driver for Armada AP806 system controller clk: hisilicon: add CRG driver for hi3519 soc clk: hisilicon: export some hisilicon APIs to modules reset: hisilicon: add reset controller driver for hisilicon SOCs clk: bcm/kona: Do not use sizeof on pointer type clk: qcom: msm8916: Fix crypto clock flags clk: nxp: lpc18xx: Initialize clk_init_data::flags to 0 clk/axs10x: Add I2S PLL clock driver clk: imx7d: fix ahb clock mux 1 clk: fix comment of devm_clk_hw_register() ...
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Kconfig6
-rw-r--r--drivers/clk/Makefile5
-rw-r--r--drivers/clk/at91/clk-h32mx.c2
-rw-r--r--drivers/clk/axis/Makefile1
-rw-r--r--drivers/clk/axis/clk-artpec6.c242
-rw-r--r--drivers/clk/axs10x/Makefile1
-rw-r--r--drivers/clk/axs10x/i2s_pll_clock.c228
-rw-r--r--drivers/clk/bcm/clk-bcm2835.c1215
-rw-r--r--drivers/clk/bcm/clk-kona-setup.c3
-rw-r--r--drivers/clk/clk-clps711x.c19
-rw-r--r--drivers/clk/clk-composite.c93
-rw-r--r--drivers/clk/clk-divider.c91
-rw-r--r--drivers/clk/clk-fixed-factor.c42
-rw-r--r--drivers/clk/clk-fixed-rate.c44
-rw-r--r--drivers/clk/clk-fractional-divider.c40
-rw-r--r--drivers/clk/clk-gate.c43
-rw-r--r--drivers/clk/clk-gpio.c52
-rw-r--r--drivers/clk/clk-ls1x.c3
-rw-r--r--drivers/clk/clk-mux.c57
-rw-r--r--drivers/clk/clk-nspire.c3
-rw-r--r--drivers/clk/clk-oxnas.c195
-rw-r--r--drivers/clk/clk-palmas.c4
-rw-r--r--drivers/clk/clk-qoriq.c5
-rw-r--r--drivers/clk/clk-rk808.c1
-rw-r--r--drivers/clk/clk-tango4.c73
-rw-r--r--drivers/clk/clk-twl6040.c1
-rw-r--r--drivers/clk/clk-wm831x.c1
-rw-r--r--drivers/clk/clk-xgene.c2
-rw-r--r--drivers/clk/clk.c222
-rw-r--r--drivers/clk/clkdev.c75
-rw-r--r--drivers/clk/hisilicon/Kconfig15
-rw-r--r--drivers/clk/hisilicon/Makefile2
-rw-r--r--drivers/clk/hisilicon/clk-hi3519.c131
-rw-r--r--drivers/clk/hisilicon/clk.c23
-rw-r--r--drivers/clk/hisilicon/clk.h14
-rw-r--r--drivers/clk/hisilicon/reset.c134
-rw-r--r--drivers/clk/hisilicon/reset.h36
-rw-r--r--drivers/clk/imx/clk-gate2.c7
-rw-r--r--drivers/clk/imx/clk-imx35.c4
-rw-r--r--drivers/clk/imx/clk-imx6sx.c10
-rw-r--r--drivers/clk/imx/clk-imx7d.c5
-rw-r--r--drivers/clk/imx/clk-pllv3.c9
-rw-r--r--drivers/clk/imx/clk-vf610.c60
-rw-r--r--drivers/clk/imx/clk.h13
-rw-r--r--drivers/clk/ingenic/cgu.c11
-rw-r--r--drivers/clk/ingenic/cgu.h6
-rw-r--r--drivers/clk/ingenic/jz4740-cgu.c24
-rw-r--r--drivers/clk/ingenic/jz4780-cgu.c40
-rw-r--r--drivers/clk/meson/meson8b-clkc.c6
-rw-r--r--drivers/clk/mmp/clk-mmp2.c14
-rw-r--r--drivers/clk/mmp/clk-of-mmp2.c10
-rw-r--r--drivers/clk/mmp/clk-of-pxa168.c8
-rw-r--r--drivers/clk/mmp/clk-of-pxa1928.c12
-rw-r--r--drivers/clk/mmp/clk-of-pxa910.c8
-rw-r--r--drivers/clk/mmp/clk-pxa168.c8
-rw-r--r--drivers/clk/mmp/clk-pxa910.c8
-rw-r--r--drivers/clk/mvebu/Kconfig6
-rw-r--r--drivers/clk/mvebu/Makefile2
-rw-r--r--drivers/clk/mvebu/ap806-system-controller.c168
-rw-r--r--drivers/clk/mvebu/cp110-system-controller.c406
-rw-r--r--drivers/clk/nxp/clk-lpc18xx-creg.c1
-rw-r--r--drivers/clk/qcom/gcc-msm8916.c2
-rw-r--r--drivers/clk/qcom/mmcc-msm8996.c32
-rw-r--r--drivers/clk/renesas/clk-mstp.c3
-rw-r--r--drivers/clk/renesas/r8a7795-cpg-mssr.c13
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c2
-rw-r--r--drivers/clk/rockchip/Makefile1
-rw-r--r--drivers/clk/rockchip/clk-cpu.c29
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c3
-rw-r--r--drivers/clk/rockchip/clk-pll.c336
-rw-r--r--drivers/clk/rockchip/clk-rk3036.c21
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c51
-rw-r--r--drivers/clk/rockchip/clk-rk3228.c21
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c23
-rw-r--r--drivers/clk/rockchip/clk-rk3368.c28
-rw-r--r--drivers/clk/rockchip/clk-rk3399.c1573
-rw-r--r--drivers/clk/rockchip/clk.c151
-rw-r--r--drivers/clk/rockchip/clk.h104
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c77
-rw-r--r--drivers/clk/sirf/clk-atlas6.c7
-rw-r--r--drivers/clk/sirf/clk-prima2.c7
-rw-r--r--drivers/clk/sunxi/Makefile3
-rw-r--r--drivers/clk/sunxi/clk-a10-hosc.c3
-rw-r--r--drivers/clk/sunxi/clk-a10-mod1.c2
-rw-r--r--drivers/clk/sunxi/clk-sun4i-display.c261
-rw-r--r--drivers/clk/sunxi/clk-sun4i-pll3.c98
-rw-r--r--drivers/clk/sunxi/clk-sun4i-tcon-ch1.c300
-rw-r--r--drivers/clk/sunxi/clk-sun9i-mmc.c2
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c79
-rw-r--r--drivers/clk/tegra/Makefile1
-rw-r--r--drivers/clk/tegra/clk-dfll.c11
-rw-r--r--drivers/clk/tegra/clk-dfll.h22
-rw-r--r--drivers/clk/tegra/clk-id.h2
-rw-r--r--drivers/clk/tegra/clk-periph-fixed.c120
-rw-r--r--drivers/clk/tegra/clk-periph-gate.c2
-rw-r--r--drivers/clk/tegra/clk-periph.c2
-rw-r--r--drivers/clk/tegra/clk-pll.c46
-rw-r--r--drivers/clk/tegra/clk-tegra-fixed.c1
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c5
-rw-r--r--drivers/clk/tegra/clk-tegra114.c6
-rw-r--r--drivers/clk/tegra/clk-tegra124-dfll-fcpu.c103
-rw-r--r--drivers/clk/tegra/clk-tegra124.c4
-rw-r--r--drivers/clk/tegra/clk-tegra210.c29
-rw-r--r--drivers/clk/tegra/clk-tegra30.c12
-rw-r--r--drivers/clk/tegra/clk.c4
-rw-r--r--drivers/clk/tegra/clk.h27
-rw-r--r--drivers/clk/tegra/cvb.c71
-rw-r--r--drivers/clk/tegra/cvb.h15
-rw-r--r--drivers/clk/ti/clk-54xx.c1
-rw-r--r--drivers/clk/ti/clk-7xx.c1
-rw-r--r--drivers/clk/ti/clk-dra7-atl.c2
-rw-r--r--drivers/clk/ti/clkt_dflt.c2
-rw-r--r--drivers/clk/ti/clkt_dpll.c3
-rw-r--r--drivers/clk/ti/dpll.c5
-rw-r--r--drivers/clk/zte/clk-zx296702.c3
115 files changed, 6589 insertions, 1113 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 90518cd7fc9c..53ddba26578c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -200,6 +200,12 @@ config COMMON_CLK_PXA
200config COMMON_CLK_PIC32 200config COMMON_CLK_PIC32
201 def_bool COMMON_CLK && MACH_PIC32 201 def_bool COMMON_CLK && MACH_PIC32
202 202
203config COMMON_CLK_OXNAS
204 bool "Clock driver for the OXNAS SoC Family"
205 select MFD_SYSCON
206 ---help---
207 Support for the OXNAS SoC Family clocks.
208
203source "drivers/clk/bcm/Kconfig" 209source "drivers/clk/bcm/Kconfig"
204source "drivers/clk/hisilicon/Kconfig" 210source "drivers/clk/hisilicon/Kconfig"
205source "drivers/clk/mvebu/Kconfig" 211source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 18e64bbeeaf4..dcc5e698ff6d 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
33obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 33obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
34obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 34obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
35obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 35obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
36obj-$(CONFIG_COMMON_CLK_OXNAS) += clk-oxnas.o
36obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o 37obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o
37obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o 38obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
38obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o 39obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
@@ -51,6 +52,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
51obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o 52obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
52obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o 53obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
53obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 54obj-$(CONFIG_COMMON_CLK_AT91) += at91/
55obj-$(CONFIG_ARCH_ARTPEC) += axis/
54obj-y += bcm/ 56obj-y += bcm/
55obj-$(CONFIG_ARCH_BERLIN) += berlin/ 57obj-$(CONFIG_ARCH_BERLIN) += berlin/
56obj-$(CONFIG_ARCH_HISI) += hisilicon/ 58obj-$(CONFIG_ARCH_HISI) += hisilicon/
@@ -62,7 +64,7 @@ obj-$(CONFIG_MACH_PIC32) += microchip/
62ifeq ($(CONFIG_COMMON_CLK), y) 64ifeq ($(CONFIG_COMMON_CLK), y)
63obj-$(CONFIG_ARCH_MMP) += mmp/ 65obj-$(CONFIG_ARCH_MMP) += mmp/
64endif 66endif
65obj-$(CONFIG_PLAT_ORION) += mvebu/ 67obj-y += mvebu/
66obj-$(CONFIG_ARCH_MESON) += meson/ 68obj-$(CONFIG_ARCH_MESON) += meson/
67obj-$(CONFIG_ARCH_MXS) += mxs/ 69obj-$(CONFIG_ARCH_MXS) += mxs/
68obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ 70obj-$(CONFIG_MACH_PISTACHIO) += pistachio/
@@ -85,3 +87,4 @@ obj-$(CONFIG_X86) += x86/
85obj-$(CONFIG_ARCH_ZX) += zte/ 87obj-$(CONFIG_ARCH_ZX) += zte/
86obj-$(CONFIG_ARCH_ZYNQ) += zynq/ 88obj-$(CONFIG_ARCH_ZYNQ) += zynq/
87obj-$(CONFIG_H8300) += h8300/ 89obj-$(CONFIG_H8300) += h8300/
90obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 819f5842fa66..8e20c8a76db7 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -114,7 +114,7 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
114 h32mxclk->regmap = regmap; 114 h32mxclk->regmap = regmap;
115 115
116 clk = clk_register(NULL, &h32mxclk->hw); 116 clk = clk_register(NULL, &h32mxclk->hw);
117 if (!clk) { 117 if (IS_ERR(clk)) {
118 kfree(h32mxclk); 118 kfree(h32mxclk);
119 return; 119 return;
120 } 120 }
diff --git a/drivers/clk/axis/Makefile b/drivers/clk/axis/Makefile
new file mode 100644
index 000000000000..628c9d3b9a02
--- /dev/null
+++ b/drivers/clk/axis/Makefile
@@ -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
index 000000000000..ffc988b098e4
--- /dev/null
+++ b/drivers/clk/axis/clk-artpec6.c
@@ -0,0 +1,242 @@
1/*
2 * ARTPEC-6 clock initialization
3 *
4 * Copyright 2015-2016 Axis Comunications AB.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/device.h>
13#include <linux/io.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16#include <linux/platform_device.h>
17#include <linux/slab.h>
18#include <dt-bindings/clock/axis,artpec6-clkctrl.h>
19
20#define NUM_I2S_CLOCKS 2
21
22struct artpec6_clkctrl_drvdata {
23 struct clk *clk_table[ARTPEC6_CLK_NUMCLOCKS];
24 void __iomem *syscon_base;
25 struct clk_onecell_data clk_data;
26 spinlock_t i2scfg_lock;
27};
28
29static struct artpec6_clkctrl_drvdata *clkdata;
30
31static const char *const i2s_clk_names[NUM_I2S_CLOCKS] = {
32 "i2s0",
33 "i2s1",
34};
35
36static const int i2s_clk_indexes[NUM_I2S_CLOCKS] = {
37 ARTPEC6_CLK_I2S0_CLK,
38 ARTPEC6_CLK_I2S1_CLK,
39};
40
41static void of_artpec6_clkctrl_setup(struct device_node *np)
42{
43 int i;
44 const char *sys_refclk_name;
45 u32 pll_mode, pll_m, pll_n;
46 struct clk **clks;
47
48 /* Mandatory parent clock. */
49 i = of_property_match_string(np, "clock-names", "sys_refclk");
50 if (i < 0)
51 return;
52
53 sys_refclk_name = of_clk_get_parent_name(np, i);
54
55 clkdata = kzalloc(sizeof(*clkdata), GFP_KERNEL);
56 if (!clkdata)
57 return;
58
59 clks = clkdata->clk_table;
60
61 for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i)
62 clks[i] = ERR_PTR(-EPROBE_DEFER);
63
64 clkdata->syscon_base = of_iomap(np, 0);
65 BUG_ON(clkdata->syscon_base == NULL);
66
67 /* Read PLL1 factors configured by boot strap pins. */
68 pll_mode = (readl(clkdata->syscon_base) >> 6) & 3;
69 switch (pll_mode) {
70 case 0: /* DDR3-2133 mode */
71 pll_m = 4;
72 pll_n = 85;
73 break;
74 case 1: /* DDR3-1866 mode */
75 pll_m = 6;
76 pll_n = 112;
77 break;
78 case 2: /* DDR3-1600 mode */
79 pll_m = 4;
80 pll_n = 64;
81 break;
82 case 3: /* DDR3-1333 mode */
83 pll_m = 8;
84 pll_n = 106;
85 break;
86 }
87
88 clks[ARTPEC6_CLK_CPU] =
89 clk_register_fixed_factor(NULL, "cpu", sys_refclk_name, 0, pll_n,
90 pll_m);
91 clks[ARTPEC6_CLK_CPU_PERIPH] =
92 clk_register_fixed_factor(NULL, "cpu_periph", "cpu", 0, 1, 2);
93
94 /* EPROBE_DEFER on the apb_clock is not handled in amba devices. */
95 clks[ARTPEC6_CLK_UART_PCLK] =
96 clk_register_fixed_factor(NULL, "uart_pclk", "cpu", 0, 1, 8);
97 clks[ARTPEC6_CLK_UART_REFCLK] =
98 clk_register_fixed_rate(NULL, "uart_ref", sys_refclk_name, 0,
99 50000000);
100
101 clks[ARTPEC6_CLK_SPI_PCLK] =
102 clk_register_fixed_factor(NULL, "spi_pclk", "cpu", 0, 1, 8);
103 clks[ARTPEC6_CLK_SPI_SSPCLK] =
104 clk_register_fixed_rate(NULL, "spi_sspclk", sys_refclk_name, 0,
105 50000000);
106
107 clks[ARTPEC6_CLK_DBG_PCLK] =
108 clk_register_fixed_factor(NULL, "dbg_pclk", "cpu", 0, 1, 8);
109
110 clkdata->clk_data.clks = clkdata->clk_table;
111 clkdata->clk_data.clk_num = ARTPEC6_CLK_NUMCLOCKS;
112
113 of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data);
114}
115
116CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl",
117 of_artpec6_clkctrl_setup);
118
119static int artpec6_clkctrl_probe(struct platform_device *pdev)
120{
121 int propidx;
122 struct device_node *np = pdev->dev.of_node;
123 struct device *dev = &pdev->dev;
124 struct clk **clks = clkdata->clk_table;
125 const char *sys_refclk_name;
126 const char *i2s_refclk_name = NULL;
127 const char *frac_clk_name[2] = { NULL, NULL };
128 const char *i2s_mux_parents[2];
129 u32 muxreg;
130 int i;
131 int err = 0;
132
133 /* Mandatory parent clock. */
134 propidx = of_property_match_string(np, "clock-names", "sys_refclk");
135 if (propidx < 0)
136 return -EINVAL;
137
138 sys_refclk_name = of_clk_get_parent_name(np, propidx);
139
140 /* Find clock names of optional parent clocks. */
141 propidx = of_property_match_string(np, "clock-names", "i2s_refclk");
142 if (propidx >= 0)
143 i2s_refclk_name = of_clk_get_parent_name(np, propidx);
144
145 propidx = of_property_match_string(np, "clock-names", "frac_clk0");
146 if (propidx >= 0)
147 frac_clk_name[0] = of_clk_get_parent_name(np, propidx);
148 propidx = of_property_match_string(np, "clock-names", "frac_clk1");
149 if (propidx >= 0)
150 frac_clk_name[1] = of_clk_get_parent_name(np, propidx);
151
152 spin_lock_init(&clkdata->i2scfg_lock);
153
154 clks[ARTPEC6_CLK_NAND_CLKA] =
155 clk_register_fixed_factor(dev, "nand_clka", "cpu", 0, 1, 8);
156 clks[ARTPEC6_CLK_NAND_CLKB] =
157 clk_register_fixed_rate(dev, "nand_clkb", sys_refclk_name, 0,
158 100000000);
159 clks[ARTPEC6_CLK_ETH_ACLK] =
160 clk_register_fixed_factor(dev, "eth_aclk", "cpu", 0, 1, 4);
161 clks[ARTPEC6_CLK_DMA_ACLK] =
162 clk_register_fixed_factor(dev, "dma_aclk", "cpu", 0, 1, 4);
163 clks[ARTPEC6_CLK_PTP_REF] =
164 clk_register_fixed_rate(dev, "ptp_ref", sys_refclk_name, 0,
165 100000000);
166 clks[ARTPEC6_CLK_SD_PCLK] =
167 clk_register_fixed_rate(dev, "sd_pclk", sys_refclk_name, 0,
168 100000000);
169 clks[ARTPEC6_CLK_SD_IMCLK] =
170 clk_register_fixed_rate(dev, "sd_imclk", sys_refclk_name, 0,
171 100000000);
172 clks[ARTPEC6_CLK_I2S_HST] =
173 clk_register_fixed_factor(dev, "i2s_hst", "cpu", 0, 1, 8);
174
175 for (i = 0; i < NUM_I2S_CLOCKS; ++i) {
176 if (i2s_refclk_name && frac_clk_name[i]) {
177 i2s_mux_parents[0] = frac_clk_name[i];
178 i2s_mux_parents[1] = i2s_refclk_name;
179
180 clks[i2s_clk_indexes[i]] =
181 clk_register_mux(dev, i2s_clk_names[i],
182 i2s_mux_parents, 2,
183 CLK_SET_RATE_NO_REPARENT |
184 CLK_SET_RATE_PARENT,
185 clkdata->syscon_base + 0x14, i, 1,
186 0, &clkdata->i2scfg_lock);
187 } else if (frac_clk_name[i]) {
188 /* Lock the mux for internal clock reference. */
189 muxreg = readl(clkdata->syscon_base + 0x14);
190 muxreg &= ~BIT(i);
191 writel(muxreg, clkdata->syscon_base + 0x14);
192 clks[i2s_clk_indexes[i]] =
193 clk_register_fixed_factor(dev, i2s_clk_names[i],
194 frac_clk_name[i], 0, 1,
195 1);
196 } else if (i2s_refclk_name) {
197 /* Lock the mux for external clock reference. */
198 muxreg = readl(clkdata->syscon_base + 0x14);
199 muxreg |= BIT(i);
200 writel(muxreg, clkdata->syscon_base + 0x14);
201 clks[i2s_clk_indexes[i]] =
202 clk_register_fixed_factor(dev, i2s_clk_names[i],
203 i2s_refclk_name, 0, 1, 1);
204 }
205 }
206
207 clks[ARTPEC6_CLK_I2C] =
208 clk_register_fixed_rate(dev, "i2c", sys_refclk_name, 0, 100000000);
209
210 clks[ARTPEC6_CLK_SYS_TIMER] =
211 clk_register_fixed_rate(dev, "timer", sys_refclk_name, 0,
212 100000000);
213 clks[ARTPEC6_CLK_FRACDIV_IN] =
214 clk_register_fixed_rate(dev, "fracdiv_in", sys_refclk_name, 0,
215 600000000);
216
217 for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i) {
218 if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -EPROBE_DEFER) {
219 dev_err(dev,
220 "Failed to register clock at index %d err=%ld\n",
221 i, PTR_ERR(clks[i]));
222 err = PTR_ERR(clks[i]);
223 }
224 }
225
226 return err;
227}
228
229static const struct of_device_id artpec_clkctrl_of_match[] = {
230 { .compatible = "axis,artpec6-clkctrl" },
231 {}
232};
233
234static struct platform_driver artpec6_clkctrl_driver = {
235 .probe = artpec6_clkctrl_probe,
236 .driver = {
237 .name = "artpec6_clkctrl",
238 .of_match_table = artpec_clkctrl_of_match,
239 },
240};
241
242builtin_platform_driver(artpec6_clkctrl_driver);
diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile
new file mode 100644
index 000000000000..01996b871b06
--- /dev/null
+++ b/drivers/clk/axs10x/Makefile
@@ -0,0 +1 @@
obj-y += i2s_pll_clock.o
diff --git a/drivers/clk/axs10x/i2s_pll_clock.c b/drivers/clk/axs10x/i2s_pll_clock.c
new file mode 100644
index 000000000000..411310d29581
--- /dev/null
+++ b/drivers/clk/axs10x/i2s_pll_clock.c
@@ -0,0 +1,228 @@
1/*
2 * Synopsys AXS10X SDP I2S PLL clock driver
3 *
4 * Copyright (C) 2016 Synopsys
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/module.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/device.h>
16#include <linux/of_address.h>
17#include <linux/slab.h>
18#include <linux/of.h>
19
20/* PLL registers addresses */
21#define PLL_IDIV_REG 0x0
22#define PLL_FBDIV_REG 0x4
23#define PLL_ODIV0_REG 0x8
24#define PLL_ODIV1_REG 0xC
25
26struct i2s_pll_cfg {
27 unsigned int rate;
28 unsigned int idiv;
29 unsigned int fbdiv;
30 unsigned int odiv0;
31 unsigned int odiv1;
32};
33
34static const struct i2s_pll_cfg i2s_pll_cfg_27m[] = {
35 /* 27 Mhz */
36 { 1024000, 0x104, 0x451, 0x10E38, 0x2000 },
37 { 1411200, 0x104, 0x596, 0x10D35, 0x2000 },
38 { 1536000, 0x208, 0xA28, 0x10B2C, 0x2000 },
39 { 2048000, 0x82, 0x451, 0x10E38, 0x2000 },
40 { 2822400, 0x82, 0x596, 0x10D35, 0x2000 },
41 { 3072000, 0x104, 0xA28, 0x10B2C, 0x2000 },
42 { 2116800, 0x82, 0x3CF, 0x10C30, 0x2000 },
43 { 2304000, 0x104, 0x79E, 0x10B2C, 0x2000 },
44 { 0, 0, 0, 0, 0 },
45};
46
47static const struct i2s_pll_cfg i2s_pll_cfg_28m[] = {
48 /* 28.224 Mhz */
49 { 1024000, 0x82, 0x105, 0x107DF, 0x2000 },
50 { 1411200, 0x28A, 0x1, 0x10001, 0x2000 },
51 { 1536000, 0xA28, 0x187, 0x10042, 0x2000 },
52 { 2048000, 0x41, 0x105, 0x107DF, 0x2000 },
53 { 2822400, 0x145, 0x1, 0x10001, 0x2000 },
54 { 3072000, 0x514, 0x187, 0x10042, 0x2000 },
55 { 2116800, 0x514, 0x42, 0x10001, 0x2000 },
56 { 2304000, 0x619, 0x82, 0x10001, 0x2000 },
57 { 0, 0, 0, 0, 0 },
58};
59
60struct i2s_pll_clk {
61 void __iomem *base;
62 struct clk_hw hw;
63 struct device *dev;
64};
65
66static inline void i2s_pll_write(struct i2s_pll_clk *clk, unsigned int reg,
67 unsigned int val)
68{
69 writel_relaxed(val, clk->base + reg);
70}
71
72static inline unsigned int i2s_pll_read(struct i2s_pll_clk *clk,
73 unsigned int reg)
74{
75 return readl_relaxed(clk->base + reg);
76}
77
78static inline struct i2s_pll_clk *to_i2s_pll_clk(struct clk_hw *hw)
79{
80 return container_of(hw, struct i2s_pll_clk, hw);
81}
82
83static inline unsigned int i2s_pll_get_value(unsigned int val)
84{
85 return (val & 0x3F) + ((val >> 6) & 0x3F);
86}
87
88static const struct i2s_pll_cfg *i2s_pll_get_cfg(unsigned long prate)
89{
90 switch (prate) {
91 case 27000000:
92 return i2s_pll_cfg_27m;
93 case 28224000:
94 return i2s_pll_cfg_28m;
95 default:
96 return NULL;
97 }
98}
99
100static unsigned long i2s_pll_recalc_rate(struct clk_hw *hw,
101 unsigned long parent_rate)
102{
103 struct i2s_pll_clk *clk = to_i2s_pll_clk(hw);
104 unsigned int idiv, fbdiv, odiv;
105
106 idiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_IDIV_REG));
107 fbdiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_FBDIV_REG));
108 odiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_ODIV0_REG));
109
110 return ((parent_rate / idiv) * fbdiv) / odiv;
111}
112
113static long i2s_pll_round_rate(struct clk_hw *hw, unsigned long rate,
114 unsigned long *prate)
115{
116 struct i2s_pll_clk *clk = to_i2s_pll_clk(hw);
117 const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(*prate);
118 int i;
119
120 if (!pll_cfg) {
121 dev_err(clk->dev, "invalid parent rate=%ld\n", *prate);
122 return -EINVAL;
123 }
124
125 for (i = 0; pll_cfg[i].rate != 0; i++)
126 if (pll_cfg[i].rate == rate)
127 return rate;
128
129 return -EINVAL;
130}
131
132static int i2s_pll_set_rate(struct clk_hw *hw, unsigned long rate,
133 unsigned long parent_rate)
134{
135 struct i2s_pll_clk *clk = to_i2s_pll_clk(hw);
136 const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(parent_rate);
137 int i;
138
139 if (!pll_cfg) {
140 dev_err(clk->dev, "invalid parent rate=%ld\n", parent_rate);
141 return -EINVAL;
142 }
143
144 for (i = 0; pll_cfg[i].rate != 0; i++) {
145 if (pll_cfg[i].rate == rate) {
146 i2s_pll_write(clk, PLL_IDIV_REG, pll_cfg[i].idiv);
147 i2s_pll_write(clk, PLL_FBDIV_REG, pll_cfg[i].fbdiv);
148 i2s_pll_write(clk, PLL_ODIV0_REG, pll_cfg[i].odiv0);
149 i2s_pll_write(clk, PLL_ODIV1_REG, pll_cfg[i].odiv1);
150 return 0;
151 }
152 }
153
154 dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate,
155 parent_rate);
156 return -EINVAL;
157}
158
159static const struct clk_ops i2s_pll_ops = {
160 .recalc_rate = i2s_pll_recalc_rate,
161 .round_rate = i2s_pll_round_rate,
162 .set_rate = i2s_pll_set_rate,
163};
164
165static int i2s_pll_clk_probe(struct platform_device *pdev)
166{
167 struct device *dev = &pdev->dev;
168 struct device_node *node = dev->of_node;
169 const char *clk_name;
170 const char *parent_name;
171 struct clk *clk;
172 struct i2s_pll_clk *pll_clk;
173 struct clk_init_data init;
174 struct resource *mem;
175
176 pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
177 if (!pll_clk)
178 return -ENOMEM;
179
180 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
181 pll_clk->base = devm_ioremap_resource(dev, mem);
182 if (IS_ERR(pll_clk->base))
183 return PTR_ERR(pll_clk->base);
184
185 clk_name = node->name;
186 init.name = clk_name;
187 init.ops = &i2s_pll_ops;
188 parent_name = of_clk_get_parent_name(node, 0);
189 init.parent_names = &parent_name;
190 init.num_parents = 1;
191 pll_clk->hw.init = &init;
192 pll_clk->dev = dev;
193
194 clk = devm_clk_register(dev, &pll_clk->hw);
195 if (IS_ERR(clk)) {
196 dev_err(dev, "failed to register %s clock (%ld)\n",
197 clk_name, PTR_ERR(clk));
198 return PTR_ERR(clk);
199 }
200
201 return of_clk_add_provider(node, of_clk_src_simple_get, clk);
202}
203
204static int i2s_pll_clk_remove(struct platform_device *pdev)
205{
206 of_clk_del_provider(pdev->dev.of_node);
207 return 0;
208}
209
210static const struct of_device_id i2s_pll_clk_id[] = {
211 { .compatible = "snps,axs10x-i2s-pll-clock", },
212 { },
213};
214MODULE_DEVICE_TABLE(of, i2s_pll_clk_id);
215
216static struct platform_driver i2s_pll_clk_driver = {
217 .driver = {
218 .name = "axs10x-i2s-pll-clock",
219 .of_match_table = i2s_pll_clk_id,
220 },
221 .probe = i2s_pll_clk_probe,
222 .remove = i2s_pll_clk_remove,
223};
224module_platform_driver(i2s_pll_clk_driver);
225
226MODULE_AUTHOR("Jose Abreu <joabreu@synopsys.com>");
227MODULE_DESCRIPTION("Synopsys AXS10X SDP I2S PLL Clock Driver");
228MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index c74ed3fd496d..7a7970865c2d 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -12,9 +12,6 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 15 */
19 16
20/** 17/**
@@ -40,6 +37,7 @@
40#include <linux/clk-provider.h> 37#include <linux/clk-provider.h>
41#include <linux/clkdev.h> 38#include <linux/clkdev.h>
42#include <linux/clk/bcm2835.h> 39#include <linux/clk/bcm2835.h>
40#include <linux/debugfs.h>
43#include <linux/module.h> 41#include <linux/module.h>
44#include <linux/of.h> 42#include <linux/of.h>
45#include <linux/platform_device.h> 43#include <linux/platform_device.h>
@@ -51,6 +49,7 @@
51#define CM_GNRICCTL 0x000 49#define CM_GNRICCTL 0x000
52#define CM_GNRICDIV 0x004 50#define CM_GNRICDIV 0x004
53# define CM_DIV_FRAC_BITS 12 51# define CM_DIV_FRAC_BITS 12
52# define CM_DIV_FRAC_MASK GENMASK(CM_DIV_FRAC_BITS - 1, 0)
54 53
55#define CM_VPUCTL 0x008 54#define CM_VPUCTL 0x008
56#define CM_VPUDIV 0x00c 55#define CM_VPUDIV 0x00c
@@ -118,6 +117,8 @@
118#define CM_SDCCTL 0x1a8 117#define CM_SDCCTL 0x1a8
119#define CM_SDCDIV 0x1ac 118#define CM_SDCDIV 0x1ac
120#define CM_ARMCTL 0x1b0 119#define CM_ARMCTL 0x1b0
120#define CM_AVEOCTL 0x1b8
121#define CM_AVEODIV 0x1bc
121#define CM_EMMCCTL 0x1c0 122#define CM_EMMCCTL 0x1c0
122#define CM_EMMCDIV 0x1c4 123#define CM_EMMCDIV 0x1c4
123 124
@@ -128,6 +129,7 @@
128# define CM_GATE BIT(CM_GATE_BIT) 129# define CM_GATE BIT(CM_GATE_BIT)
129# define CM_BUSY BIT(7) 130# define CM_BUSY BIT(7)
130# define CM_BUSYD BIT(8) 131# define CM_BUSYD BIT(8)
132# define CM_FRAC BIT(9)
131# define CM_SRC_SHIFT 0 133# define CM_SRC_SHIFT 0
132# define CM_SRC_BITS 4 134# define CM_SRC_BITS 4
133# define CM_SRC_MASK 0xf 135# define CM_SRC_MASK 0xf
@@ -297,11 +299,11 @@
297struct bcm2835_cprman { 299struct bcm2835_cprman {
298 struct device *dev; 300 struct device *dev;
299 void __iomem *regs; 301 void __iomem *regs;
300 spinlock_t regs_lock; 302 spinlock_t regs_lock; /* spinlock for all clocks */
301 const char *osc_name; 303 const char *osc_name;
302 304
303 struct clk_onecell_data onecell; 305 struct clk_onecell_data onecell;
304 struct clk *clks[BCM2835_CLOCK_COUNT]; 306 struct clk *clks[];
305}; 307};
306 308
307static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) 309static 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)
314 return readl(cprman->regs + reg); 316 return readl(cprman->regs + reg);
315} 317}
316 318
319static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
320 struct debugfs_reg32 *regs, size_t nregs,
321 struct dentry *dentry)
322{
323 struct dentry *regdump;
324 struct debugfs_regset32 *regset;
325
326 regset = devm_kzalloc(cprman->dev, sizeof(*regset), GFP_KERNEL);
327 if (!regset)
328 return -ENOMEM;
329
330 regset->regs = regs;
331 regset->nregs = nregs;
332 regset->base = cprman->regs + base;
333
334 regdump = debugfs_create_regset32("regdump", S_IRUGO, dentry,
335 regset);
336
337 return regdump ? 0 : -ENOMEM;
338}
339
317/* 340/*
318 * These are fixed clocks. They're probably not all root clocks and it may 341 * These are fixed clocks. They're probably not all root clocks and it may
319 * be possible to turn them on and off but until this is mapped out better 342 * be possible to turn them on and off but until this is mapped out better
@@ -377,132 +400,27 @@ struct bcm2835_pll_ana_bits {
377static const struct bcm2835_pll_ana_bits bcm2835_ana_default = { 400static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
378 .mask0 = 0, 401 .mask0 = 0,
379 .set0 = 0, 402 .set0 = 0,
380 .mask1 = ~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK), 403 .mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
381 .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT), 404 .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
382 .mask3 = ~A2W_PLL_KA_MASK, 405 .mask3 = (u32)~A2W_PLL_KA_MASK,
383 .set3 = (2 << A2W_PLL_KA_SHIFT), 406 .set3 = (2 << A2W_PLL_KA_SHIFT),
384 .fb_prediv_mask = BIT(14), 407 .fb_prediv_mask = BIT(14),
385}; 408};
386 409
387static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { 410static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
388 .mask0 = ~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK), 411 .mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
389 .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT), 412 .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
390 .mask1 = ~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK), 413 .mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
391 .set1 = (6 << A2W_PLLH_KP_SHIFT), 414 .set1 = (6 << A2W_PLLH_KP_SHIFT),
392 .mask3 = 0, 415 .mask3 = 0,
393 .set3 = 0, 416 .set3 = 0,
394 .fb_prediv_mask = BIT(11), 417 .fb_prediv_mask = BIT(11),
395}; 418};
396 419
397/*
398 * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
399 * Port 2) transmitter clock.
400 *
401 * It is in the PX LDO power domain, which is on when the AUDIO domain
402 * is on.
403 */
404static const struct bcm2835_pll_data bcm2835_plla_data = {
405 .name = "plla",
406 .cm_ctrl_reg = CM_PLLA,
407 .a2w_ctrl_reg = A2W_PLLA_CTRL,
408 .frac_reg = A2W_PLLA_FRAC,
409 .ana_reg_base = A2W_PLLA_ANA0,
410 .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
411 .lock_mask = CM_LOCK_FLOCKA,
412
413 .ana = &bcm2835_ana_default,
414
415 .min_rate = 600000000u,
416 .max_rate = 2400000000u,
417 .max_fb_rate = BCM2835_MAX_FB_RATE,
418};
419
420/* PLLB is used for the ARM's clock. */
421static const struct bcm2835_pll_data bcm2835_pllb_data = {
422 .name = "pllb",
423 .cm_ctrl_reg = CM_PLLB,
424 .a2w_ctrl_reg = A2W_PLLB_CTRL,
425 .frac_reg = A2W_PLLB_FRAC,
426 .ana_reg_base = A2W_PLLB_ANA0,
427 .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
428 .lock_mask = CM_LOCK_FLOCKB,
429
430 .ana = &bcm2835_ana_default,
431
432 .min_rate = 600000000u,
433 .max_rate = 3000000000u,
434 .max_fb_rate = BCM2835_MAX_FB_RATE,
435};
436
437/*
438 * PLLC is the core PLL, used to drive the core VPU clock.
439 *
440 * It is in the PX LDO power domain, which is on when the AUDIO domain
441 * is on.
442*/
443static const struct bcm2835_pll_data bcm2835_pllc_data = {
444 .name = "pllc",
445 .cm_ctrl_reg = CM_PLLC,
446 .a2w_ctrl_reg = A2W_PLLC_CTRL,
447 .frac_reg = A2W_PLLC_FRAC,
448 .ana_reg_base = A2W_PLLC_ANA0,
449 .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
450 .lock_mask = CM_LOCK_FLOCKC,
451
452 .ana = &bcm2835_ana_default,
453
454 .min_rate = 600000000u,
455 .max_rate = 3000000000u,
456 .max_fb_rate = BCM2835_MAX_FB_RATE,
457};
458
459/*
460 * PLLD is the display PLL, used to drive DSI display panels.
461 *
462 * It is in the PX LDO power domain, which is on when the AUDIO domain
463 * is on.
464 */
465static const struct bcm2835_pll_data bcm2835_plld_data = {
466 .name = "plld",
467 .cm_ctrl_reg = CM_PLLD,
468 .a2w_ctrl_reg = A2W_PLLD_CTRL,
469 .frac_reg = A2W_PLLD_FRAC,
470 .ana_reg_base = A2W_PLLD_ANA0,
471 .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
472 .lock_mask = CM_LOCK_FLOCKD,
473
474 .ana = &bcm2835_ana_default,
475
476 .min_rate = 600000000u,
477 .max_rate = 2400000000u,
478 .max_fb_rate = BCM2835_MAX_FB_RATE,
479};
480
481/*
482 * PLLH is used to supply the pixel clock or the AUX clock for the TV
483 * encoder.
484 *
485 * It is in the HDMI power domain.
486 */
487static const struct bcm2835_pll_data bcm2835_pllh_data = {
488 "pllh",
489 .cm_ctrl_reg = CM_PLLH,
490 .a2w_ctrl_reg = A2W_PLLH_CTRL,
491 .frac_reg = A2W_PLLH_FRAC,
492 .ana_reg_base = A2W_PLLH_ANA0,
493 .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
494 .lock_mask = CM_LOCK_FLOCKH,
495
496 .ana = &bcm2835_ana_pllh,
497
498 .min_rate = 600000000u,
499 .max_rate = 3000000000u,
500 .max_fb_rate = BCM2835_MAX_FB_RATE,
501};
502
503struct bcm2835_pll_divider_data { 420struct bcm2835_pll_divider_data {
504 const char *name; 421 const char *name;
505 const struct bcm2835_pll_data *source_pll; 422 const char *source_pll;
423
506 u32 cm_reg; 424 u32 cm_reg;
507 u32 a2w_reg; 425 u32 a2w_reg;
508 426
@@ -511,124 +429,6 @@ struct bcm2835_pll_divider_data {
511 u32 fixed_divider; 429 u32 fixed_divider;
512}; 430};
513 431
514static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
515 .name = "plla_core",
516 .source_pll = &bcm2835_plla_data,
517 .cm_reg = CM_PLLA,
518 .a2w_reg = A2W_PLLA_CORE,
519 .load_mask = CM_PLLA_LOADCORE,
520 .hold_mask = CM_PLLA_HOLDCORE,
521 .fixed_divider = 1,
522};
523
524static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
525 .name = "plla_per",
526 .source_pll = &bcm2835_plla_data,
527 .cm_reg = CM_PLLA,
528 .a2w_reg = A2W_PLLA_PER,
529 .load_mask = CM_PLLA_LOADPER,
530 .hold_mask = CM_PLLA_HOLDPER,
531 .fixed_divider = 1,
532};
533
534static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
535 .name = "pllb_arm",
536 .source_pll = &bcm2835_pllb_data,
537 .cm_reg = CM_PLLB,
538 .a2w_reg = A2W_PLLB_ARM,
539 .load_mask = CM_PLLB_LOADARM,
540 .hold_mask = CM_PLLB_HOLDARM,
541 .fixed_divider = 1,
542};
543
544static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
545 .name = "pllc_core0",
546 .source_pll = &bcm2835_pllc_data,
547 .cm_reg = CM_PLLC,
548 .a2w_reg = A2W_PLLC_CORE0,
549 .load_mask = CM_PLLC_LOADCORE0,
550 .hold_mask = CM_PLLC_HOLDCORE0,
551 .fixed_divider = 1,
552};
553
554static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
555 .name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
556 .cm_reg = CM_PLLC, A2W_PLLC_CORE1,
557 .load_mask = CM_PLLC_LOADCORE1,
558 .hold_mask = CM_PLLC_HOLDCORE1,
559 .fixed_divider = 1,
560};
561
562static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
563 .name = "pllc_core2",
564 .source_pll = &bcm2835_pllc_data,
565 .cm_reg = CM_PLLC,
566 .a2w_reg = A2W_PLLC_CORE2,
567 .load_mask = CM_PLLC_LOADCORE2,
568 .hold_mask = CM_PLLC_HOLDCORE2,
569 .fixed_divider = 1,
570};
571
572static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
573 .name = "pllc_per",
574 .source_pll = &bcm2835_pllc_data,
575 .cm_reg = CM_PLLC,
576 .a2w_reg = A2W_PLLC_PER,
577 .load_mask = CM_PLLC_LOADPER,
578 .hold_mask = CM_PLLC_HOLDPER,
579 .fixed_divider = 1,
580};
581
582static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
583 .name = "plld_core",
584 .source_pll = &bcm2835_plld_data,
585 .cm_reg = CM_PLLD,
586 .a2w_reg = A2W_PLLD_CORE,
587 .load_mask = CM_PLLD_LOADCORE,
588 .hold_mask = CM_PLLD_HOLDCORE,
589 .fixed_divider = 1,
590};
591
592static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
593 .name = "plld_per",
594 .source_pll = &bcm2835_plld_data,
595 .cm_reg = CM_PLLD,
596 .a2w_reg = A2W_PLLD_PER,
597 .load_mask = CM_PLLD_LOADPER,
598 .hold_mask = CM_PLLD_HOLDPER,
599 .fixed_divider = 1,
600};
601
602static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
603 .name = "pllh_rcal",
604 .source_pll = &bcm2835_pllh_data,
605 .cm_reg = CM_PLLH,
606 .a2w_reg = A2W_PLLH_RCAL,
607 .load_mask = CM_PLLH_LOADRCAL,
608 .hold_mask = 0,
609 .fixed_divider = 10,
610};
611
612static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
613 .name = "pllh_aux",
614 .source_pll = &bcm2835_pllh_data,
615 .cm_reg = CM_PLLH,
616 .a2w_reg = A2W_PLLH_AUX,
617 .load_mask = CM_PLLH_LOADAUX,
618 .hold_mask = 0,
619 .fixed_divider = 10,
620};
621
622static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
623 .name = "pllh_pix",
624 .source_pll = &bcm2835_pllh_data,
625 .cm_reg = CM_PLLH,
626 .a2w_reg = A2W_PLLH_PIX,
627 .load_mask = CM_PLLH_LOADPIX,
628 .hold_mask = 0,
629 .fixed_divider = 10,
630};
631
632struct bcm2835_clock_data { 432struct bcm2835_clock_data {
633 const char *name; 433 const char *name;
634 434
@@ -644,187 +444,14 @@ struct bcm2835_clock_data {
644 u32 frac_bits; 444 u32 frac_bits;
645 445
646 bool is_vpu_clock; 446 bool is_vpu_clock;
447 bool is_mash_clock;
647}; 448};
648 449
649static const char *const bcm2835_clock_per_parents[] = { 450struct bcm2835_gate_data {
650 "gnd", 451 const char *name;
651 "xosc", 452 const char *parent;
652 "testdebug0",
653 "testdebug1",
654 "plla_per",
655 "pllc_per",
656 "plld_per",
657 "pllh_aux",
658};
659
660static const char *const bcm2835_clock_vpu_parents[] = {
661 "gnd",
662 "xosc",
663 "testdebug0",
664 "testdebug1",
665 "plla_core",
666 "pllc_core0",
667 "plld_core",
668 "pllh_aux",
669 "pllc_core1",
670 "pllc_core2",
671};
672
673static const char *const bcm2835_clock_osc_parents[] = {
674 "gnd",
675 "xosc",
676 "testdebug0",
677 "testdebug1"
678};
679
680/*
681 * Used for a 1Mhz clock for the system clocksource, and also used by
682 * the watchdog timer and the camera pulse generator.
683 */
684static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
685 .name = "timer",
686 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
687 .parents = bcm2835_clock_osc_parents,
688 .ctl_reg = CM_TIMERCTL,
689 .div_reg = CM_TIMERDIV,
690 .int_bits = 6,
691 .frac_bits = 12,
692};
693
694/* One Time Programmable Memory clock. Maximum 10Mhz. */
695static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
696 .name = "otp",
697 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
698 .parents = bcm2835_clock_osc_parents,
699 .ctl_reg = CM_OTPCTL,
700 .div_reg = CM_OTPDIV,
701 .int_bits = 4,
702 .frac_bits = 0,
703};
704
705/*
706 * VPU clock. This doesn't have an enable bit, since it drives the
707 * bus for everything else, and is special so it doesn't need to be
708 * gated for rate changes. It is also known as "clk_audio" in various
709 * hardware documentation.
710 */
711static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
712 .name = "vpu",
713 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
714 .parents = bcm2835_clock_vpu_parents,
715 .ctl_reg = CM_VPUCTL,
716 .div_reg = CM_VPUDIV,
717 .int_bits = 12,
718 .frac_bits = 8,
719 .is_vpu_clock = true,
720};
721
722static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
723 .name = "v3d",
724 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
725 .parents = bcm2835_clock_vpu_parents,
726 .ctl_reg = CM_V3DCTL,
727 .div_reg = CM_V3DDIV,
728 .int_bits = 4,
729 .frac_bits = 8,
730};
731
732static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
733 .name = "isp",
734 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
735 .parents = bcm2835_clock_vpu_parents,
736 .ctl_reg = CM_ISPCTL,
737 .div_reg = CM_ISPDIV,
738 .int_bits = 4,
739 .frac_bits = 8,
740};
741
742static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
743 .name = "h264",
744 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
745 .parents = bcm2835_clock_vpu_parents,
746 .ctl_reg = CM_H264CTL,
747 .div_reg = CM_H264DIV,
748 .int_bits = 4,
749 .frac_bits = 8,
750};
751
752/* TV encoder clock. Only operating frequency is 108Mhz. */
753static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
754 .name = "vec",
755 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
756 .parents = bcm2835_clock_per_parents,
757 .ctl_reg = CM_VECCTL,
758 .div_reg = CM_VECDIV,
759 .int_bits = 4,
760 .frac_bits = 0,
761};
762
763static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
764 .name = "uart",
765 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
766 .parents = bcm2835_clock_per_parents,
767 .ctl_reg = CM_UARTCTL,
768 .div_reg = CM_UARTDIV,
769 .int_bits = 10,
770 .frac_bits = 12,
771};
772
773/* HDMI state machine */
774static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
775 .name = "hsm",
776 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
777 .parents = bcm2835_clock_per_parents,
778 .ctl_reg = CM_HSMCTL,
779 .div_reg = CM_HSMDIV,
780 .int_bits = 4,
781 .frac_bits = 8,
782};
783
784/*
785 * Secondary SDRAM clock. Used for low-voltage modes when the PLL in
786 * the SDRAM controller can't be used.
787 */
788static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
789 .name = "sdram",
790 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
791 .parents = bcm2835_clock_vpu_parents,
792 .ctl_reg = CM_SDCCTL,
793 .div_reg = CM_SDCDIV,
794 .int_bits = 6,
795 .frac_bits = 0,
796};
797
798/* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */
799static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
800 .name = "tsens",
801 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
802 .parents = bcm2835_clock_osc_parents,
803 .ctl_reg = CM_TSENSCTL,
804 .div_reg = CM_TSENSDIV,
805 .int_bits = 5,
806 .frac_bits = 0,
807};
808
809/* Arasan EMMC clock */
810static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
811 .name = "emmc",
812 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
813 .parents = bcm2835_clock_per_parents,
814 .ctl_reg = CM_EMMCCTL,
815 .div_reg = CM_EMMCDIV,
816 .int_bits = 4,
817 .frac_bits = 8,
818};
819 453
820static const struct bcm2835_clock_data bcm2835_clock_pwm_data = { 454 u32 ctl_reg;
821 .name = "pwm",
822 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
823 .parents = bcm2835_clock_per_parents,
824 .ctl_reg = CM_PWMCTL,
825 .div_reg = CM_PWMDIV,
826 .int_bits = 12,
827 .frac_bits = 12,
828}; 455};
829 456
830struct bcm2835_pll { 457struct bcm2835_pll {
@@ -910,8 +537,14 @@ static void bcm2835_pll_off(struct clk_hw *hw)
910 struct bcm2835_cprman *cprman = pll->cprman; 537 struct bcm2835_cprman *cprman = pll->cprman;
911 const struct bcm2835_pll_data *data = pll->data; 538 const struct bcm2835_pll_data *data = pll->data;
912 539
913 cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); 540 spin_lock(&cprman->regs_lock);
914 cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN); 541 cprman_write(cprman, data->cm_ctrl_reg,
542 cprman_read(cprman, data->cm_ctrl_reg) |
543 CM_PLL_ANARST);
544 cprman_write(cprman, data->a2w_ctrl_reg,
545 cprman_read(cprman, data->a2w_ctrl_reg) |
546 A2W_PLL_CTRL_PWRDN);
547 spin_unlock(&cprman->regs_lock);
915} 548}
916 549
917static int bcm2835_pll_on(struct clk_hw *hw) 550static int bcm2835_pll_on(struct clk_hw *hw)
@@ -921,6 +554,10 @@ static int bcm2835_pll_on(struct clk_hw *hw)
921 const struct bcm2835_pll_data *data = pll->data; 554 const struct bcm2835_pll_data *data = pll->data;
922 ktime_t timeout; 555 ktime_t timeout;
923 556
557 cprman_write(cprman, data->a2w_ctrl_reg,
558 cprman_read(cprman, data->a2w_ctrl_reg) &
559 ~A2W_PLL_CTRL_PWRDN);
560
924 /* Take the PLL out of reset. */ 561 /* Take the PLL out of reset. */
925 cprman_write(cprman, data->cm_ctrl_reg, 562 cprman_write(cprman, data->cm_ctrl_reg,
926 cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST); 563 cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
@@ -1030,6 +667,36 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
1030 return 0; 667 return 0;
1031} 668}
1032 669
670static int bcm2835_pll_debug_init(struct clk_hw *hw,
671 struct dentry *dentry)
672{
673 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
674 struct bcm2835_cprman *cprman = pll->cprman;
675 const struct bcm2835_pll_data *data = pll->data;
676 struct debugfs_reg32 *regs;
677
678 regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
679 if (!regs)
680 return -ENOMEM;
681
682 regs[0].name = "cm_ctrl";
683 regs[0].offset = data->cm_ctrl_reg;
684 regs[1].name = "a2w_ctrl";
685 regs[1].offset = data->a2w_ctrl_reg;
686 regs[2].name = "frac";
687 regs[2].offset = data->frac_reg;
688 regs[3].name = "ana0";
689 regs[3].offset = data->ana_reg_base + 0 * 4;
690 regs[4].name = "ana1";
691 regs[4].offset = data->ana_reg_base + 1 * 4;
692 regs[5].name = "ana2";
693 regs[5].offset = data->ana_reg_base + 2 * 4;
694 regs[6].name = "ana3";
695 regs[6].offset = data->ana_reg_base + 3 * 4;
696
697 return bcm2835_debugfs_regset(cprman, 0, regs, 7, dentry);
698}
699
1033static const struct clk_ops bcm2835_pll_clk_ops = { 700static const struct clk_ops bcm2835_pll_clk_ops = {
1034 .is_prepared = bcm2835_pll_is_on, 701 .is_prepared = bcm2835_pll_is_on,
1035 .prepare = bcm2835_pll_on, 702 .prepare = bcm2835_pll_on,
@@ -1037,6 +704,7 @@ static const struct clk_ops bcm2835_pll_clk_ops = {
1037 .recalc_rate = bcm2835_pll_get_rate, 704 .recalc_rate = bcm2835_pll_get_rate,
1038 .set_rate = bcm2835_pll_set_rate, 705 .set_rate = bcm2835_pll_set_rate,
1039 .round_rate = bcm2835_pll_round_rate, 706 .round_rate = bcm2835_pll_round_rate,
707 .debug_init = bcm2835_pll_debug_init,
1040}; 708};
1041 709
1042struct bcm2835_pll_divider { 710struct bcm2835_pll_divider {
@@ -1079,10 +747,12 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw)
1079 struct bcm2835_cprman *cprman = divider->cprman; 747 struct bcm2835_cprman *cprman = divider->cprman;
1080 const struct bcm2835_pll_divider_data *data = divider->data; 748 const struct bcm2835_pll_divider_data *data = divider->data;
1081 749
750 spin_lock(&cprman->regs_lock);
1082 cprman_write(cprman, data->cm_reg, 751 cprman_write(cprman, data->cm_reg,
1083 (cprman_read(cprman, data->cm_reg) & 752 (cprman_read(cprman, data->cm_reg) &
1084 ~data->load_mask) | data->hold_mask); 753 ~data->load_mask) | data->hold_mask);
1085 cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); 754 cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
755 spin_unlock(&cprman->regs_lock);
1086} 756}
1087 757
1088static int bcm2835_pll_divider_on(struct clk_hw *hw) 758static int bcm2835_pll_divider_on(struct clk_hw *hw)
@@ -1091,12 +761,14 @@ static int bcm2835_pll_divider_on(struct clk_hw *hw)
1091 struct bcm2835_cprman *cprman = divider->cprman; 761 struct bcm2835_cprman *cprman = divider->cprman;
1092 const struct bcm2835_pll_divider_data *data = divider->data; 762 const struct bcm2835_pll_divider_data *data = divider->data;
1093 763
764 spin_lock(&cprman->regs_lock);
1094 cprman_write(cprman, data->a2w_reg, 765 cprman_write(cprman, data->a2w_reg,
1095 cprman_read(cprman, data->a2w_reg) & 766 cprman_read(cprman, data->a2w_reg) &
1096 ~A2W_PLL_CHANNEL_DISABLE); 767 ~A2W_PLL_CHANNEL_DISABLE);
1097 768
1098 cprman_write(cprman, data->cm_reg, 769 cprman_write(cprman, data->cm_reg,
1099 cprman_read(cprman, data->cm_reg) & ~data->hold_mask); 770 cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
771 spin_unlock(&cprman->regs_lock);
1100 772
1101 return 0; 773 return 0;
1102} 774}
@@ -1124,6 +796,26 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
1124 return 0; 796 return 0;
1125} 797}
1126 798
799static int bcm2835_pll_divider_debug_init(struct clk_hw *hw,
800 struct dentry *dentry)
801{
802 struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
803 struct bcm2835_cprman *cprman = divider->cprman;
804 const struct bcm2835_pll_divider_data *data = divider->data;
805 struct debugfs_reg32 *regs;
806
807 regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
808 if (!regs)
809 return -ENOMEM;
810
811 regs[0].name = "cm";
812 regs[0].offset = data->cm_reg;
813 regs[1].name = "a2w";
814 regs[1].offset = data->a2w_reg;
815
816 return bcm2835_debugfs_regset(cprman, 0, regs, 2, dentry);
817}
818
1127static const struct clk_ops bcm2835_pll_divider_clk_ops = { 819static const struct clk_ops bcm2835_pll_divider_clk_ops = {
1128 .is_prepared = bcm2835_pll_divider_is_on, 820 .is_prepared = bcm2835_pll_divider_is_on,
1129 .prepare = bcm2835_pll_divider_on, 821 .prepare = bcm2835_pll_divider_on,
@@ -1131,6 +823,7 @@ static const struct clk_ops bcm2835_pll_divider_clk_ops = {
1131 .recalc_rate = bcm2835_pll_divider_get_rate, 823 .recalc_rate = bcm2835_pll_divider_get_rate,
1132 .set_rate = bcm2835_pll_divider_set_rate, 824 .set_rate = bcm2835_pll_divider_set_rate,
1133 .round_rate = bcm2835_pll_divider_round_rate, 825 .round_rate = bcm2835_pll_divider_round_rate,
826 .debug_init = bcm2835_pll_divider_debug_init,
1134}; 827};
1135 828
1136/* 829/*
@@ -1170,7 +863,7 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
1170 GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1; 863 GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
1171 u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS; 864 u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
1172 u64 rem; 865 u64 rem;
1173 u32 div; 866 u32 div, mindiv, maxdiv;
1174 867
1175 rem = do_div(temp, rate); 868 rem = do_div(temp, rate);
1176 div = temp; 869 div = temp;
@@ -1180,10 +873,23 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
1180 div += unused_frac_mask + 1; 873 div += unused_frac_mask + 1;
1181 div &= ~unused_frac_mask; 874 div &= ~unused_frac_mask;
1182 875
1183 /* Clamp to the limits. */ 876 /* different clamping limits apply for a mash clock */
1184 div = max(div, unused_frac_mask + 1); 877 if (data->is_mash_clock) {
1185 div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, 878 /* clamp to min divider of 2 */
1186 CM_DIV_FRAC_BITS - data->frac_bits)); 879 mindiv = 2 << CM_DIV_FRAC_BITS;
880 /* clamp to the highest possible integer divider */
881 maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS;
882 } else {
883 /* clamp to min divider of 1 */
884 mindiv = 1 << CM_DIV_FRAC_BITS;
885 /* clamp to the highest possible fractional divider */
886 maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
887 CM_DIV_FRAC_BITS - data->frac_bits);
888 }
889
890 /* apply the clamping limits */
891 div = max_t(u32, div, mindiv);
892 div = min_t(u32, div, maxdiv);
1187 893
1188 return div; 894 return div;
1189} 895}
@@ -1277,14 +983,31 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
1277 struct bcm2835_cprman *cprman = clock->cprman; 983 struct bcm2835_cprman *cprman = clock->cprman;
1278 const struct bcm2835_clock_data *data = clock->data; 984 const struct bcm2835_clock_data *data = clock->data;
1279 u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); 985 u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
986 u32 ctl;
987
988 spin_lock(&cprman->regs_lock);
989
990 /*
991 * Setting up frac support
992 *
993 * In principle it is recommended to stop/start the clock first,
994 * but as we set CLK_SET_RATE_GATE during registration of the
995 * clock this requirement should be take care of by the
996 * clk-framework.
997 */
998 ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
999 ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
1000 cprman_write(cprman, data->ctl_reg, ctl);
1280 1001
1281 cprman_write(cprman, data->div_reg, div); 1002 cprman_write(cprman, data->div_reg, div);
1282 1003
1004 spin_unlock(&cprman->regs_lock);
1005
1283 return 0; 1006 return 0;
1284} 1007}
1285 1008
1286static int bcm2835_clock_determine_rate(struct clk_hw *hw, 1009static int bcm2835_clock_determine_rate(struct clk_hw *hw,
1287 struct clk_rate_request *req) 1010 struct clk_rate_request *req)
1288{ 1011{
1289 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); 1012 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1290 struct clk_hw *parent, *best_parent = NULL; 1013 struct clk_hw *parent, *best_parent = NULL;
@@ -1342,6 +1065,30 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
1342 return (src & CM_SRC_MASK) >> CM_SRC_SHIFT; 1065 return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
1343} 1066}
1344 1067
1068static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
1069 {
1070 .name = "ctl",
1071 .offset = 0,
1072 },
1073 {
1074 .name = "div",
1075 .offset = 4,
1076 },
1077};
1078
1079static int bcm2835_clock_debug_init(struct clk_hw *hw,
1080 struct dentry *dentry)
1081{
1082 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1083 struct bcm2835_cprman *cprman = clock->cprman;
1084 const struct bcm2835_clock_data *data = clock->data;
1085
1086 return bcm2835_debugfs_regset(
1087 cprman, data->ctl_reg,
1088 bcm2835_debugfs_clock_reg32,
1089 ARRAY_SIZE(bcm2835_debugfs_clock_reg32),
1090 dentry);
1091}
1345 1092
1346static const struct clk_ops bcm2835_clock_clk_ops = { 1093static const struct clk_ops bcm2835_clock_clk_ops = {
1347 .is_prepared = bcm2835_clock_is_on, 1094 .is_prepared = bcm2835_clock_is_on,
@@ -1352,6 +1099,7 @@ static const struct clk_ops bcm2835_clock_clk_ops = {
1352 .determine_rate = bcm2835_clock_determine_rate, 1099 .determine_rate = bcm2835_clock_determine_rate,
1353 .set_parent = bcm2835_clock_set_parent, 1100 .set_parent = bcm2835_clock_set_parent,
1354 .get_parent = bcm2835_clock_get_parent, 1101 .get_parent = bcm2835_clock_get_parent,
1102 .debug_init = bcm2835_clock_debug_init,
1355}; 1103};
1356 1104
1357static int bcm2835_vpu_clock_is_on(struct clk_hw *hw) 1105static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
@@ -1370,6 +1118,7 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
1370 .determine_rate = bcm2835_clock_determine_rate, 1118 .determine_rate = bcm2835_clock_determine_rate,
1371 .set_parent = bcm2835_clock_set_parent, 1119 .set_parent = bcm2835_clock_set_parent,
1372 .get_parent = bcm2835_clock_get_parent, 1120 .get_parent = bcm2835_clock_get_parent,
1121 .debug_init = bcm2835_clock_debug_init,
1373}; 1122};
1374 1123
1375static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman, 1124static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
@@ -1418,7 +1167,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
1418 1167
1419 memset(&init, 0, sizeof(init)); 1168 memset(&init, 0, sizeof(init));
1420 1169
1421 init.parent_names = &data->source_pll->name; 1170 init.parent_names = &data->source_pll;
1422 init.num_parents = 1; 1171 init.num_parents = 1;
1423 init.name = divider_name; 1172 init.name = divider_name;
1424 init.ops = &bcm2835_pll_divider_clk_ops; 1173 init.ops = &bcm2835_pll_divider_clk_ops;
@@ -1501,14 +1250,559 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1501 return devm_clk_register(cprman->dev, &clock->hw); 1250 return devm_clk_register(cprman->dev, &clock->hw);
1502} 1251}
1503 1252
1253static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
1254 const struct bcm2835_gate_data *data)
1255{
1256 return clk_register_gate(cprman->dev, data->name, data->parent,
1257 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
1258 cprman->regs + data->ctl_reg,
1259 CM_GATE_BIT, 0, &cprman->regs_lock);
1260}
1261
1262typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
1263 const void *data);
1264struct bcm2835_clk_desc {
1265 bcm2835_clk_register clk_register;
1266 const void *data;
1267};
1268
1269/* assignment helper macros for different clock types */
1270#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
1271 .data = __VA_ARGS__ }
1272#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \
1273 &(struct bcm2835_pll_data) \
1274 {__VA_ARGS__})
1275#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \
1276 &(struct bcm2835_pll_divider_data) \
1277 {__VA_ARGS__})
1278#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \
1279 &(struct bcm2835_clock_data) \
1280 {__VA_ARGS__})
1281#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \
1282 &(struct bcm2835_gate_data) \
1283 {__VA_ARGS__})
1284
1285/* parent mux arrays plus helper macros */
1286
1287/* main oscillator parent mux */
1288static const char *const bcm2835_clock_osc_parents[] = {
1289 "gnd",
1290 "xosc",
1291 "testdebug0",
1292 "testdebug1"
1293};
1294
1295#define REGISTER_OSC_CLK(...) REGISTER_CLK( \
1296 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \
1297 .parents = bcm2835_clock_osc_parents, \
1298 __VA_ARGS__)
1299
1300/* main peripherial parent mux */
1301static const char *const bcm2835_clock_per_parents[] = {
1302 "gnd",
1303 "xosc",
1304 "testdebug0",
1305 "testdebug1",
1306 "plla_per",
1307 "pllc_per",
1308 "plld_per",
1309 "pllh_aux",
1310};
1311
1312#define REGISTER_PER_CLK(...) REGISTER_CLK( \
1313 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \
1314 .parents = bcm2835_clock_per_parents, \
1315 __VA_ARGS__)
1316
1317/* main vpu parent mux */
1318static const char *const bcm2835_clock_vpu_parents[] = {
1319 "gnd",
1320 "xosc",
1321 "testdebug0",
1322 "testdebug1",
1323 "plla_core",
1324 "pllc_core0",
1325 "plld_core",
1326 "pllh_aux",
1327 "pllc_core1",
1328 "pllc_core2",
1329};
1330
1331#define REGISTER_VPU_CLK(...) REGISTER_CLK( \
1332 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \
1333 .parents = bcm2835_clock_vpu_parents, \
1334 __VA_ARGS__)
1335
1336/*
1337 * the real definition of all the pll, pll_dividers and clocks
1338 * these make use of the above REGISTER_* macros
1339 */
1340static const struct bcm2835_clk_desc clk_desc_array[] = {
1341 /* the PLL + PLL dividers */
1342
1343 /*
1344 * PLLA is the auxiliary PLL, used to drive the CCP2
1345 * (Compact Camera Port 2) transmitter clock.
1346 *
1347 * It is in the PX LDO power domain, which is on when the
1348 * AUDIO domain is on.
1349 */
1350 [BCM2835_PLLA] = REGISTER_PLL(
1351 .name = "plla",
1352 .cm_ctrl_reg = CM_PLLA,
1353 .a2w_ctrl_reg = A2W_PLLA_CTRL,
1354 .frac_reg = A2W_PLLA_FRAC,
1355 .ana_reg_base = A2W_PLLA_ANA0,
1356 .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
1357 .lock_mask = CM_LOCK_FLOCKA,
1358
1359 .ana = &bcm2835_ana_default,
1360
1361 .min_rate = 600000000u,
1362 .max_rate = 2400000000u,
1363 .max_fb_rate = BCM2835_MAX_FB_RATE),
1364 [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(
1365 .name = "plla_core",
1366 .source_pll = "plla",
1367 .cm_reg = CM_PLLA,
1368 .a2w_reg = A2W_PLLA_CORE,
1369 .load_mask = CM_PLLA_LOADCORE,
1370 .hold_mask = CM_PLLA_HOLDCORE,
1371 .fixed_divider = 1),
1372 [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
1373 .name = "plla_per",
1374 .source_pll = "plla",
1375 .cm_reg = CM_PLLA,
1376 .a2w_reg = A2W_PLLA_PER,
1377 .load_mask = CM_PLLA_LOADPER,
1378 .hold_mask = CM_PLLA_HOLDPER,
1379 .fixed_divider = 1),
1380 [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
1381 .name = "plla_dsi0",
1382 .source_pll = "plla",
1383 .cm_reg = CM_PLLA,
1384 .a2w_reg = A2W_PLLA_DSI0,
1385 .load_mask = CM_PLLA_LOADDSI0,
1386 .hold_mask = CM_PLLA_HOLDDSI0,
1387 .fixed_divider = 1),
1388 [BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV(
1389 .name = "plla_ccp2",
1390 .source_pll = "plla",
1391 .cm_reg = CM_PLLA,
1392 .a2w_reg = A2W_PLLA_CCP2,
1393 .load_mask = CM_PLLA_LOADCCP2,
1394 .hold_mask = CM_PLLA_HOLDCCP2,
1395 .fixed_divider = 1),
1396
1397 /* PLLB is used for the ARM's clock. */
1398 [BCM2835_PLLB] = REGISTER_PLL(
1399 .name = "pllb",
1400 .cm_ctrl_reg = CM_PLLB,
1401 .a2w_ctrl_reg = A2W_PLLB_CTRL,
1402 .frac_reg = A2W_PLLB_FRAC,
1403 .ana_reg_base = A2W_PLLB_ANA0,
1404 .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
1405 .lock_mask = CM_LOCK_FLOCKB,
1406
1407 .ana = &bcm2835_ana_default,
1408
1409 .min_rate = 600000000u,
1410 .max_rate = 3000000000u,
1411 .max_fb_rate = BCM2835_MAX_FB_RATE),
1412 [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV(
1413 .name = "pllb_arm",
1414 .source_pll = "pllb",
1415 .cm_reg = CM_PLLB,
1416 .a2w_reg = A2W_PLLB_ARM,
1417 .load_mask = CM_PLLB_LOADARM,
1418 .hold_mask = CM_PLLB_HOLDARM,
1419 .fixed_divider = 1),
1420
1421 /*
1422 * PLLC is the core PLL, used to drive the core VPU clock.
1423 *
1424 * It is in the PX LDO power domain, which is on when the
1425 * AUDIO domain is on.
1426 */
1427 [BCM2835_PLLC] = REGISTER_PLL(
1428 .name = "pllc",
1429 .cm_ctrl_reg = CM_PLLC,
1430 .a2w_ctrl_reg = A2W_PLLC_CTRL,
1431 .frac_reg = A2W_PLLC_FRAC,
1432 .ana_reg_base = A2W_PLLC_ANA0,
1433 .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
1434 .lock_mask = CM_LOCK_FLOCKC,
1435
1436 .ana = &bcm2835_ana_default,
1437
1438 .min_rate = 600000000u,
1439 .max_rate = 3000000000u,
1440 .max_fb_rate = BCM2835_MAX_FB_RATE),
1441 [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(
1442 .name = "pllc_core0",
1443 .source_pll = "pllc",
1444 .cm_reg = CM_PLLC,
1445 .a2w_reg = A2W_PLLC_CORE0,
1446 .load_mask = CM_PLLC_LOADCORE0,
1447 .hold_mask = CM_PLLC_HOLDCORE0,
1448 .fixed_divider = 1),
1449 [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
1450 .name = "pllc_core1",
1451 .source_pll = "pllc",
1452 .cm_reg = CM_PLLC,
1453 .a2w_reg = A2W_PLLC_CORE1,
1454 .load_mask = CM_PLLC_LOADCORE1,
1455 .hold_mask = CM_PLLC_HOLDCORE1,
1456 .fixed_divider = 1),
1457 [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
1458 .name = "pllc_core2",
1459 .source_pll = "pllc",
1460 .cm_reg = CM_PLLC,
1461 .a2w_reg = A2W_PLLC_CORE2,
1462 .load_mask = CM_PLLC_LOADCORE2,
1463 .hold_mask = CM_PLLC_HOLDCORE2,
1464 .fixed_divider = 1),
1465 [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
1466 .name = "pllc_per",
1467 .source_pll = "pllc",
1468 .cm_reg = CM_PLLC,
1469 .a2w_reg = A2W_PLLC_PER,
1470 .load_mask = CM_PLLC_LOADPER,
1471 .hold_mask = CM_PLLC_HOLDPER,
1472 .fixed_divider = 1),
1473
1474 /*
1475 * PLLD is the display PLL, used to drive DSI display panels.
1476 *
1477 * It is in the PX LDO power domain, which is on when the
1478 * AUDIO domain is on.
1479 */
1480 [BCM2835_PLLD] = REGISTER_PLL(
1481 .name = "plld",
1482 .cm_ctrl_reg = CM_PLLD,
1483 .a2w_ctrl_reg = A2W_PLLD_CTRL,
1484 .frac_reg = A2W_PLLD_FRAC,
1485 .ana_reg_base = A2W_PLLD_ANA0,
1486 .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
1487 .lock_mask = CM_LOCK_FLOCKD,
1488
1489 .ana = &bcm2835_ana_default,
1490
1491 .min_rate = 600000000u,
1492 .max_rate = 2400000000u,
1493 .max_fb_rate = BCM2835_MAX_FB_RATE),
1494 [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(
1495 .name = "plld_core",
1496 .source_pll = "plld",
1497 .cm_reg = CM_PLLD,
1498 .a2w_reg = A2W_PLLD_CORE,
1499 .load_mask = CM_PLLD_LOADCORE,
1500 .hold_mask = CM_PLLD_HOLDCORE,
1501 .fixed_divider = 1),
1502 [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
1503 .name = "plld_per",
1504 .source_pll = "plld",
1505 .cm_reg = CM_PLLD,
1506 .a2w_reg = A2W_PLLD_PER,
1507 .load_mask = CM_PLLD_LOADPER,
1508 .hold_mask = CM_PLLD_HOLDPER,
1509 .fixed_divider = 1),
1510 [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
1511 .name = "plld_dsi0",
1512 .source_pll = "plld",
1513 .cm_reg = CM_PLLD,
1514 .a2w_reg = A2W_PLLD_DSI0,
1515 .load_mask = CM_PLLD_LOADDSI0,
1516 .hold_mask = CM_PLLD_HOLDDSI0,
1517 .fixed_divider = 1),
1518 [BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV(
1519 .name = "plld_dsi1",
1520 .source_pll = "plld",
1521 .cm_reg = CM_PLLD,
1522 .a2w_reg = A2W_PLLD_DSI1,
1523 .load_mask = CM_PLLD_LOADDSI1,
1524 .hold_mask = CM_PLLD_HOLDDSI1,
1525 .fixed_divider = 1),
1526
1527 /*
1528 * PLLH is used to supply the pixel clock or the AUX clock for the
1529 * TV encoder.
1530 *
1531 * It is in the HDMI power domain.
1532 */
1533 [BCM2835_PLLH] = REGISTER_PLL(
1534 "pllh",
1535 .cm_ctrl_reg = CM_PLLH,
1536 .a2w_ctrl_reg = A2W_PLLH_CTRL,
1537 .frac_reg = A2W_PLLH_FRAC,
1538 .ana_reg_base = A2W_PLLH_ANA0,
1539 .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
1540 .lock_mask = CM_LOCK_FLOCKH,
1541
1542 .ana = &bcm2835_ana_pllh,
1543
1544 .min_rate = 600000000u,
1545 .max_rate = 3000000000u,
1546 .max_fb_rate = BCM2835_MAX_FB_RATE),
1547 [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(
1548 .name = "pllh_rcal",
1549 .source_pll = "pllh",
1550 .cm_reg = CM_PLLH,
1551 .a2w_reg = A2W_PLLH_RCAL,
1552 .load_mask = CM_PLLH_LOADRCAL,
1553 .hold_mask = 0,
1554 .fixed_divider = 10),
1555 [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
1556 .name = "pllh_aux",
1557 .source_pll = "pllh",
1558 .cm_reg = CM_PLLH,
1559 .a2w_reg = A2W_PLLH_AUX,
1560 .load_mask = CM_PLLH_LOADAUX,
1561 .hold_mask = 0,
1562 .fixed_divider = 10),
1563 [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
1564 .name = "pllh_pix",
1565 .source_pll = "pllh",
1566 .cm_reg = CM_PLLH,
1567 .a2w_reg = A2W_PLLH_PIX,
1568 .load_mask = CM_PLLH_LOADPIX,
1569 .hold_mask = 0,
1570 .fixed_divider = 10),
1571
1572 /* the clocks */
1573
1574 /* clocks with oscillator parent mux */
1575
1576 /* One Time Programmable Memory clock. Maximum 10Mhz. */
1577 [BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK(
1578 .name = "otp",
1579 .ctl_reg = CM_OTPCTL,
1580 .div_reg = CM_OTPDIV,
1581 .int_bits = 4,
1582 .frac_bits = 0),
1583 /*
1584 * Used for a 1Mhz clock for the system clocksource, and also used
1585 * bythe watchdog timer and the camera pulse generator.
1586 */
1587 [BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK(
1588 .name = "timer",
1589 .ctl_reg = CM_TIMERCTL,
1590 .div_reg = CM_TIMERDIV,
1591 .int_bits = 6,
1592 .frac_bits = 12),
1593 /*
1594 * Clock for the temperature sensor.
1595 * Generally run at 2Mhz, max 5Mhz.
1596 */
1597 [BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK(
1598 .name = "tsens",
1599 .ctl_reg = CM_TSENSCTL,
1600 .div_reg = CM_TSENSDIV,
1601 .int_bits = 5,
1602 .frac_bits = 0),
1603 [BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK(
1604 .name = "tec",
1605 .ctl_reg = CM_TECCTL,
1606 .div_reg = CM_TECDIV,
1607 .int_bits = 6,
1608 .frac_bits = 0),
1609
1610 /* clocks with vpu parent mux */
1611 [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK(
1612 .name = "h264",
1613 .ctl_reg = CM_H264CTL,
1614 .div_reg = CM_H264DIV,
1615 .int_bits = 4,
1616 .frac_bits = 8),
1617 [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
1618 .name = "isp",
1619 .ctl_reg = CM_ISPCTL,
1620 .div_reg = CM_ISPDIV,
1621 .int_bits = 4,
1622 .frac_bits = 8),
1623
1624 /*
1625 * Secondary SDRAM clock. Used for low-voltage modes when the PLL
1626 * in the SDRAM controller can't be used.
1627 */
1628 [BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK(
1629 .name = "sdram",
1630 .ctl_reg = CM_SDCCTL,
1631 .div_reg = CM_SDCDIV,
1632 .int_bits = 6,
1633 .frac_bits = 0),
1634 [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
1635 .name = "v3d",
1636 .ctl_reg = CM_V3DCTL,
1637 .div_reg = CM_V3DDIV,
1638 .int_bits = 4,
1639 .frac_bits = 8),
1640 /*
1641 * VPU clock. This doesn't have an enable bit, since it drives
1642 * the bus for everything else, and is special so it doesn't need
1643 * to be gated for rate changes. It is also known as "clk_audio"
1644 * in various hardware documentation.
1645 */
1646 [BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK(
1647 .name = "vpu",
1648 .ctl_reg = CM_VPUCTL,
1649 .div_reg = CM_VPUDIV,
1650 .int_bits = 12,
1651 .frac_bits = 8,
1652 .is_vpu_clock = true),
1653
1654 /* clocks with per parent mux */
1655 [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
1656 .name = "aveo",
1657 .ctl_reg = CM_AVEOCTL,
1658 .div_reg = CM_AVEODIV,
1659 .int_bits = 4,
1660 .frac_bits = 0),
1661 [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
1662 .name = "cam0",
1663 .ctl_reg = CM_CAM0CTL,
1664 .div_reg = CM_CAM0DIV,
1665 .int_bits = 4,
1666 .frac_bits = 8),
1667 [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
1668 .name = "cam1",
1669 .ctl_reg = CM_CAM1CTL,
1670 .div_reg = CM_CAM1DIV,
1671 .int_bits = 4,
1672 .frac_bits = 8),
1673 [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
1674 .name = "dft",
1675 .ctl_reg = CM_DFTCTL,
1676 .div_reg = CM_DFTDIV,
1677 .int_bits = 5,
1678 .frac_bits = 0),
1679 [BCM2835_CLOCK_DPI] = REGISTER_PER_CLK(
1680 .name = "dpi",
1681 .ctl_reg = CM_DPICTL,
1682 .div_reg = CM_DPIDIV,
1683 .int_bits = 4,
1684 .frac_bits = 8),
1685
1686 /* Arasan EMMC clock */
1687 [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
1688 .name = "emmc",
1689 .ctl_reg = CM_EMMCCTL,
1690 .div_reg = CM_EMMCDIV,
1691 .int_bits = 4,
1692 .frac_bits = 8),
1693
1694 /* General purpose (GPIO) clocks */
1695 [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
1696 .name = "gp0",
1697 .ctl_reg = CM_GP0CTL,
1698 .div_reg = CM_GP0DIV,
1699 .int_bits = 12,
1700 .frac_bits = 12,
1701 .is_mash_clock = true),
1702 [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
1703 .name = "gp1",
1704 .ctl_reg = CM_GP1CTL,
1705 .div_reg = CM_GP1DIV,
1706 .int_bits = 12,
1707 .frac_bits = 12,
1708 .is_mash_clock = true),
1709 [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
1710 .name = "gp2",
1711 .ctl_reg = CM_GP2CTL,
1712 .div_reg = CM_GP2DIV,
1713 .int_bits = 12,
1714 .frac_bits = 12),
1715
1716 /* HDMI state machine */
1717 [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
1718 .name = "hsm",
1719 .ctl_reg = CM_HSMCTL,
1720 .div_reg = CM_HSMDIV,
1721 .int_bits = 4,
1722 .frac_bits = 8),
1723 [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK(
1724 .name = "pcm",
1725 .ctl_reg = CM_PCMCTL,
1726 .div_reg = CM_PCMDIV,
1727 .int_bits = 12,
1728 .frac_bits = 12,
1729 .is_mash_clock = true),
1730 [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
1731 .name = "pwm",
1732 .ctl_reg = CM_PWMCTL,
1733 .div_reg = CM_PWMDIV,
1734 .int_bits = 12,
1735 .frac_bits = 12,
1736 .is_mash_clock = true),
1737 [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
1738 .name = "slim",
1739 .ctl_reg = CM_SLIMCTL,
1740 .div_reg = CM_SLIMDIV,
1741 .int_bits = 12,
1742 .frac_bits = 12,
1743 .is_mash_clock = true),
1744 [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
1745 .name = "smi",
1746 .ctl_reg = CM_SMICTL,
1747 .div_reg = CM_SMIDIV,
1748 .int_bits = 4,
1749 .frac_bits = 8),
1750 [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
1751 .name = "uart",
1752 .ctl_reg = CM_UARTCTL,
1753 .div_reg = CM_UARTDIV,
1754 .int_bits = 10,
1755 .frac_bits = 12),
1756
1757 /* TV encoder clock. Only operating frequency is 108Mhz. */
1758 [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
1759 .name = "vec",
1760 .ctl_reg = CM_VECCTL,
1761 .div_reg = CM_VECDIV,
1762 .int_bits = 4,
1763 .frac_bits = 0),
1764
1765 /* dsi clocks */
1766 [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
1767 .name = "dsi0e",
1768 .ctl_reg = CM_DSI0ECTL,
1769 .div_reg = CM_DSI0EDIV,
1770 .int_bits = 4,
1771 .frac_bits = 8),
1772 [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
1773 .name = "dsi1e",
1774 .ctl_reg = CM_DSI1ECTL,
1775 .div_reg = CM_DSI1EDIV,
1776 .int_bits = 4,
1777 .frac_bits = 8),
1778
1779 /* the gates */
1780
1781 /*
1782 * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
1783 * you have the debug bit set in the power manager, which we
1784 * don't bother exposing) are individual gates off of the
1785 * non-stop vpu clock.
1786 */
1787 [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
1788 .name = "peri_image",
1789 .parent = "vpu",
1790 .ctl_reg = CM_PERIICTL),
1791};
1792
1504static int bcm2835_clk_probe(struct platform_device *pdev) 1793static int bcm2835_clk_probe(struct platform_device *pdev)
1505{ 1794{
1506 struct device *dev = &pdev->dev; 1795 struct device *dev = &pdev->dev;
1507 struct clk **clks; 1796 struct clk **clks;
1508 struct bcm2835_cprman *cprman; 1797 struct bcm2835_cprman *cprman;
1509 struct resource *res; 1798 struct resource *res;
1799 const struct bcm2835_clk_desc *desc;
1800 const size_t asize = ARRAY_SIZE(clk_desc_array);
1801 size_t i;
1510 1802
1511 cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL); 1803 cprman = devm_kzalloc(dev,
1804 sizeof(*cprman) + asize * sizeof(*clks),
1805 GFP_KERNEL);
1512 if (!cprman) 1806 if (!cprman)
1513 return -ENOMEM; 1807 return -ENOMEM;
1514 1808
@@ -1525,80 +1819,15 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
1525 1819
1526 platform_set_drvdata(pdev, cprman); 1820 platform_set_drvdata(pdev, cprman);
1527 1821
1528 cprman->onecell.clk_num = BCM2835_CLOCK_COUNT; 1822 cprman->onecell.clk_num = asize;
1529 cprman->onecell.clks = cprman->clks; 1823 cprman->onecell.clks = cprman->clks;
1530 clks = cprman->clks; 1824 clks = cprman->clks;
1531 1825
1532 clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data); 1826 for (i = 0; i < asize; i++) {
1533 clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data); 1827 desc = &clk_desc_array[i];
1534 clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data); 1828 if (desc->clk_register && desc->data)
1535 clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data); 1829 clks[i] = desc->clk_register(cprman, desc->data);
1536 clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data); 1830 }
1537
1538 clks[BCM2835_PLLA_CORE] =
1539 bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
1540 clks[BCM2835_PLLA_PER] =
1541 bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
1542 clks[BCM2835_PLLC_CORE0] =
1543 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
1544 clks[BCM2835_PLLC_CORE1] =
1545 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
1546 clks[BCM2835_PLLC_CORE2] =
1547 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
1548 clks[BCM2835_PLLC_PER] =
1549 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
1550 clks[BCM2835_PLLD_CORE] =
1551 bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
1552 clks[BCM2835_PLLD_PER] =
1553 bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
1554 clks[BCM2835_PLLH_RCAL] =
1555 bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
1556 clks[BCM2835_PLLH_AUX] =
1557 bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
1558 clks[BCM2835_PLLH_PIX] =
1559 bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
1560
1561 clks[BCM2835_CLOCK_TIMER] =
1562 bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
1563 clks[BCM2835_CLOCK_OTP] =
1564 bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
1565 clks[BCM2835_CLOCK_TSENS] =
1566 bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
1567 clks[BCM2835_CLOCK_VPU] =
1568 bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
1569 clks[BCM2835_CLOCK_V3D] =
1570 bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
1571 clks[BCM2835_CLOCK_ISP] =
1572 bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
1573 clks[BCM2835_CLOCK_H264] =
1574 bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
1575 clks[BCM2835_CLOCK_V3D] =
1576 bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
1577 clks[BCM2835_CLOCK_SDRAM] =
1578 bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
1579 clks[BCM2835_CLOCK_UART] =
1580 bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
1581 clks[BCM2835_CLOCK_VEC] =
1582 bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
1583 clks[BCM2835_CLOCK_HSM] =
1584 bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
1585 clks[BCM2835_CLOCK_EMMC] =
1586 bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
1587
1588 /*
1589 * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
1590 * you have the debug bit set in the power manager, which we
1591 * don't bother exposing) are individual gates off of the
1592 * non-stop vpu clock.
1593 */
1594 clks[BCM2835_CLOCK_PERI_IMAGE] =
1595 clk_register_gate(dev, "peri_image", "vpu",
1596 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
1597 cprman->regs + CM_PERIICTL, CM_GATE_BIT,
1598 0, &cprman->regs_lock);
1599
1600 clks[BCM2835_CLOCK_PWM] =
1601 bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data);
1602 1831
1603 return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, 1832 return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
1604 &cprman->onecell); 1833 &cprman->onecell);
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index deaa7f962b84..526b0b0e9a9f 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -577,7 +577,8 @@ static u32 *parent_process(const char *clocks[],
577 * selector is not required, but we allocate space for the 577 * selector is not required, but we allocate space for the
578 * array anyway to keep things simple. 578 * array anyway to keep things simple.
579 */ 579 */
580 parent_names = kmalloc(parent_count * sizeof(parent_names), GFP_KERNEL); 580 parent_names = kmalloc_array(parent_count, sizeof(*parent_names),
581 GFP_KERNEL);
581 if (!parent_names) { 582 if (!parent_names) {
582 pr_err("%s: error allocating %u parent names\n", __func__, 583 pr_err("%s: error allocating %u parent names\n", __func__,
583 parent_count); 584 parent_count);
diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c
index ff4ef4f1df62..1f60b02416a7 100644
--- a/drivers/clk/clk-clps711x.c
+++ b/drivers/clk/clk-clps711x.c
@@ -107,16 +107,15 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
107 writel(tmp, base + CLPS711X_SYSCON1); 107 writel(tmp, base + CLPS711X_SYSCON1);
108 108
109 clps711x_clk->clks[CLPS711X_CLK_DUMMY] = 109 clps711x_clk->clks[CLPS711X_CLK_DUMMY] =
110 clk_register_fixed_rate(NULL, "dummy", NULL, CLK_IS_ROOT, 0); 110 clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
111 clps711x_clk->clks[CLPS711X_CLK_CPU] = 111 clps711x_clk->clks[CLPS711X_CLK_CPU] =
112 clk_register_fixed_rate(NULL, "cpu", NULL, CLK_IS_ROOT, f_cpu); 112 clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
113 clps711x_clk->clks[CLPS711X_CLK_BUS] = 113 clps711x_clk->clks[CLPS711X_CLK_BUS] =
114 clk_register_fixed_rate(NULL, "bus", NULL, CLK_IS_ROOT, f_bus); 114 clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
115 clps711x_clk->clks[CLPS711X_CLK_PLL] = 115 clps711x_clk->clks[CLPS711X_CLK_PLL] =
116 clk_register_fixed_rate(NULL, "pll", NULL, CLK_IS_ROOT, f_pll); 116 clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
117 clps711x_clk->clks[CLPS711X_CLK_TIMERREF] = 117 clps711x_clk->clks[CLPS711X_CLK_TIMERREF] =
118 clk_register_fixed_rate(NULL, "timer_ref", NULL, CLK_IS_ROOT, 118 clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
119 f_tim);
120 clps711x_clk->clks[CLPS711X_CLK_TIMER1] = 119 clps711x_clk->clks[CLPS711X_CLK_TIMER1] =
121 clk_register_divider_table(NULL, "timer1", "timer_ref", 0, 120 clk_register_divider_table(NULL, "timer1", "timer_ref", 0,
122 base + CLPS711X_SYSCON1, 5, 1, 0, 121 base + CLPS711X_SYSCON1, 5, 1, 0,
@@ -126,10 +125,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
126 base + CLPS711X_SYSCON1, 7, 1, 0, 125 base + CLPS711X_SYSCON1, 7, 1, 0,
127 timer_div_table, &clps711x_clk->lock); 126 timer_div_table, &clps711x_clk->lock);
128 clps711x_clk->clks[CLPS711X_CLK_PWM] = 127 clps711x_clk->clks[CLPS711X_CLK_PWM] =
129 clk_register_fixed_rate(NULL, "pwm", NULL, CLK_IS_ROOT, f_pwm); 128 clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
130 clps711x_clk->clks[CLPS711X_CLK_SPIREF] = 129 clps711x_clk->clks[CLPS711X_CLK_SPIREF] =
131 clk_register_fixed_rate(NULL, "spi_ref", NULL, CLK_IS_ROOT, 130 clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
132 f_spi);
133 clps711x_clk->clks[CLPS711X_CLK_SPI] = 131 clps711x_clk->clks[CLPS711X_CLK_SPI] =
134 clk_register_divider_table(NULL, "spi", "spi_ref", 0, 132 clk_register_divider_table(NULL, "spi", "spi_ref", 0,
135 base + CLPS711X_SYSCON1, 16, 2, 0, 133 base + CLPS711X_SYSCON1, 16, 2, 0,
@@ -137,8 +135,7 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
137 clps711x_clk->clks[CLPS711X_CLK_UART] = 135 clps711x_clk->clks[CLPS711X_CLK_UART] =
138 clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10); 136 clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
139 clps711x_clk->clks[CLPS711X_CLK_TICK] = 137 clps711x_clk->clks[CLPS711X_CLK_TICK] =
140 clk_register_fixed_rate(NULL, "tick", NULL, CLK_IS_ROOT, 64); 138 clk_register_fixed_rate(NULL, "tick", NULL, 0, 64);
141
142 for (i = 0; i < CLPS711X_CLK_MAX; i++) 139 for (i = 0; i < CLPS711X_CLK_MAX; i++)
143 if (IS_ERR(clps711x_clk->clks[i])) 140 if (IS_ERR(clps711x_clk->clks[i]))
144 pr_err("clk %i: register failed with %ld\n", 141 pr_err("clk %i: register failed with %ld\n",
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 1f903e1f86a2..00269de2f390 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -151,6 +151,33 @@ static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
151 return rate_ops->set_rate(rate_hw, rate, parent_rate); 151 return rate_ops->set_rate(rate_hw, rate, parent_rate);
152} 152}
153 153
154static int clk_composite_set_rate_and_parent(struct clk_hw *hw,
155 unsigned long rate,
156 unsigned long parent_rate,
157 u8 index)
158{
159 struct clk_composite *composite = to_clk_composite(hw);
160 const struct clk_ops *rate_ops = composite->rate_ops;
161 const struct clk_ops *mux_ops = composite->mux_ops;
162 struct clk_hw *rate_hw = composite->rate_hw;
163 struct clk_hw *mux_hw = composite->mux_hw;
164 unsigned long temp_rate;
165
166 __clk_hw_set_clk(rate_hw, hw);
167 __clk_hw_set_clk(mux_hw, hw);
168
169 temp_rate = rate_ops->recalc_rate(rate_hw, parent_rate);
170 if (temp_rate > rate) {
171 rate_ops->set_rate(rate_hw, rate, parent_rate);
172 mux_ops->set_parent(mux_hw, index);
173 } else {
174 mux_ops->set_parent(mux_hw, index);
175 rate_ops->set_rate(rate_hw, rate, parent_rate);
176 }
177
178 return 0;
179}
180
154static int clk_composite_is_enabled(struct clk_hw *hw) 181static int clk_composite_is_enabled(struct clk_hw *hw)
155{ 182{
156 struct clk_composite *composite = to_clk_composite(hw); 183 struct clk_composite *composite = to_clk_composite(hw);
@@ -184,17 +211,18 @@ static void clk_composite_disable(struct clk_hw *hw)
184 gate_ops->disable(gate_hw); 211 gate_ops->disable(gate_hw);
185} 212}
186 213
187struct clk *clk_register_composite(struct device *dev, const char *name, 214struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
188 const char * const *parent_names, int num_parents, 215 const char * const *parent_names, int num_parents,
189 struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 216 struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
190 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 217 struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
191 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 218 struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
192 unsigned long flags) 219 unsigned long flags)
193{ 220{
194 struct clk *clk; 221 struct clk_hw *hw;
195 struct clk_init_data init; 222 struct clk_init_data init;
196 struct clk_composite *composite; 223 struct clk_composite *composite;
197 struct clk_ops *clk_composite_ops; 224 struct clk_ops *clk_composite_ops;
225 int ret;
198 226
199 composite = kzalloc(sizeof(*composite), GFP_KERNEL); 227 composite = kzalloc(sizeof(*composite), GFP_KERNEL);
200 if (!composite) 228 if (!composite)
@@ -204,12 +232,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
204 init.flags = flags | CLK_IS_BASIC; 232 init.flags = flags | CLK_IS_BASIC;
205 init.parent_names = parent_names; 233 init.parent_names = parent_names;
206 init.num_parents = num_parents; 234 init.num_parents = num_parents;
235 hw = &composite->hw;
207 236
208 clk_composite_ops = &composite->ops; 237 clk_composite_ops = &composite->ops;
209 238
210 if (mux_hw && mux_ops) { 239 if (mux_hw && mux_ops) {
211 if (!mux_ops->get_parent) { 240 if (!mux_ops->get_parent) {
212 clk = ERR_PTR(-EINVAL); 241 hw = ERR_PTR(-EINVAL);
213 goto err; 242 goto err;
214 } 243 }
215 244
@@ -224,7 +253,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
224 253
225 if (rate_hw && rate_ops) { 254 if (rate_hw && rate_ops) {
226 if (!rate_ops->recalc_rate) { 255 if (!rate_ops->recalc_rate) {
227 clk = ERR_PTR(-EINVAL); 256 hw = ERR_PTR(-EINVAL);
228 goto err; 257 goto err;
229 } 258 }
230 clk_composite_ops->recalc_rate = clk_composite_recalc_rate; 259 clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
@@ -250,10 +279,16 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
250 composite->rate_ops = rate_ops; 279 composite->rate_ops = rate_ops;
251 } 280 }
252 281
282 if (mux_hw && mux_ops && rate_hw && rate_ops) {
283 if (mux_ops->set_parent && rate_ops->set_rate)
284 clk_composite_ops->set_rate_and_parent =
285 clk_composite_set_rate_and_parent;
286 }
287
253 if (gate_hw && gate_ops) { 288 if (gate_hw && gate_ops) {
254 if (!gate_ops->is_enabled || !gate_ops->enable || 289 if (!gate_ops->is_enabled || !gate_ops->enable ||
255 !gate_ops->disable) { 290 !gate_ops->disable) {
256 clk = ERR_PTR(-EINVAL); 291 hw = ERR_PTR(-EINVAL);
257 goto err; 292 goto err;
258 } 293 }
259 294
@@ -267,22 +302,56 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
267 init.ops = clk_composite_ops; 302 init.ops = clk_composite_ops;
268 composite->hw.init = &init; 303 composite->hw.init = &init;
269 304
270 clk = clk_register(dev, &composite->hw); 305 ret = clk_hw_register(dev, hw);
271 if (IS_ERR(clk)) 306 if (ret) {
307 hw = ERR_PTR(ret);
272 goto err; 308 goto err;
309 }
273 310
274 if (composite->mux_hw) 311 if (composite->mux_hw)
275 composite->mux_hw->clk = clk; 312 composite->mux_hw->clk = hw->clk;
276 313
277 if (composite->rate_hw) 314 if (composite->rate_hw)
278 composite->rate_hw->clk = clk; 315 composite->rate_hw->clk = hw->clk;
279 316
280 if (composite->gate_hw) 317 if (composite->gate_hw)
281 composite->gate_hw->clk = clk; 318 composite->gate_hw->clk = hw->clk;
282 319
283 return clk; 320 return hw;
284 321
285err: 322err:
286 kfree(composite); 323 kfree(composite);
287 return clk; 324 return hw;
325}
326
327struct clk *clk_register_composite(struct device *dev, const char *name,
328 const char * const *parent_names, int num_parents,
329 struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
330 struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
331 struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
332 unsigned long flags)
333{
334 struct clk_hw *hw;
335
336 hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
337 mux_hw, mux_ops, rate_hw, rate_ops, gate_hw, gate_ops,
338 flags);
339 if (IS_ERR(hw))
340 return ERR_CAST(hw);
341 return hw->clk;
342}
343
344void clk_unregister_composite(struct clk *clk)
345{
346 struct clk_composite *composite;
347 struct clk_hw *hw;
348
349 hw = __clk_get_hw(clk);
350 if (!hw)
351 return;
352
353 composite = to_clk_composite(hw);
354
355 clk_unregister(clk);
356 kfree(composite);
288} 357}
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 00e035b51c69..a0f55bc1ad3d 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -426,15 +426,16 @@ const struct clk_ops clk_divider_ro_ops = {
426}; 426};
427EXPORT_SYMBOL_GPL(clk_divider_ro_ops); 427EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
428 428
429static struct clk *_register_divider(struct device *dev, const char *name, 429static struct clk_hw *_register_divider(struct device *dev, const char *name,
430 const char *parent_name, unsigned long flags, 430 const char *parent_name, unsigned long flags,
431 void __iomem *reg, u8 shift, u8 width, 431 void __iomem *reg, u8 shift, u8 width,
432 u8 clk_divider_flags, const struct clk_div_table *table, 432 u8 clk_divider_flags, const struct clk_div_table *table,
433 spinlock_t *lock) 433 spinlock_t *lock)
434{ 434{
435 struct clk_divider *div; 435 struct clk_divider *div;
436 struct clk *clk; 436 struct clk_hw *hw;
437 struct clk_init_data init; 437 struct clk_init_data init;
438 int ret;
438 439
439 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { 440 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
440 if (width + shift > 16) { 441 if (width + shift > 16) {
@@ -467,12 +468,14 @@ static struct clk *_register_divider(struct device *dev, const char *name,
467 div->table = table; 468 div->table = table;
468 469
469 /* register the clock */ 470 /* register the clock */
470 clk = clk_register(dev, &div->hw); 471 hw = &div->hw;
471 472 ret = clk_hw_register(dev, hw);
472 if (IS_ERR(clk)) 473 if (ret) {
473 kfree(div); 474 kfree(div);
475 hw = ERR_PTR(ret);
476 }
474 477
475 return clk; 478 return hw;
476} 479}
477 480
478/** 481/**
@@ -492,12 +495,39 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
492 void __iomem *reg, u8 shift, u8 width, 495 void __iomem *reg, u8 shift, u8 width,
493 u8 clk_divider_flags, spinlock_t *lock) 496 u8 clk_divider_flags, spinlock_t *lock)
494{ 497{
495 return _register_divider(dev, name, parent_name, flags, reg, shift, 498 struct clk_hw *hw;
499
500 hw = _register_divider(dev, name, parent_name, flags, reg, shift,
496 width, clk_divider_flags, NULL, lock); 501 width, clk_divider_flags, NULL, lock);
502 if (IS_ERR(hw))
503 return ERR_CAST(hw);
504 return hw->clk;
497} 505}
498EXPORT_SYMBOL_GPL(clk_register_divider); 506EXPORT_SYMBOL_GPL(clk_register_divider);
499 507
500/** 508/**
509 * clk_hw_register_divider - register a divider clock with the clock framework
510 * @dev: device registering this clock
511 * @name: name of this clock
512 * @parent_name: name of clock's parent
513 * @flags: framework-specific flags
514 * @reg: register address to adjust divider
515 * @shift: number of bits to shift the bitfield
516 * @width: width of the bitfield
517 * @clk_divider_flags: divider-specific flags for this clock
518 * @lock: shared register lock for this clock
519 */
520struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
521 const char *parent_name, unsigned long flags,
522 void __iomem *reg, u8 shift, u8 width,
523 u8 clk_divider_flags, spinlock_t *lock)
524{
525 return _register_divider(dev, name, parent_name, flags, reg, shift,
526 width, clk_divider_flags, NULL, lock);
527}
528EXPORT_SYMBOL_GPL(clk_hw_register_divider);
529
530/**
501 * clk_register_divider_table - register a table based divider clock with 531 * clk_register_divider_table - register a table based divider clock with
502 * the clock framework 532 * the clock framework
503 * @dev: device registering this clock 533 * @dev: device registering this clock
@@ -517,11 +547,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
517 u8 clk_divider_flags, const struct clk_div_table *table, 547 u8 clk_divider_flags, const struct clk_div_table *table,
518 spinlock_t *lock) 548 spinlock_t *lock)
519{ 549{
520 return _register_divider(dev, name, parent_name, flags, reg, shift, 550 struct clk_hw *hw;
551
552 hw = _register_divider(dev, name, parent_name, flags, reg, shift,
521 width, clk_divider_flags, table, lock); 553 width, clk_divider_flags, table, lock);
554 if (IS_ERR(hw))
555 return ERR_CAST(hw);
556 return hw->clk;
522} 557}
523EXPORT_SYMBOL_GPL(clk_register_divider_table); 558EXPORT_SYMBOL_GPL(clk_register_divider_table);
524 559
560/**
561 * clk_hw_register_divider_table - register a table based divider clock with
562 * the clock framework
563 * @dev: device registering this clock
564 * @name: name of this clock
565 * @parent_name: name of clock's parent
566 * @flags: framework-specific flags
567 * @reg: register address to adjust divider
568 * @shift: number of bits to shift the bitfield
569 * @width: width of the bitfield
570 * @clk_divider_flags: divider-specific flags for this clock
571 * @table: array of divider/value pairs ending with a div set to 0
572 * @lock: shared register lock for this clock
573 */
574struct clk_hw *clk_hw_register_divider_table(struct device *dev,
575 const char *name, const char *parent_name, unsigned long flags,
576 void __iomem *reg, u8 shift, u8 width,
577 u8 clk_divider_flags, const struct clk_div_table *table,
578 spinlock_t *lock)
579{
580 return _register_divider(dev, name, parent_name, flags, reg, shift,
581 width, clk_divider_flags, table, lock);
582}
583EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
584
525void clk_unregister_divider(struct clk *clk) 585void clk_unregister_divider(struct clk *clk)
526{ 586{
527 struct clk_divider *div; 587 struct clk_divider *div;
@@ -537,3 +597,18 @@ void clk_unregister_divider(struct clk *clk)
537 kfree(div); 597 kfree(div);
538} 598}
539EXPORT_SYMBOL_GPL(clk_unregister_divider); 599EXPORT_SYMBOL_GPL(clk_unregister_divider);
600
601/**
602 * clk_hw_unregister_divider - unregister a clk divider
603 * @hw: hardware-specific clock data to unregister
604 */
605void clk_hw_unregister_divider(struct clk_hw *hw)
606{
607 struct clk_divider *div;
608
609 div = to_clk_divider(hw);
610
611 clk_hw_unregister(hw);
612 kfree(div);
613}
614EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 053448e2453d..75cd6c792cb8 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -68,13 +68,14 @@ const struct clk_ops clk_fixed_factor_ops = {
68}; 68};
69EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); 69EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
70 70
71struct clk *clk_register_fixed_factor(struct device *dev, const char *name, 71struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
72 const char *parent_name, unsigned long flags, 72 const char *name, const char *parent_name, unsigned long flags,
73 unsigned int mult, unsigned int div) 73 unsigned int mult, unsigned int div)
74{ 74{
75 struct clk_fixed_factor *fix; 75 struct clk_fixed_factor *fix;
76 struct clk_init_data init; 76 struct clk_init_data init;
77 struct clk *clk; 77 struct clk_hw *hw;
78 int ret;
78 79
79 fix = kmalloc(sizeof(*fix), GFP_KERNEL); 80 fix = kmalloc(sizeof(*fix), GFP_KERNEL);
80 if (!fix) 81 if (!fix)
@@ -91,12 +92,28 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
91 init.parent_names = &parent_name; 92 init.parent_names = &parent_name;
92 init.num_parents = 1; 93 init.num_parents = 1;
93 94
94 clk = clk_register(dev, &fix->hw); 95 hw = &fix->hw;
95 96 ret = clk_hw_register(dev, hw);
96 if (IS_ERR(clk)) 97 if (ret) {
97 kfree(fix); 98 kfree(fix);
99 hw = ERR_PTR(ret);
100 }
101
102 return hw;
103}
104EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
105
106struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
107 const char *parent_name, unsigned long flags,
108 unsigned int mult, unsigned int div)
109{
110 struct clk_hw *hw;
98 111
99 return clk; 112 hw = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
113 div);
114 if (IS_ERR(hw))
115 return ERR_CAST(hw);
116 return hw->clk;
100} 117}
101EXPORT_SYMBOL_GPL(clk_register_fixed_factor); 118EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
102 119
@@ -113,6 +130,17 @@ void clk_unregister_fixed_factor(struct clk *clk)
113} 130}
114EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor); 131EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor);
115 132
133void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
134{
135 struct clk_fixed_factor *fix;
136
137 fix = to_clk_fixed_factor(hw);
138
139 clk_hw_unregister(hw);
140 kfree(fix);
141}
142EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
143
116#ifdef CONFIG_OF 144#ifdef CONFIG_OF
117/** 145/**
118 * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock 146 * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index cd9dc925b3f8..8e4453eb54e8 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -45,8 +45,8 @@ const struct clk_ops clk_fixed_rate_ops = {
45EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); 45EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
46 46
47/** 47/**
48 * clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the 48 * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
49 * clock framework 49 * the clock framework
50 * @dev: device that is registering this clock 50 * @dev: device that is registering this clock
51 * @name: name of this clock 51 * @name: name of this clock
52 * @parent_name: name of clock's parent 52 * @parent_name: name of clock's parent
@@ -54,13 +54,14 @@ EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
54 * @fixed_rate: non-adjustable clock rate 54 * @fixed_rate: non-adjustable clock rate
55 * @fixed_accuracy: non-adjustable clock rate 55 * @fixed_accuracy: non-adjustable clock rate
56 */ 56 */
57struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, 57struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
58 const char *name, const char *parent_name, unsigned long flags, 58 const char *name, const char *parent_name, unsigned long flags,
59 unsigned long fixed_rate, unsigned long fixed_accuracy) 59 unsigned long fixed_rate, unsigned long fixed_accuracy)
60{ 60{
61 struct clk_fixed_rate *fixed; 61 struct clk_fixed_rate *fixed;
62 struct clk *clk; 62 struct clk_hw *hw;
63 struct clk_init_data init; 63 struct clk_init_data init;
64 int ret;
64 65
65 /* allocate fixed-rate clock */ 66 /* allocate fixed-rate clock */
66 fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); 67 fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
@@ -79,22 +80,49 @@ struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
79 fixed->hw.init = &init; 80 fixed->hw.init = &init;
80 81
81 /* register the clock */ 82 /* register the clock */
82 clk = clk_register(dev, &fixed->hw); 83 hw = &fixed->hw;
83 if (IS_ERR(clk)) 84 ret = clk_hw_register(dev, hw);
85 if (ret) {
84 kfree(fixed); 86 kfree(fixed);
87 hw = ERR_PTR(ret);
88 }
85 89
86 return clk; 90 return hw;
91}
92EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
93
94struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
95 const char *name, const char *parent_name, unsigned long flags,
96 unsigned long fixed_rate, unsigned long fixed_accuracy)
97{
98 struct clk_hw *hw;
99
100 hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
101 flags, fixed_rate, fixed_accuracy);
102 if (IS_ERR(hw))
103 return ERR_CAST(hw);
104 return hw->clk;
87} 105}
88EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy); 106EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
89 107
90/** 108/**
91 * clk_register_fixed_rate - register fixed-rate clock with the clock framework 109 * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
110 * framework
92 * @dev: device that is registering this clock 111 * @dev: device that is registering this clock
93 * @name: name of this clock 112 * @name: name of this clock
94 * @parent_name: name of clock's parent 113 * @parent_name: name of clock's parent
95 * @flags: framework-specific flags 114 * @flags: framework-specific flags
96 * @fixed_rate: non-adjustable clock rate 115 * @fixed_rate: non-adjustable clock rate
97 */ 116 */
117struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
118 const char *parent_name, unsigned long flags,
119 unsigned long fixed_rate)
120{
121 return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
122 flags, fixed_rate, 0);
123}
124EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
125
98struct clk *clk_register_fixed_rate(struct device *dev, const char *name, 126struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
99 const char *parent_name, unsigned long flags, 127 const char *parent_name, unsigned long flags,
100 unsigned long fixed_rate) 128 unsigned long fixed_rate)
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 1abcd76b4993..aab904618eb6 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -116,14 +116,15 @@ const struct clk_ops clk_fractional_divider_ops = {
116}; 116};
117EXPORT_SYMBOL_GPL(clk_fractional_divider_ops); 117EXPORT_SYMBOL_GPL(clk_fractional_divider_ops);
118 118
119struct clk *clk_register_fractional_divider(struct device *dev, 119struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
120 const char *name, const char *parent_name, unsigned long flags, 120 const char *name, const char *parent_name, unsigned long flags,
121 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, 121 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
122 u8 clk_divider_flags, spinlock_t *lock) 122 u8 clk_divider_flags, spinlock_t *lock)
123{ 123{
124 struct clk_fractional_divider *fd; 124 struct clk_fractional_divider *fd;
125 struct clk_init_data init; 125 struct clk_init_data init;
126 struct clk *clk; 126 struct clk_hw *hw;
127 int ret;
127 128
128 fd = kzalloc(sizeof(*fd), GFP_KERNEL); 129 fd = kzalloc(sizeof(*fd), GFP_KERNEL);
129 if (!fd) 130 if (!fd)
@@ -146,10 +147,39 @@ struct clk *clk_register_fractional_divider(struct device *dev,
146 fd->lock = lock; 147 fd->lock = lock;
147 fd->hw.init = &init; 148 fd->hw.init = &init;
148 149
149 clk = clk_register(dev, &fd->hw); 150 hw = &fd->hw;
150 if (IS_ERR(clk)) 151 ret = clk_hw_register(dev, hw);
152 if (ret) {
151 kfree(fd); 153 kfree(fd);
154 hw = ERR_PTR(ret);
155 }
156
157 return hw;
158}
159EXPORT_SYMBOL_GPL(clk_hw_register_fractional_divider);
152 160
153 return clk; 161struct clk *clk_register_fractional_divider(struct device *dev,
162 const char *name, const char *parent_name, unsigned long flags,
163 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
164 u8 clk_divider_flags, spinlock_t *lock)
165{
166 struct clk_hw *hw;
167
168 hw = clk_hw_register_fractional_divider(dev, name, parent_name, flags,
169 reg, mshift, mwidth, nshift, nwidth, clk_divider_flags,
170 lock);
171 if (IS_ERR(hw))
172 return ERR_CAST(hw);
173 return hw->clk;
154} 174}
155EXPORT_SYMBOL_GPL(clk_register_fractional_divider); 175EXPORT_SYMBOL_GPL(clk_register_fractional_divider);
176
177void clk_hw_unregister_fractional_divider(struct clk_hw *hw)
178{
179 struct clk_fractional_divider *fd;
180
181 fd = to_clk_fd(hw);
182
183 clk_hw_unregister(hw);
184 kfree(fd);
185}
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index d0d8ec8e1f1b..4e691e35483a 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -110,7 +110,7 @@ const struct clk_ops clk_gate_ops = {
110EXPORT_SYMBOL_GPL(clk_gate_ops); 110EXPORT_SYMBOL_GPL(clk_gate_ops);
111 111
112/** 112/**
113 * clk_register_gate - register a gate clock with the clock framework 113 * clk_hw_register_gate - register a gate clock with the clock framework
114 * @dev: device that is registering this clock 114 * @dev: device that is registering this clock
115 * @name: name of this clock 115 * @name: name of this clock
116 * @parent_name: name of this clock's parent 116 * @parent_name: name of this clock's parent
@@ -120,14 +120,15 @@ EXPORT_SYMBOL_GPL(clk_gate_ops);
120 * @clk_gate_flags: gate-specific flags for this clock 120 * @clk_gate_flags: gate-specific flags for this clock
121 * @lock: shared register lock for this clock 121 * @lock: shared register lock for this clock
122 */ 122 */
123struct clk *clk_register_gate(struct device *dev, const char *name, 123struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
124 const char *parent_name, unsigned long flags, 124 const char *parent_name, unsigned long flags,
125 void __iomem *reg, u8 bit_idx, 125 void __iomem *reg, u8 bit_idx,
126 u8 clk_gate_flags, spinlock_t *lock) 126 u8 clk_gate_flags, spinlock_t *lock)
127{ 127{
128 struct clk_gate *gate; 128 struct clk_gate *gate;
129 struct clk *clk; 129 struct clk_hw *hw;
130 struct clk_init_data init; 130 struct clk_init_data init;
131 int ret;
131 132
132 if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { 133 if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
133 if (bit_idx > 15) { 134 if (bit_idx > 15) {
@@ -154,12 +155,29 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
154 gate->lock = lock; 155 gate->lock = lock;
155 gate->hw.init = &init; 156 gate->hw.init = &init;
156 157
157 clk = clk_register(dev, &gate->hw); 158 hw = &gate->hw;
158 159 ret = clk_hw_register(dev, hw);
159 if (IS_ERR(clk)) 160 if (ret) {
160 kfree(gate); 161 kfree(gate);
162 hw = ERR_PTR(ret);
163 }
161 164
162 return clk; 165 return hw;
166}
167EXPORT_SYMBOL_GPL(clk_hw_register_gate);
168
169struct clk *clk_register_gate(struct device *dev, const char *name,
170 const char *parent_name, unsigned long flags,
171 void __iomem *reg, u8 bit_idx,
172 u8 clk_gate_flags, spinlock_t *lock)
173{
174 struct clk_hw *hw;
175
176 hw = clk_hw_register_gate(dev, name, parent_name, flags, reg,
177 bit_idx, clk_gate_flags, lock);
178 if (IS_ERR(hw))
179 return ERR_CAST(hw);
180 return hw->clk;
163} 181}
164EXPORT_SYMBOL_GPL(clk_register_gate); 182EXPORT_SYMBOL_GPL(clk_register_gate);
165 183
@@ -178,3 +196,14 @@ void clk_unregister_gate(struct clk *clk)
178 kfree(gate); 196 kfree(gate);
179} 197}
180EXPORT_SYMBOL_GPL(clk_unregister_gate); 198EXPORT_SYMBOL_GPL(clk_unregister_gate);
199
200void clk_hw_unregister_gate(struct clk_hw *hw)
201{
202 struct clk_gate *gate;
203
204 gate = to_clk_gate(hw);
205
206 clk_hw_unregister(hw);
207 kfree(gate);
208}
209EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 08f65acc5d57..86b245746a6b 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -94,13 +94,13 @@ const struct clk_ops clk_gpio_mux_ops = {
94}; 94};
95EXPORT_SYMBOL_GPL(clk_gpio_mux_ops); 95EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
96 96
97static struct clk *clk_register_gpio(struct device *dev, const char *name, 97static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
98 const char * const *parent_names, u8 num_parents, unsigned gpio, 98 const char * const *parent_names, u8 num_parents, unsigned gpio,
99 bool active_low, unsigned long flags, 99 bool active_low, unsigned long flags,
100 const struct clk_ops *clk_gpio_ops) 100 const struct clk_ops *clk_gpio_ops)
101{ 101{
102 struct clk_gpio *clk_gpio; 102 struct clk_gpio *clk_gpio;
103 struct clk *clk; 103 struct clk_hw *hw;
104 struct clk_init_data init = {}; 104 struct clk_init_data init = {};
105 unsigned long gpio_flags; 105 unsigned long gpio_flags;
106 int err; 106 int err;
@@ -141,24 +141,26 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
141 clk_gpio->gpiod = gpio_to_desc(gpio); 141 clk_gpio->gpiod = gpio_to_desc(gpio);
142 clk_gpio->hw.init = &init; 142 clk_gpio->hw.init = &init;
143 143
144 hw = &clk_gpio->hw;
144 if (dev) 145 if (dev)
145 clk = devm_clk_register(dev, &clk_gpio->hw); 146 err = devm_clk_hw_register(dev, hw);
146 else 147 else
147 clk = clk_register(NULL, &clk_gpio->hw); 148 err = clk_hw_register(NULL, hw);
148 149
149 if (!IS_ERR(clk)) 150 if (!err)
150 return clk; 151 return hw;
151 152
152 if (!dev) { 153 if (!dev) {
153 gpiod_put(clk_gpio->gpiod); 154 gpiod_put(clk_gpio->gpiod);
154 kfree(clk_gpio); 155 kfree(clk_gpio);
155 } 156 }
156 157
157 return clk; 158 return ERR_PTR(err);
158} 159}
159 160
160/** 161/**
161 * clk_register_gpio_gate - register a gpio clock gate with the clock framework 162 * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
163 * framework
162 * @dev: device that is registering this clock 164 * @dev: device that is registering this clock
163 * @name: name of this clock 165 * @name: name of this clock
164 * @parent_name: name of this clock's parent 166 * @parent_name: name of this clock's parent
@@ -166,7 +168,7 @@ static struct clk *clk_register_gpio(struct device *dev, const char *name,
166 * @active_low: true if gpio should be set to 0 to enable clock 168 * @active_low: true if gpio should be set to 0 to enable clock
167 * @flags: clock flags 169 * @flags: clock flags
168 */ 170 */
169struct clk *clk_register_gpio_gate(struct device *dev, const char *name, 171struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
170 const char *parent_name, unsigned gpio, bool active_low, 172 const char *parent_name, unsigned gpio, bool active_low,
171 unsigned long flags) 173 unsigned long flags)
172{ 174{
@@ -175,10 +177,24 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
175 (parent_name ? 1 : 0), gpio, active_low, flags, 177 (parent_name ? 1 : 0), gpio, active_low, flags,
176 &clk_gpio_gate_ops); 178 &clk_gpio_gate_ops);
177} 179}
180EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
181
182struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
183 const char *parent_name, unsigned gpio, bool active_low,
184 unsigned long flags)
185{
186 struct clk_hw *hw;
187
188 hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low,
189 flags);
190 if (IS_ERR(hw))
191 return ERR_CAST(hw);
192 return hw->clk;
193}
178EXPORT_SYMBOL_GPL(clk_register_gpio_gate); 194EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
179 195
180/** 196/**
181 * clk_register_gpio_mux - register a gpio clock mux with the clock framework 197 * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
182 * @dev: device that is registering this clock 198 * @dev: device that is registering this clock
183 * @name: name of this clock 199 * @name: name of this clock
184 * @parent_names: names of this clock's parents 200 * @parent_names: names of this clock's parents
@@ -187,7 +203,7 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
187 * @active_low: true if gpio should be set to 0 to enable clock 203 * @active_low: true if gpio should be set to 0 to enable clock
188 * @flags: clock flags 204 * @flags: clock flags
189 */ 205 */
190struct clk *clk_register_gpio_mux(struct device *dev, const char *name, 206struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
191 const char * const *parent_names, u8 num_parents, unsigned gpio, 207 const char * const *parent_names, u8 num_parents, unsigned gpio,
192 bool active_low, unsigned long flags) 208 bool active_low, unsigned long flags)
193{ 209{
@@ -199,6 +215,20 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
199 return clk_register_gpio(dev, name, parent_names, num_parents, 215 return clk_register_gpio(dev, name, parent_names, num_parents,
200 gpio, active_low, flags, &clk_gpio_mux_ops); 216 gpio, active_low, flags, &clk_gpio_mux_ops);
201} 217}
218EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
219
220struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
221 const char * const *parent_names, u8 num_parents, unsigned gpio,
222 bool active_low, unsigned long flags)
223{
224 struct clk_hw *hw;
225
226 hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
227 gpio, active_low, flags);
228 if (IS_ERR(hw))
229 return ERR_CAST(hw);
230 return hw->clk;
231}
202EXPORT_SYMBOL_GPL(clk_register_gpio_mux); 232EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
203 233
204static int gpio_clk_driver_probe(struct platform_device *pdev) 234static int gpio_clk_driver_probe(struct platform_device *pdev)
diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c
index d4c61985f448..5097831387ff 100644
--- a/drivers/clk/clk-ls1x.c
+++ b/drivers/clk/clk-ls1x.c
@@ -88,8 +88,7 @@ void __init ls1x_clk_init(void)
88{ 88{
89 struct clk *clk; 89 struct clk *clk;
90 90
91 clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, CLK_IS_ROOT, 91 clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC);
92 OSC);
93 clk_register_clkdev(clk, "osc_33m_clk", NULL); 92 clk_register_clkdev(clk, "osc_33m_clk", NULL);
94 93
95 /* clock derived from 33 MHz OSC clk */ 94 /* clock derived from 33 MHz OSC clk */
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 252188fd8bcd..16a3d5717f4e 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -113,16 +113,17 @@ const struct clk_ops clk_mux_ro_ops = {
113}; 113};
114EXPORT_SYMBOL_GPL(clk_mux_ro_ops); 114EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
115 115
116struct clk *clk_register_mux_table(struct device *dev, const char *name, 116struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
117 const char * const *parent_names, u8 num_parents, 117 const char * const *parent_names, u8 num_parents,
118 unsigned long flags, 118 unsigned long flags,
119 void __iomem *reg, u8 shift, u32 mask, 119 void __iomem *reg, u8 shift, u32 mask,
120 u8 clk_mux_flags, u32 *table, spinlock_t *lock) 120 u8 clk_mux_flags, u32 *table, spinlock_t *lock)
121{ 121{
122 struct clk_mux *mux; 122 struct clk_mux *mux;
123 struct clk *clk; 123 struct clk_hw *hw;
124 struct clk_init_data init; 124 struct clk_init_data init;
125 u8 width = 0; 125 u8 width = 0;
126 int ret;
126 127
127 if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { 128 if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
128 width = fls(mask) - ffs(mask) + 1; 129 width = fls(mask) - ffs(mask) + 1;
@@ -157,12 +158,31 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
157 mux->table = table; 158 mux->table = table;
158 mux->hw.init = &init; 159 mux->hw.init = &init;
159 160
160 clk = clk_register(dev, &mux->hw); 161 hw = &mux->hw;
161 162 ret = clk_hw_register(dev, hw);
162 if (IS_ERR(clk)) 163 if (ret) {
163 kfree(mux); 164 kfree(mux);
165 hw = ERR_PTR(ret);
166 }
164 167
165 return clk; 168 return hw;
169}
170EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
171
172struct clk *clk_register_mux_table(struct device *dev, const char *name,
173 const char * const *parent_names, u8 num_parents,
174 unsigned long flags,
175 void __iomem *reg, u8 shift, u32 mask,
176 u8 clk_mux_flags, u32 *table, spinlock_t *lock)
177{
178 struct clk_hw *hw;
179
180 hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
181 flags, reg, shift, mask, clk_mux_flags,
182 table, lock);
183 if (IS_ERR(hw))
184 return ERR_CAST(hw);
185 return hw->clk;
166} 186}
167EXPORT_SYMBOL_GPL(clk_register_mux_table); 187EXPORT_SYMBOL_GPL(clk_register_mux_table);
168 188
@@ -180,6 +200,20 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
180} 200}
181EXPORT_SYMBOL_GPL(clk_register_mux); 201EXPORT_SYMBOL_GPL(clk_register_mux);
182 202
203struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
204 const char * const *parent_names, u8 num_parents,
205 unsigned long flags,
206 void __iomem *reg, u8 shift, u8 width,
207 u8 clk_mux_flags, spinlock_t *lock)
208{
209 u32 mask = BIT(width) - 1;
210
211 return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
212 flags, reg, shift, mask, clk_mux_flags,
213 NULL, lock);
214}
215EXPORT_SYMBOL_GPL(clk_hw_register_mux);
216
183void clk_unregister_mux(struct clk *clk) 217void clk_unregister_mux(struct clk *clk)
184{ 218{
185 struct clk_mux *mux; 219 struct clk_mux *mux;
@@ -195,3 +229,14 @@ void clk_unregister_mux(struct clk *clk)
195 kfree(mux); 229 kfree(mux);
196} 230}
197EXPORT_SYMBOL_GPL(clk_unregister_mux); 231EXPORT_SYMBOL_GPL(clk_unregister_mux);
232
233void clk_hw_unregister_mux(struct clk_hw *hw)
234{
235 struct clk_mux *mux;
236
237 mux = to_clk_mux(hw);
238
239 clk_hw_unregister(hw);
240 kfree(mux);
241}
242EXPORT_SYMBOL_GPL(clk_hw_unregister_mux);
diff --git a/drivers/clk/clk-nspire.c b/drivers/clk/clk-nspire.c
index a378db7b2382..64f196a90816 100644
--- a/drivers/clk/clk-nspire.c
+++ b/drivers/clk/clk-nspire.c
@@ -125,8 +125,7 @@ static void __init nspire_clk_setup(struct device_node *node,
125 125
126 of_property_read_string(node, "clock-output-names", &clk_name); 126 of_property_read_string(node, "clock-output-names", &clk_name);
127 127
128 clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, 128 clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, info.base_clock);
129 info.base_clock);
130 if (!IS_ERR(clk)) 129 if (!IS_ERR(clk))
131 of_clk_add_provider(node, of_clk_src_simple_get, clk); 130 of_clk_add_provider(node, of_clk_src_simple_get, clk);
132 else 131 else
diff --git a/drivers/clk/clk-oxnas.c b/drivers/clk/clk-oxnas.c
new file mode 100644
index 000000000000..efba7d4dbcfc
--- /dev/null
+++ b/drivers/clk/clk-oxnas.c
@@ -0,0 +1,195 @@
1/*
2 * Copyright (C) 2010 Broadcom
3 * Copyright (C) 2012 Stephen Warren
4 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/clk-provider.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/platform_device.h>
24#include <linux/stringify.h>
25#include <linux/regmap.h>
26#include <linux/mfd/syscon.h>
27
28/* Standard regmap gate clocks */
29struct clk_oxnas {
30 struct clk_hw hw;
31 signed char bit;
32 struct regmap *regmap;
33};
34
35/* Regmap offsets */
36#define CLK_STAT_REGOFFSET 0x24
37#define CLK_SET_REGOFFSET 0x2c
38#define CLK_CLR_REGOFFSET 0x30
39
40static inline struct clk_oxnas *to_clk_oxnas(struct clk_hw *hw)
41{
42 return container_of(hw, struct clk_oxnas, hw);
43}
44
45static int oxnas_clk_is_enabled(struct clk_hw *hw)
46{
47 struct clk_oxnas *std = to_clk_oxnas(hw);
48 int ret;
49 unsigned int val;
50
51 ret = regmap_read(std->regmap, CLK_STAT_REGOFFSET, &val);
52 if (ret < 0)
53 return ret;
54
55 return val & BIT(std->bit);
56}
57
58static int oxnas_clk_enable(struct clk_hw *hw)
59{
60 struct clk_oxnas *std = to_clk_oxnas(hw);
61
62 regmap_write(std->regmap, CLK_SET_REGOFFSET, BIT(std->bit));
63
64 return 0;
65}
66
67static void oxnas_clk_disable(struct clk_hw *hw)
68{
69 struct clk_oxnas *std = to_clk_oxnas(hw);
70
71 regmap_write(std->regmap, CLK_CLR_REGOFFSET, BIT(std->bit));
72}
73
74static const struct clk_ops oxnas_clk_ops = {
75 .enable = oxnas_clk_enable,
76 .disable = oxnas_clk_disable,
77 .is_enabled = oxnas_clk_is_enabled,
78};
79
80static const char *const oxnas_clk_parents[] = {
81 "oscillator",
82};
83
84static const char *const eth_parents[] = {
85 "gmacclk",
86};
87
88#define DECLARE_STD_CLKP(__clk, __parent) \
89static const struct clk_init_data clk_##__clk##_init = { \
90 .name = __stringify(__clk), \
91 .ops = &oxnas_clk_ops, \
92 .parent_names = __parent, \
93 .num_parents = ARRAY_SIZE(__parent), \
94}
95
96#define DECLARE_STD_CLK(__clk) DECLARE_STD_CLKP(__clk, oxnas_clk_parents)
97
98/* Hardware Bit - Clock association */
99struct clk_oxnas_init_data {
100 unsigned long bit;
101 const struct clk_init_data *clk_init;
102};
103
104/* Clk init data declaration */
105DECLARE_STD_CLK(leon);
106DECLARE_STD_CLK(dma_sgdma);
107DECLARE_STD_CLK(cipher);
108DECLARE_STD_CLK(sata);
109DECLARE_STD_CLK(audio);
110DECLARE_STD_CLK(usbmph);
111DECLARE_STD_CLKP(etha, eth_parents);
112DECLARE_STD_CLK(pciea);
113DECLARE_STD_CLK(nand);
114
115/* Table index is clock indice */
116static const struct clk_oxnas_init_data clk_oxnas_init[] = {
117 [0] = {0, &clk_leon_init},
118 [1] = {1, &clk_dma_sgdma_init},
119 [2] = {2, &clk_cipher_init},
120 /* Skip & Do not touch to DDR clock */
121 [3] = {4, &clk_sata_init},
122 [4] = {5, &clk_audio_init},
123 [5] = {6, &clk_usbmph_init},
124 [6] = {7, &clk_etha_init},
125 [7] = {8, &clk_pciea_init},
126 [8] = {9, &clk_nand_init},
127};
128
129struct clk_oxnas_data {
130 struct clk_oxnas clk_oxnas[ARRAY_SIZE(clk_oxnas_init)];
131 struct clk_onecell_data onecell_data[ARRAY_SIZE(clk_oxnas_init)];
132 struct clk *clks[ARRAY_SIZE(clk_oxnas_init)];
133};
134
135static int oxnas_stdclk_probe(struct platform_device *pdev)
136{
137 struct device_node *np = pdev->dev.of_node;
138 struct clk_oxnas_data *clk_oxnas;
139 struct regmap *regmap;
140 int i;
141
142 clk_oxnas = devm_kzalloc(&pdev->dev, sizeof(*clk_oxnas), GFP_KERNEL);
143 if (!clk_oxnas)
144 return -ENOMEM;
145
146 regmap = syscon_node_to_regmap(of_get_parent(np));
147 if (!regmap) {
148 dev_err(&pdev->dev, "failed to have parent regmap\n");
149 return -EINVAL;
150 }
151
152 for (i = 0; i < ARRAY_SIZE(clk_oxnas_init); i++) {
153 struct clk_oxnas *_clk;
154
155 _clk = &clk_oxnas->clk_oxnas[i];
156 _clk->bit = clk_oxnas_init[i].bit;
157 _clk->hw.init = clk_oxnas_init[i].clk_init;
158 _clk->regmap = regmap;
159
160 clk_oxnas->clks[i] =
161 devm_clk_register(&pdev->dev, &_clk->hw);
162 if (WARN_ON(IS_ERR(clk_oxnas->clks[i])))
163 return PTR_ERR(clk_oxnas->clks[i]);
164 }
165
166 clk_oxnas->onecell_data->clks = clk_oxnas->clks;
167 clk_oxnas->onecell_data->clk_num = ARRAY_SIZE(clk_oxnas_init);
168
169 return of_clk_add_provider(np, of_clk_src_onecell_get,
170 clk_oxnas->onecell_data);
171}
172
173static int oxnas_stdclk_remove(struct platform_device *pdev)
174{
175 of_clk_del_provider(pdev->dev.of_node);
176
177 return 0;
178}
179
180static const struct of_device_id oxnas_stdclk_dt_ids[] = {
181 { .compatible = "oxsemi,ox810se-stdclk" },
182 { }
183};
184MODULE_DEVICE_TABLE(of, oxnas_stdclk_dt_ids);
185
186static struct platform_driver oxnas_stdclk_driver = {
187 .probe = oxnas_stdclk_probe,
188 .remove = oxnas_stdclk_remove,
189 .driver = {
190 .name = "oxnas-stdclk",
191 .of_match_table = oxnas_stdclk_dt_ids,
192 },
193};
194
195module_platform_driver(oxnas_stdclk_driver);
diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c
index 9c0b8e6b1ab3..8328863cb0e0 100644
--- a/drivers/clk/clk-palmas.c
+++ b/drivers/clk/clk-palmas.c
@@ -132,7 +132,7 @@ static const struct palmas_clks_of_match_data palmas_of_clk32kg = {
132 .init = { 132 .init = {
133 .name = "clk32kg", 133 .name = "clk32kg",
134 .ops = &palmas_clks_ops, 134 .ops = &palmas_clks_ops,
135 .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, 135 .flags = CLK_IGNORE_UNUSED,
136 }, 136 },
137 .desc = { 137 .desc = {
138 .clk_name = "clk32kg", 138 .clk_name = "clk32kg",
@@ -148,7 +148,7 @@ static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
148 .init = { 148 .init = {
149 .name = "clk32kgaudio", 149 .name = "clk32kgaudio",
150 .ops = &palmas_clks_ops, 150 .ops = &palmas_clks_ops,
151 .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, 151 .flags = CLK_IGNORE_UNUSED,
152 }, 152 },
153 .desc = { 153 .desc = {
154 .clk_name = "clk32kgaudio", 154 .clk_name = "clk32kgaudio",
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 7bc1c4527ae4..58566a17944a 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -869,14 +869,15 @@ static void __init core_mux_init(struct device_node *np)
869 } 869 }
870} 870}
871 871
872static struct clk *sysclk_from_fixed(struct device_node *node, const char *name) 872static struct clk __init
873*sysclk_from_fixed(struct device_node *node, const char *name)
873{ 874{
874 u32 rate; 875 u32 rate;
875 876
876 if (of_property_read_u32(node, "clock-frequency", &rate)) 877 if (of_property_read_u32(node, "clock-frequency", &rate))
877 return ERR_PTR(-ENODEV); 878 return ERR_PTR(-ENODEV);
878 879
879 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); 880 return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
880} 881}
881 882
882static struct clk *sysclk_from_parent(const char *name) 883static struct clk *sysclk_from_parent(const char *name)
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index 0fee2f4ca258..74383039761e 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -106,7 +106,6 @@ static int rk808_clkout_probe(struct platform_device *pdev)
106 if (!clk_table) 106 if (!clk_table)
107 return -ENOMEM; 107 return -ENOMEM;
108 108
109 init.flags = CLK_IS_ROOT;
110 init.parent_names = NULL; 109 init.parent_names = NULL;
111 init.num_parents = 0; 110 init.num_parents = 0;
112 init.name = "rk808-clkout1"; 111 init.name = "rk808-clkout1";
diff --git a/drivers/clk/clk-tango4.c b/drivers/clk/clk-tango4.c
index 004ab7dfcfe3..eef75e305a59 100644
--- a/drivers/clk/clk-tango4.c
+++ b/drivers/clk/clk-tango4.c
@@ -4,17 +4,19 @@
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/io.h> 5#include <linux/io.h>
6 6
7static struct clk *out[2]; 7#define CLK_COUNT 4 /* cpu_clk, sys_clk, usb_clk, sdio_clk */
8static struct clk_onecell_data clk_data = { out, 2 }; 8static struct clk *clks[CLK_COUNT];
9static struct clk_onecell_data clk_data = { clks, CLK_COUNT };
9 10
10#define SYSCLK_CTRL 0x20 11#define SYSCLK_DIV 0x20
11#define CPUCLK_CTRL 0x24 12#define CPUCLK_DIV 0x24
12#define LEGACY_DIV 0x3c 13#define DIV_BYPASS BIT(23)
13 14
14#define PLL_N(val) (((val) >> 0) & 0x7f) 15/*** CLKGEN_PLL ***/
15#define PLL_K(val) (((val) >> 13) & 0x7) 16#define extract_pll_n(val) ((val >> 0) & ((1u << 7) - 1))
16#define PLL_M(val) (((val) >> 16) & 0x7) 17#define extract_pll_k(val) ((val >> 13) & ((1u << 3) - 1))
17#define DIV_INDEX(val) (((val) >> 8) & 0xf) 18#define extract_pll_m(val) ((val >> 16) & ((1u << 3) - 1))
19#define extract_pll_isel(val) ((val >> 24) & ((1u << 3) - 1))
18 20
19static void __init make_pll(int idx, const char *parent, void __iomem *base) 21static void __init make_pll(int idx, const char *parent, void __iomem *base)
20{ 22{
@@ -22,40 +24,61 @@ static void __init make_pll(int idx, const char *parent, void __iomem *base)
22 u32 val, mul, div; 24 u32 val, mul, div;
23 25
24 sprintf(name, "pll%d", idx); 26 sprintf(name, "pll%d", idx);
25 val = readl_relaxed(base + idx*8); 27 val = readl(base + idx * 8);
26 mul = PLL_N(val) + 1; 28 mul = extract_pll_n(val) + 1;
27 div = (PLL_M(val) + 1) << PLL_K(val); 29 div = (extract_pll_m(val) + 1) << extract_pll_k(val);
28 clk_register_fixed_factor(NULL, name, parent, 0, mul, div); 30 clk_register_fixed_factor(NULL, name, parent, 0, mul, div);
31 if (extract_pll_isel(val) != 1)
32 panic("%s: input not set to XTAL_IN\n", name);
29} 33}
30 34
31static int __init get_div(void __iomem *base) 35static void __init make_cd(int idx, void __iomem *base)
32{ 36{
33 u8 sysclk_tab[16] = { 2, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; 37 char name[8];
34 int idx = DIV_INDEX(readl_relaxed(base + LEGACY_DIV)); 38 u32 val, mul, div;
35 39
36 return sysclk_tab[idx]; 40 sprintf(name, "cd%d", idx);
41 val = readl(base + idx * 8);
42 mul = 1 << 27;
43 div = (2 << 27) + val;
44 clk_register_fixed_factor(NULL, name, "pll2", 0, mul, div);
45 if (val > 0xf0000000)
46 panic("%s: unsupported divider %x\n", name, val);
37} 47}
38 48
39static void __init tango4_clkgen_setup(struct device_node *np) 49static void __init tango4_clkgen_setup(struct device_node *np)
40{ 50{
41 int div, ret; 51 struct clk **pp = clk_data.clks;
42 void __iomem *base = of_iomap(np, 0); 52 void __iomem *base = of_iomap(np, 0);
43 const char *parent = of_clk_get_parent_name(np, 0); 53 const char *parent = of_clk_get_parent_name(np, 0);
44 54
45 if (!base) 55 if (!base)
46 panic("%s: invalid address\n", np->full_name); 56 panic("%s: invalid address\n", np->name);
57
58 if (readl(base + CPUCLK_DIV) & DIV_BYPASS)
59 panic("%s: unsupported cpuclk setup\n", np->name);
60
61 if (readl(base + SYSCLK_DIV) & DIV_BYPASS)
62 panic("%s: unsupported sysclk setup\n", np->name);
63
64 writel(0x100, base + CPUCLK_DIV); /* disable frequency ramping */
47 65
48 make_pll(0, parent, base); 66 make_pll(0, parent, base);
49 make_pll(1, parent, base); 67 make_pll(1, parent, base);
68 make_pll(2, parent, base);
69 make_cd(2, base + 0x80);
70 make_cd(6, base + 0x80);
50 71
51 out[0] = clk_register_divider(NULL, "cpuclk", "pll0", 0, 72 pp[0] = clk_register_divider(NULL, "cpu_clk", "pll0", 0,
52 base + CPUCLK_CTRL, 8, 8, CLK_DIVIDER_ONE_BASED, NULL); 73 base + CPUCLK_DIV, 8, 8, CLK_DIVIDER_ONE_BASED, NULL);
74 pp[1] = clk_register_fixed_factor(NULL, "sys_clk", "pll1", 0, 1, 4);
75 pp[2] = clk_register_fixed_factor(NULL, "usb_clk", "cd2", 0, 1, 2);
76 pp[3] = clk_register_fixed_factor(NULL, "sdio_clk", "cd6", 0, 1, 2);
53 77
54 div = readl_relaxed(base + SYSCLK_CTRL) & BIT(23) ? get_div(base) : 4; 78 if (IS_ERR(pp[0]) || IS_ERR(pp[1]) || IS_ERR(pp[2]) || IS_ERR(pp[3]))
55 out[1] = clk_register_fixed_factor(NULL, "sysclk", "pll1", 0, 1, div); 79 panic("%s: clk registration failed\n", np->name);
56 80
57 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 81 if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data))
58 if (IS_ERR(out[0]) || IS_ERR(out[1]) || ret < 0) 82 panic("%s: clk provider registration failed\n", np->name);
59 panic("%s: clk registration failed\n", np->full_name);
60} 83}
61CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup); 84CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup);
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c
index 8e5ed649a098..697c66757400 100644
--- a/drivers/clk/clk-twl6040.c
+++ b/drivers/clk/clk-twl6040.c
@@ -74,7 +74,6 @@ static const struct clk_ops twl6040_mcpdm_ops = {
74static struct clk_init_data wm831x_clkout_init = { 74static struct clk_init_data wm831x_clkout_init = {
75 .name = "mcpdm_fclk", 75 .name = "mcpdm_fclk",
76 .ops = &twl6040_mcpdm_ops, 76 .ops = &twl6040_mcpdm_ops,
77 .flags = CLK_IS_ROOT,
78}; 77};
79 78
80static int twl6040_clk_probe(struct platform_device *pdev) 79static int twl6040_clk_probe(struct platform_device *pdev)
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index 43f9d15255f4..88def4b2761c 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -58,7 +58,6 @@ static const struct clk_ops wm831x_xtal_ops = {
58static struct clk_init_data wm831x_xtal_init = { 58static struct clk_init_data wm831x_xtal_init = {
59 .name = "xtal", 59 .name = "xtal",
60 .ops = &wm831x_xtal_ops, 60 .ops = &wm831x_xtal_ops,
61 .flags = CLK_IS_ROOT,
62}; 61};
63 62
64static const unsigned long wm831x_fll_auto_rates[] = { 63static const unsigned long wm831x_fll_auto_rates[] = {
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index d73450b60b28..343313250c58 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -198,7 +198,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
198 of_property_read_string(np, "clock-output-names", &clk_name); 198 of_property_read_string(np, "clock-output-names", &clk_name);
199 clk = xgene_register_clk_pll(NULL, 199 clk = xgene_register_clk_pll(NULL,
200 clk_name, of_clk_get_parent_name(np, 0), 200 clk_name, of_clk_get_parent_name(np, 0),
201 CLK_IS_ROOT, reg, 0, pll_type, &clk_lock, 201 0, reg, 0, pll_type, &clk_lock,
202 version); 202 version);
203 if (!IS_ERR(clk)) { 203 if (!IS_ERR(clk)) {
204 of_clk_add_provider(np, of_clk_src_simple_get, clk); 204 of_clk_add_provider(np, of_clk_src_simple_get, clk);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fb74dc1f7520..d584004f7af7 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -574,6 +574,9 @@ static void clk_core_unprepare(struct clk_core *core)
574 if (WARN_ON(core->prepare_count == 0)) 574 if (WARN_ON(core->prepare_count == 0))
575 return; 575 return;
576 576
577 if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL))
578 return;
579
577 if (--core->prepare_count > 0) 580 if (--core->prepare_count > 0)
578 return; 581 return;
579 582
@@ -679,6 +682,9 @@ static void clk_core_disable(struct clk_core *core)
679 if (WARN_ON(core->enable_count == 0)) 682 if (WARN_ON(core->enable_count == 0))
680 return; 683 return;
681 684
685 if (WARN_ON(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL))
686 return;
687
682 if (--core->enable_count > 0) 688 if (--core->enable_count > 0)
683 return; 689 return;
684 690
@@ -2397,6 +2403,16 @@ static int __clk_core_init(struct clk_core *core)
2397 if (core->ops->init) 2403 if (core->ops->init)
2398 core->ops->init(core->hw); 2404 core->ops->init(core->hw);
2399 2405
2406 if (core->flags & CLK_IS_CRITICAL) {
2407 unsigned long flags;
2408
2409 clk_core_prepare(core);
2410
2411 flags = clk_enable_lock();
2412 clk_core_enable(core);
2413 clk_enable_unlock(flags);
2414 }
2415
2400 kref_init(&core->ref); 2416 kref_init(&core->ref);
2401out: 2417out:
2402 clk_prepare_unlock(); 2418 clk_prepare_unlock();
@@ -2536,6 +2552,22 @@ fail_out:
2536} 2552}
2537EXPORT_SYMBOL_GPL(clk_register); 2553EXPORT_SYMBOL_GPL(clk_register);
2538 2554
2555/**
2556 * clk_hw_register - register a clk_hw and return an error code
2557 * @dev: device that is registering this clock
2558 * @hw: link to hardware-specific clock data
2559 *
2560 * clk_hw_register is the primary interface for populating the clock tree with
2561 * new clock nodes. It returns an integer equal to zero indicating success or
2562 * less than zero indicating failure. Drivers must test for an error code after
2563 * calling clk_hw_register().
2564 */
2565int clk_hw_register(struct device *dev, struct clk_hw *hw)
2566{
2567 return PTR_ERR_OR_ZERO(clk_register(dev, hw));
2568}
2569EXPORT_SYMBOL_GPL(clk_hw_register);
2570
2539/* Free memory allocated for a clock. */ 2571/* Free memory allocated for a clock. */
2540static void __clk_release(struct kref *ref) 2572static void __clk_release(struct kref *ref)
2541{ 2573{
@@ -2637,11 +2669,26 @@ unlock:
2637} 2669}
2638EXPORT_SYMBOL_GPL(clk_unregister); 2670EXPORT_SYMBOL_GPL(clk_unregister);
2639 2671
2672/**
2673 * clk_hw_unregister - unregister a currently registered clk_hw
2674 * @hw: hardware-specific clock data to unregister
2675 */
2676void clk_hw_unregister(struct clk_hw *hw)
2677{
2678 clk_unregister(hw->clk);
2679}
2680EXPORT_SYMBOL_GPL(clk_hw_unregister);
2681
2640static void devm_clk_release(struct device *dev, void *res) 2682static void devm_clk_release(struct device *dev, void *res)
2641{ 2683{
2642 clk_unregister(*(struct clk **)res); 2684 clk_unregister(*(struct clk **)res);
2643} 2685}
2644 2686
2687static void devm_clk_hw_release(struct device *dev, void *res)
2688{
2689 clk_hw_unregister(*(struct clk_hw **)res);
2690}
2691
2645/** 2692/**
2646 * devm_clk_register - resource managed clk_register() 2693 * devm_clk_register - resource managed clk_register()
2647 * @dev: device that is registering this clock 2694 * @dev: device that is registering this clock
@@ -2672,6 +2719,36 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
2672} 2719}
2673EXPORT_SYMBOL_GPL(devm_clk_register); 2720EXPORT_SYMBOL_GPL(devm_clk_register);
2674 2721
2722/**
2723 * devm_clk_hw_register - resource managed clk_hw_register()
2724 * @dev: device that is registering this clock
2725 * @hw: link to hardware-specific clock data
2726 *
2727 * Managed clk_hw_register(). Clocks registered by this function are
2728 * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
2729 * for more information.
2730 */
2731int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
2732{
2733 struct clk_hw **hwp;
2734 int ret;
2735
2736 hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
2737 if (!hwp)
2738 return -ENOMEM;
2739
2740 ret = clk_hw_register(dev, hw);
2741 if (!ret) {
2742 *hwp = hw;
2743 devres_add(dev, hwp);
2744 } else {
2745 devres_free(hwp);
2746 }
2747
2748 return ret;
2749}
2750EXPORT_SYMBOL_GPL(devm_clk_hw_register);
2751
2675static int devm_clk_match(struct device *dev, void *res, void *data) 2752static int devm_clk_match(struct device *dev, void *res, void *data)
2676{ 2753{
2677 struct clk *c = res; 2754 struct clk *c = res;
@@ -2680,6 +2757,15 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
2680 return c == data; 2757 return c == data;
2681} 2758}
2682 2759
2760static int devm_clk_hw_match(struct device *dev, void *res, void *data)
2761{
2762 struct clk_hw *hw = res;
2763
2764 if (WARN_ON(!hw))
2765 return 0;
2766 return hw == data;
2767}
2768
2683/** 2769/**
2684 * devm_clk_unregister - resource managed clk_unregister() 2770 * devm_clk_unregister - resource managed clk_unregister()
2685 * @clk: clock to unregister 2771 * @clk: clock to unregister
@@ -2694,6 +2780,22 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
2694} 2780}
2695EXPORT_SYMBOL_GPL(devm_clk_unregister); 2781EXPORT_SYMBOL_GPL(devm_clk_unregister);
2696 2782
2783/**
2784 * devm_clk_hw_unregister - resource managed clk_hw_unregister()
2785 * @dev: device that is unregistering the hardware-specific clock data
2786 * @hw: link to hardware-specific clock data
2787 *
2788 * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
2789 * this function will not need to be called and the resource management
2790 * code will ensure that the resource is freed.
2791 */
2792void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
2793{
2794 WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
2795 hw));
2796}
2797EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
2798
2697/* 2799/*
2698 * clkdev helpers 2800 * clkdev helpers
2699 */ 2801 */
@@ -2855,6 +2957,7 @@ struct of_clk_provider {
2855 2957
2856 struct device_node *node; 2958 struct device_node *node;
2857 struct clk *(*get)(struct of_phandle_args *clkspec, void *data); 2959 struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
2960 struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
2858 void *data; 2961 void *data;
2859}; 2962};
2860 2963
@@ -2871,6 +2974,12 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
2871} 2974}
2872EXPORT_SYMBOL_GPL(of_clk_src_simple_get); 2975EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
2873 2976
2977struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
2978{
2979 return data;
2980}
2981EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
2982
2874struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) 2983struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
2875{ 2984{
2876 struct clk_onecell_data *clk_data = data; 2985 struct clk_onecell_data *clk_data = data;
@@ -2885,6 +2994,21 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
2885} 2994}
2886EXPORT_SYMBOL_GPL(of_clk_src_onecell_get); 2995EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
2887 2996
2997struct clk_hw *
2998of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
2999{
3000 struct clk_hw_onecell_data *hw_data = data;
3001 unsigned int idx = clkspec->args[0];
3002
3003 if (idx >= hw_data->num) {
3004 pr_err("%s: invalid index %u\n", __func__, idx);
3005 return ERR_PTR(-EINVAL);
3006 }
3007
3008 return hw_data->hws[idx];
3009}
3010EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
3011
2888/** 3012/**
2889 * of_clk_add_provider() - Register a clock provider for a node 3013 * of_clk_add_provider() - Register a clock provider for a node
2890 * @np: Device node pointer associated with clock provider 3014 * @np: Device node pointer associated with clock provider
@@ -2921,6 +3045,41 @@ int of_clk_add_provider(struct device_node *np,
2921EXPORT_SYMBOL_GPL(of_clk_add_provider); 3045EXPORT_SYMBOL_GPL(of_clk_add_provider);
2922 3046
2923/** 3047/**
3048 * of_clk_add_hw_provider() - Register a clock provider for a node
3049 * @np: Device node pointer associated with clock provider
3050 * @get: callback for decoding clk_hw
3051 * @data: context pointer for @get callback.
3052 */
3053int of_clk_add_hw_provider(struct device_node *np,
3054 struct clk_hw *(*get)(struct of_phandle_args *clkspec,
3055 void *data),
3056 void *data)
3057{
3058 struct of_clk_provider *cp;
3059 int ret;
3060
3061 cp = kzalloc(sizeof(*cp), GFP_KERNEL);
3062 if (!cp)
3063 return -ENOMEM;
3064
3065 cp->node = of_node_get(np);
3066 cp->data = data;
3067 cp->get_hw = get;
3068
3069 mutex_lock(&of_clk_mutex);
3070 list_add(&cp->link, &of_clk_providers);
3071 mutex_unlock(&of_clk_mutex);
3072 pr_debug("Added clk_hw provider from %s\n", np->full_name);
3073
3074 ret = of_clk_set_defaults(np, true);
3075 if (ret < 0)
3076 of_clk_del_provider(np);
3077
3078 return ret;
3079}
3080EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
3081
3082/**
2924 * of_clk_del_provider() - Remove a previously registered clock provider 3083 * of_clk_del_provider() - Remove a previously registered clock provider
2925 * @np: Device node pointer associated with clock provider 3084 * @np: Device node pointer associated with clock provider
2926 */ 3085 */
@@ -2941,11 +3100,32 @@ void of_clk_del_provider(struct device_node *np)
2941} 3100}
2942EXPORT_SYMBOL_GPL(of_clk_del_provider); 3101EXPORT_SYMBOL_GPL(of_clk_del_provider);
2943 3102
3103static struct clk_hw *
3104__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
3105 struct of_phandle_args *clkspec)
3106{
3107 struct clk *clk;
3108 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
3109
3110 if (provider->get_hw) {
3111 hw = provider->get_hw(clkspec, provider->data);
3112 } else if (provider->get) {
3113 clk = provider->get(clkspec, provider->data);
3114 if (!IS_ERR(clk))
3115 hw = __clk_get_hw(clk);
3116 else
3117 hw = ERR_CAST(clk);
3118 }
3119
3120 return hw;
3121}
3122
2944struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 3123struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
2945 const char *dev_id, const char *con_id) 3124 const char *dev_id, const char *con_id)
2946{ 3125{
2947 struct of_clk_provider *provider; 3126 struct of_clk_provider *provider;
2948 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 3127 struct clk *clk = ERR_PTR(-EPROBE_DEFER);
3128 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
2949 3129
2950 if (!clkspec) 3130 if (!clkspec)
2951 return ERR_PTR(-EINVAL); 3131 return ERR_PTR(-EINVAL);
@@ -2954,10 +3134,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
2954 mutex_lock(&of_clk_mutex); 3134 mutex_lock(&of_clk_mutex);
2955 list_for_each_entry(provider, &of_clk_providers, link) { 3135 list_for_each_entry(provider, &of_clk_providers, link) {
2956 if (provider->node == clkspec->np) 3136 if (provider->node == clkspec->np)
2957 clk = provider->get(clkspec, provider->data); 3137 hw = __of_clk_get_hw_from_provider(provider, clkspec);
2958 if (!IS_ERR(clk)) { 3138 if (!IS_ERR(hw)) {
2959 clk = __clk_create_clk(__clk_get_hw(clk), dev_id, 3139 clk = __clk_create_clk(hw, dev_id, con_id);
2960 con_id);
2961 3140
2962 if (!IS_ERR(clk) && !__clk_get(clk)) { 3141 if (!IS_ERR(clk) && !__clk_get(clk)) {
2963 __clk_free_clk(clk); 3142 __clk_free_clk(clk);
@@ -3127,6 +3306,41 @@ static int parent_ready(struct device_node *np)
3127} 3306}
3128 3307
3129/** 3308/**
3309 * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
3310 * @np: Device node pointer associated with clock provider
3311 * @index: clock index
3312 * @flags: pointer to clk_core->flags
3313 *
3314 * Detects if the clock-critical property exists and, if so, sets the
3315 * corresponding CLK_IS_CRITICAL flag.
3316 *
3317 * Do not use this function. It exists only for legacy Device Tree
3318 * bindings, such as the one-clock-per-node style that are outdated.
3319 * Those bindings typically put all clock data into .dts and the Linux
3320 * driver has no clock data, thus making it impossible to set this flag
3321 * correctly from the driver. Only those drivers may call
3322 * of_clk_detect_critical from their setup functions.
3323 *
3324 * Return: error code or zero on success
3325 */
3326int of_clk_detect_critical(struct device_node *np,
3327 int index, unsigned long *flags)
3328{
3329 struct property *prop;
3330 const __be32 *cur;
3331 uint32_t idx;
3332
3333 if (!np || !flags)
3334 return -EINVAL;
3335
3336 of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
3337 if (index == idx)
3338 *flags |= CLK_IS_CRITICAL;
3339
3340 return 0;
3341}
3342
3343/**
3130 * of_clk_init() - Scan and init clock providers from the DT 3344 * of_clk_init() - Scan and init clock providers from the DT
3131 * @matches: array of compatible values and init functions for providers. 3345 * @matches: array of compatible values and init functions for providers.
3132 * 3346 *
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index eb20b941154b..89cc700fbc37 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -301,6 +301,20 @@ clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
301} 301}
302EXPORT_SYMBOL(clkdev_alloc); 302EXPORT_SYMBOL(clkdev_alloc);
303 303
304struct clk_lookup *
305clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
306{
307 struct clk_lookup *cl;
308 va_list ap;
309
310 va_start(ap, dev_fmt);
311 cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
312 va_end(ap);
313
314 return cl;
315}
316EXPORT_SYMBOL(clkdev_hw_alloc);
317
304/** 318/**
305 * clkdev_create - allocate and add a clkdev lookup structure 319 * clkdev_create - allocate and add a clkdev lookup structure
306 * @clk: struct clk to associate with all clk_lookups 320 * @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,
324} 338}
325EXPORT_SYMBOL_GPL(clkdev_create); 339EXPORT_SYMBOL_GPL(clkdev_create);
326 340
341/**
342 * clkdev_hw_create - allocate and add a clkdev lookup structure
343 * @hw: struct clk_hw to associate with all clk_lookups
344 * @con_id: connection ID string on device
345 * @dev_fmt: format string describing device name
346 *
347 * Returns a clk_lookup structure, which can be later unregistered and
348 * freed.
349 */
350struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
351 const char *dev_fmt, ...)
352{
353 struct clk_lookup *cl;
354 va_list ap;
355
356 va_start(ap, dev_fmt);
357 cl = vclkdev_create(hw, con_id, dev_fmt, ap);
358 va_end(ap);
359
360 return cl;
361}
362EXPORT_SYMBOL_GPL(clkdev_hw_create);
363
327int clk_add_alias(const char *alias, const char *alias_dev_name, 364int clk_add_alias(const char *alias, const char *alias_dev_name,
328 const char *con_id, struct device *dev) 365 const char *con_id, struct device *dev)
329{ 366{
@@ -404,28 +441,28 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
404EXPORT_SYMBOL(clk_register_clkdev); 441EXPORT_SYMBOL(clk_register_clkdev);
405 442
406/** 443/**
407 * clk_register_clkdevs - register a set of clk_lookup for a struct clk 444 * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
408 * @clk: struct clk to associate with all clk_lookups 445 * @hw: struct clk_hw to associate with all clk_lookups
409 * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized 446 * @con_id: connection ID string on device
410 * @num: number of clk_lookup structures to register 447 * @dev_id: format string describing device name
411 * 448 *
412 * To make things easier for mass registration, we detect error clks 449 * con_id or dev_id may be NULL as a wildcard, just as in the rest of
413 * from a previous clk_register() call, and return the error code for 450 * clkdev.
414 * those. This is to permit this function to be called immediately
415 * after clk_register().
416 */ 451 */
417int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) 452int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
453 const char *dev_id)
418{ 454{
419 unsigned i; 455 struct clk_lookup *cl;
420
421 if (IS_ERR(clk))
422 return PTR_ERR(clk);
423 456
424 for (i = 0; i < num; i++, cl++) { 457 /*
425 cl->clk_hw = __clk_get_hw(clk); 458 * Since dev_id can be NULL, and NULL is handled specially, we must
426 __clkdev_add(cl); 459 * pass it as either a NULL format string, or with "%s".
427 } 460 */
461 if (dev_id)
462 cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
463 else
464 cl = __clk_register_clkdev(hw, con_id, NULL);
428 465
429 return 0; 466 return cl ? 0 : -ENOMEM;
430} 467}
431EXPORT_SYMBOL(clk_register_clkdevs); 468EXPORT_SYMBOL(clk_hw_register_clkdev);
diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index e43485448612..3f537a04c6a6 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -1,3 +1,11 @@
1config COMMON_CLK_HI3519
2 tristate "Hi3519 Clock Driver"
3 depends on ARCH_HISI || COMPILE_TEST
4 select RESET_HISI
5 default ARCH_HISI
6 help
7 Build the clock driver for hi3519.
8
1config COMMON_CLK_HI6220 9config COMMON_CLK_HI6220
2 bool "Hi6220 Clock Driver" 10 bool "Hi6220 Clock Driver"
3 depends on ARCH_HISI || COMPILE_TEST 11 depends on ARCH_HISI || COMPILE_TEST
@@ -5,6 +13,13 @@ config COMMON_CLK_HI6220
5 help 13 help
6 Build the Hisilicon Hi6220 clock driver based on the common clock framework. 14 Build the Hisilicon Hi6220 clock driver based on the common clock framework.
7 15
16config RESET_HISI
17 bool "HiSilicon Reset Controller Driver"
18 depends on ARCH_HISI || COMPILE_TEST
19 select RESET_CONTROLLER
20 help
21 Build reset controller driver for HiSilicon device chipsets.
22
8config STUB_CLK_HI6220 23config STUB_CLK_HI6220
9 bool "Hi6220 Stub Clock Driver" 24 bool "Hi6220 Stub Clock Driver"
10 depends on COMMON_CLK_HI6220 && MAILBOX 25 depends on COMMON_CLK_HI6220 && MAILBOX
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 74dba31590f9..e169ec7da023 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -7,5 +7,7 @@ obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o
7obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o 7obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o
8obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o 8obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o
9obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o 9obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o
10obj-$(CONFIG_COMMON_CLK_HI3519) += clk-hi3519.o
10obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o 11obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o
12obj-$(CONFIG_RESET_HISI) += reset.o
11obj-$(CONFIG_STUB_CLK_HI6220) += clk-hi6220-stub.o 13obj-$(CONFIG_STUB_CLK_HI6220) += clk-hi6220-stub.o
diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c
new file mode 100644
index 000000000000..715c7301a66a
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3519.c
@@ -0,0 +1,131 @@
1/*
2 * Hi3519 Clock Driver
3 *
4 * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <dt-bindings/clock/hi3519-clock.h>
21#include <linux/clk-provider.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include "clk.h"
25#include "reset.h"
26
27#define HI3519_INNER_CLK_OFFSET 64
28#define HI3519_FIXED_24M 65
29#define HI3519_FIXED_50M 66
30#define HI3519_FIXED_75M 67
31#define HI3519_FIXED_125M 68
32#define HI3519_FIXED_150M 69
33#define HI3519_FIXED_200M 70
34#define HI3519_FIXED_250M 71
35#define HI3519_FIXED_300M 72
36#define HI3519_FIXED_400M 73
37#define HI3519_FMC_MUX 74
38
39#define HI3519_NR_CLKS 128
40
41static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = {
42 { HI3519_FIXED_24M, "24m", NULL, 0, 24000000, },
43 { HI3519_FIXED_50M, "50m", NULL, 0, 50000000, },
44 { HI3519_FIXED_75M, "75m", NULL, 0, 75000000, },
45 { HI3519_FIXED_125M, "125m", NULL, 0, 125000000, },
46 { HI3519_FIXED_150M, "150m", NULL, 0, 150000000, },
47 { HI3519_FIXED_200M, "200m", NULL, 0, 200000000, },
48 { HI3519_FIXED_250M, "250m", NULL, 0, 250000000, },
49 { HI3519_FIXED_300M, "300m", NULL, 0, 300000000, },
50 { HI3519_FIXED_400M, "400m", NULL, 0, 400000000, },
51};
52
53static const char *const fmc_mux_p[] = {
54 "24m", "75m", "125m", "150m", "200m", "250m", "300m", "400m", };
55static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7};
56
57static const struct hisi_mux_clock hi3519_mux_clks[] = {
58 { HI3519_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p),
59 CLK_SET_RATE_PARENT, 0xc0, 2, 3, 0, fmc_mux_table, },
60};
61
62static const struct hisi_gate_clock hi3519_gate_clks[] = {
63 { HI3519_FMC_CLK, "clk_fmc", "fmc_mux",
64 CLK_SET_RATE_PARENT, 0xc0, 1, 0, },
65 { HI3519_UART0_CLK, "clk_uart0", "24m",
66 CLK_SET_RATE_PARENT, 0xe4, 20, 0, },
67 { HI3519_UART1_CLK, "clk_uart1", "24m",
68 CLK_SET_RATE_PARENT, 0xe4, 21, 0, },
69 { HI3519_UART2_CLK, "clk_uart2", "24m",
70 CLK_SET_RATE_PARENT, 0xe4, 22, 0, },
71 { HI3519_UART3_CLK, "clk_uart3", "24m",
72 CLK_SET_RATE_PARENT, 0xe4, 23, 0, },
73 { HI3519_UART4_CLK, "clk_uart4", "24m",
74 CLK_SET_RATE_PARENT, 0xe4, 24, 0, },
75 { HI3519_SPI0_CLK, "clk_spi0", "50m",
76 CLK_SET_RATE_PARENT, 0xe4, 16, 0, },
77 { HI3519_SPI1_CLK, "clk_spi1", "50m",
78 CLK_SET_RATE_PARENT, 0xe4, 17, 0, },
79 { HI3519_SPI2_CLK, "clk_spi2", "50m",
80 CLK_SET_RATE_PARENT, 0xe4, 18, 0, },
81};
82
83static int hi3519_clk_probe(struct platform_device *pdev)
84{
85 struct device_node *np = pdev->dev.of_node;
86 struct hisi_clock_data *clk_data;
87 struct hisi_reset_controller *rstc;
88
89 rstc = hisi_reset_init(np);
90 if (!rstc)
91 return -ENOMEM;
92
93 clk_data = hisi_clk_init(np, HI3519_NR_CLKS);
94 if (!clk_data) {
95 hisi_reset_exit(rstc);
96 return -ENODEV;
97 }
98
99 hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
100 ARRAY_SIZE(hi3519_fixed_rate_clks),
101 clk_data);
102 hisi_clk_register_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks),
103 clk_data);
104 hisi_clk_register_gate(hi3519_gate_clks,
105 ARRAY_SIZE(hi3519_gate_clks), clk_data);
106
107 return 0;
108}
109
110static const struct of_device_id hi3519_clk_match_table[] = {
111 { .compatible = "hisilicon,hi3519-crg" },
112 { }
113};
114MODULE_DEVICE_TABLE(of, hi3519_clk_match_table);
115
116static struct platform_driver hi3519_clk_driver = {
117 .probe = hi3519_clk_probe,
118 .driver = {
119 .name = "hi3519-clk",
120 .of_match_table = hi3519_clk_match_table,
121 },
122};
123
124static int __init hi3519_clk_init(void)
125{
126 return platform_driver_register(&hi3519_clk_driver);
127}
128core_initcall(hi3519_clk_init);
129
130MODULE_LICENSE("GPL v2");
131MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver");
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 9f8e76676553..9b15adbfc30c 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -37,7 +37,7 @@
37 37
38static DEFINE_SPINLOCK(hisi_clk_lock); 38static DEFINE_SPINLOCK(hisi_clk_lock);
39 39
40struct hisi_clock_data __init *hisi_clk_init(struct device_node *np, 40struct hisi_clock_data *hisi_clk_init(struct device_node *np,
41 int nr_clks) 41 int nr_clks)
42{ 42{
43 struct hisi_clock_data *clk_data; 43 struct hisi_clock_data *clk_data;
@@ -71,8 +71,9 @@ err_data:
71err: 71err:
72 return NULL; 72 return NULL;
73} 73}
74EXPORT_SYMBOL_GPL(hisi_clk_init);
74 75
75void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, 76void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
76 int nums, struct hisi_clock_data *data) 77 int nums, struct hisi_clock_data *data)
77{ 78{
78 struct clk *clk; 79 struct clk *clk;
@@ -91,8 +92,9 @@ void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
91 data->clk_data.clks[clks[i].id] = clk; 92 data->clk_data.clks[clks[i].id] = clk;
92 } 93 }
93} 94}
95EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_rate);
94 96
95void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, 97void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
96 int nums, 98 int nums,
97 struct hisi_clock_data *data) 99 struct hisi_clock_data *data)
98{ 100{
@@ -112,8 +114,9 @@ void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
112 data->clk_data.clks[clks[i].id] = clk; 114 data->clk_data.clks[clks[i].id] = clk;
113 } 115 }
114} 116}
117EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_factor);
115 118
116void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, 119void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
117 int nums, struct hisi_clock_data *data) 120 int nums, struct hisi_clock_data *data)
118{ 121{
119 struct clk *clk; 122 struct clk *clk;
@@ -141,8 +144,9 @@ void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
141 data->clk_data.clks[clks[i].id] = clk; 144 data->clk_data.clks[clks[i].id] = clk;
142 } 145 }
143} 146}
147EXPORT_SYMBOL_GPL(hisi_clk_register_mux);
144 148
145void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, 149void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
146 int nums, struct hisi_clock_data *data) 150 int nums, struct hisi_clock_data *data)
147{ 151{
148 struct clk *clk; 152 struct clk *clk;
@@ -170,8 +174,9 @@ void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
170 data->clk_data.clks[clks[i].id] = clk; 174 data->clk_data.clks[clks[i].id] = clk;
171 } 175 }
172} 176}
177EXPORT_SYMBOL_GPL(hisi_clk_register_divider);
173 178
174void __init hisi_clk_register_gate(struct hisi_gate_clock *clks, 179void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
175 int nums, struct hisi_clock_data *data) 180 int nums, struct hisi_clock_data *data)
176{ 181{
177 struct clk *clk; 182 struct clk *clk;
@@ -198,8 +203,9 @@ void __init hisi_clk_register_gate(struct hisi_gate_clock *clks,
198 data->clk_data.clks[clks[i].id] = clk; 203 data->clk_data.clks[clks[i].id] = clk;
199 } 204 }
200} 205}
206EXPORT_SYMBOL_GPL(hisi_clk_register_gate);
201 207
202void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, 208void hisi_clk_register_gate_sep(const struct hisi_gate_clock *clks,
203 int nums, struct hisi_clock_data *data) 209 int nums, struct hisi_clock_data *data)
204{ 210{
205 struct clk *clk; 211 struct clk *clk;
@@ -226,8 +232,9 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
226 data->clk_data.clks[clks[i].id] = clk; 232 data->clk_data.clks[clks[i].id] = clk;
227 } 233 }
228} 234}
235EXPORT_SYMBOL_GPL(hisi_clk_register_gate_sep);
229 236
230void __init hi6220_clk_register_divider(struct hi6220_divider_clock *clks, 237void __init hi6220_clk_register_divider(const struct hi6220_divider_clock *clks,
231 int nums, struct hisi_clock_data *data) 238 int nums, struct hisi_clock_data *data)
232{ 239{
233 struct clk *clk; 240 struct clk *clk;
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index b56fbc1c5f27..20d64afe4ad8 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -111,18 +111,18 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
111 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock); 111 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock);
112 112
113struct hisi_clock_data *hisi_clk_init(struct device_node *, int); 113struct hisi_clock_data *hisi_clk_init(struct device_node *, int);
114void hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, 114void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
115 int, struct hisi_clock_data *); 115 int, struct hisi_clock_data *);
116void hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, 116void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
117 int, struct hisi_clock_data *); 117 int, struct hisi_clock_data *);
118void hisi_clk_register_mux(struct hisi_mux_clock *, int, 118void hisi_clk_register_mux(const struct hisi_mux_clock *, int,
119 struct hisi_clock_data *); 119 struct hisi_clock_data *);
120void hisi_clk_register_divider(struct hisi_divider_clock *, 120void hisi_clk_register_divider(const struct hisi_divider_clock *,
121 int, struct hisi_clock_data *); 121 int, struct hisi_clock_data *);
122void hisi_clk_register_gate(struct hisi_gate_clock *, 122void hisi_clk_register_gate(const struct hisi_gate_clock *,
123 int, struct hisi_clock_data *); 123 int, struct hisi_clock_data *);
124void hisi_clk_register_gate_sep(struct hisi_gate_clock *, 124void hisi_clk_register_gate_sep(const struct hisi_gate_clock *,
125 int, struct hisi_clock_data *); 125 int, struct hisi_clock_data *);
126void hi6220_clk_register_divider(struct hi6220_divider_clock *, 126void hi6220_clk_register_divider(const struct hi6220_divider_clock *,
127 int, struct hisi_clock_data *); 127 int, struct hisi_clock_data *);
128#endif /* __HISI_CLK_H */ 128#endif /* __HISI_CLK_H */
diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c
new file mode 100644
index 000000000000..6aa49c2204d0
--- /dev/null
+++ b/drivers/clk/hisilicon/reset.c
@@ -0,0 +1,134 @@
1/*
2 * Hisilicon Reset Controller Driver
3 *
4 * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/io.h>
21#include <linux/of_address.h>
22#include <linux/reset-controller.h>
23#include <linux/slab.h>
24#include <linux/spinlock.h>
25#include "reset.h"
26
27#define HISI_RESET_BIT_MASK 0x1f
28#define HISI_RESET_OFFSET_SHIFT 8
29#define HISI_RESET_OFFSET_MASK 0xffff00
30
31struct hisi_reset_controller {
32 spinlock_t lock;
33 void __iomem *membase;
34 struct reset_controller_dev rcdev;
35};
36
37
38#define to_hisi_reset_controller(rcdev) \
39 container_of(rcdev, struct hisi_reset_controller, rcdev)
40
41static int hisi_reset_of_xlate(struct reset_controller_dev *rcdev,
42 const struct of_phandle_args *reset_spec)
43{
44 u32 offset;
45 u8 bit;
46
47 offset = (reset_spec->args[0] << HISI_RESET_OFFSET_SHIFT)
48 & HISI_RESET_OFFSET_MASK;
49 bit = reset_spec->args[1] & HISI_RESET_BIT_MASK;
50
51 return (offset | bit);
52}
53
54static int hisi_reset_assert(struct reset_controller_dev *rcdev,
55 unsigned long id)
56{
57 struct hisi_reset_controller *rstc = to_hisi_reset_controller(rcdev);
58 unsigned long flags;
59 u32 offset, reg;
60 u8 bit;
61
62 offset = (id & HISI_RESET_OFFSET_MASK) >> HISI_RESET_OFFSET_SHIFT;
63 bit = id & HISI_RESET_BIT_MASK;
64
65 spin_lock_irqsave(&rstc->lock, flags);
66
67 reg = readl(rstc->membase + offset);
68 writel(reg | BIT(bit), rstc->membase + offset);
69
70 spin_unlock_irqrestore(&rstc->lock, flags);
71
72 return 0;
73}
74
75static int hisi_reset_deassert(struct reset_controller_dev *rcdev,
76 unsigned long id)
77{
78 struct hisi_reset_controller *rstc = to_hisi_reset_controller(rcdev);
79 unsigned long flags;
80 u32 offset, reg;
81 u8 bit;
82
83 offset = (id & HISI_RESET_OFFSET_MASK) >> HISI_RESET_OFFSET_SHIFT;
84 bit = id & HISI_RESET_BIT_MASK;
85
86 spin_lock_irqsave(&rstc->lock, flags);
87
88 reg = readl(rstc->membase + offset);
89 writel(reg & ~BIT(bit), rstc->membase + offset);
90
91 spin_unlock_irqrestore(&rstc->lock, flags);
92
93 return 0;
94}
95
96static const struct reset_control_ops hisi_reset_ops = {
97 .assert = hisi_reset_assert,
98 .deassert = hisi_reset_deassert,
99};
100
101struct hisi_reset_controller *hisi_reset_init(struct device_node *np)
102{
103 struct hisi_reset_controller *rstc;
104
105 rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
106 if (!rstc)
107 return NULL;
108
109 rstc->membase = of_iomap(np, 0);
110 if (!rstc->membase) {
111 kfree(rstc);
112 return NULL;
113 }
114
115 spin_lock_init(&rstc->lock);
116
117 rstc->rcdev.owner = THIS_MODULE;
118 rstc->rcdev.ops = &hisi_reset_ops;
119 rstc->rcdev.of_node = np;
120 rstc->rcdev.of_reset_n_cells = 2;
121 rstc->rcdev.of_xlate = hisi_reset_of_xlate;
122 reset_controller_register(&rstc->rcdev);
123
124 return rstc;
125}
126EXPORT_SYMBOL_GPL(hisi_reset_init);
127
128void hisi_reset_exit(struct hisi_reset_controller *rstc)
129{
130 reset_controller_unregister(&rstc->rcdev);
131 iounmap(rstc->membase);
132 kfree(rstc);
133}
134EXPORT_SYMBOL_GPL(hisi_reset_exit);
diff --git a/drivers/clk/hisilicon/reset.h b/drivers/clk/hisilicon/reset.h
new file mode 100644
index 000000000000..677d773ed27c
--- /dev/null
+++ b/drivers/clk/hisilicon/reset.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2015 HiSilicon Technologies Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __HISI_RESET_H
19#define __HISI_RESET_H
20
21struct device_node;
22struct hisi_reset_controller;
23
24#ifdef CONFIG_RESET_CONTROLLER
25struct hisi_reset_controller *hisi_reset_init(struct device_node *np);
26void hisi_reset_exit(struct hisi_reset_controller *rstc);
27#else
28static inline hisi_reset_controller *hisi_reset_init(struct device_node *np)
29{
30 return 0;
31}
32static inline void hisi_reset_exit(struct hisi_reset_controller *rstc)
33{}
34#endif
35
36#endif /* __HISI_RESET_H */
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 8935bff99fe7..db44a198a0d9 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -31,6 +31,7 @@ struct clk_gate2 {
31 struct clk_hw hw; 31 struct clk_hw hw;
32 void __iomem *reg; 32 void __iomem *reg;
33 u8 bit_idx; 33 u8 bit_idx;
34 u8 cgr_val;
34 u8 flags; 35 u8 flags;
35 spinlock_t *lock; 36 spinlock_t *lock;
36 unsigned int *share_count; 37 unsigned int *share_count;
@@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
50 goto out; 51 goto out;
51 52
52 reg = readl(gate->reg); 53 reg = readl(gate->reg);
53 reg |= 3 << gate->bit_idx; 54 reg &= ~(3 << gate->bit_idx);
55 reg |= gate->cgr_val << gate->bit_idx;
54 writel(reg, gate->reg); 56 writel(reg, gate->reg);
55 57
56out: 58out:
@@ -125,7 +127,7 @@ static struct clk_ops clk_gate2_ops = {
125 127
126struct clk *clk_register_gate2(struct device *dev, const char *name, 128struct clk *clk_register_gate2(struct device *dev, const char *name,
127 const char *parent_name, unsigned long flags, 129 const char *parent_name, unsigned long flags,
128 void __iomem *reg, u8 bit_idx, 130 void __iomem *reg, u8 bit_idx, u8 cgr_val,
129 u8 clk_gate2_flags, spinlock_t *lock, 131 u8 clk_gate2_flags, spinlock_t *lock,
130 unsigned int *share_count) 132 unsigned int *share_count)
131{ 133{
@@ -140,6 +142,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
140 /* struct clk_gate2 assignments */ 142 /* struct clk_gate2 assignments */
141 gate->reg = reg; 143 gate->reg = reg;
142 gate->bit_idx = bit_idx; 144 gate->bit_idx = bit_idx;
145 gate->cgr_val = cgr_val;
143 gate->flags = clk_gate2_flags; 146 gate->flags = clk_gate2_flags;
144 gate->lock = lock; 147 gate->lock = lock;
145 gate->share_count = share_count; 148 gate->share_count = share_count;
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index a71d24cb4c06..b0978d3b83e2 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -66,7 +66,7 @@ static const char *std_sel[] = {"ppll", "arm"};
66static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"}; 66static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
67 67
68enum mx35_clks { 68enum mx35_clks {
69 ckih, ckil, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg, 69 ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
70 arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel, 70 arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
71 esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre, 71 esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
72 spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre, 72 spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
@@ -79,7 +79,7 @@ enum mx35_clks {
79 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, 79 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
80 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, 80 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
81 wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate, 81 wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
82 gpu2d_gate, clk_max 82 gpu2d_gate, ckil, clk_max
83}; 83};
84 84
85static struct clk *clk[clk_max]; 85static struct clk *clk[clk_max];
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index fea125eb4330..97e742a8be17 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -134,6 +134,8 @@ static u32 share_count_esai;
134static u32 share_count_ssi1; 134static u32 share_count_ssi1;
135static u32 share_count_ssi2; 135static u32 share_count_ssi2;
136static u32 share_count_ssi3; 136static u32 share_count_ssi3;
137static u32 share_count_sai1;
138static u32 share_count_sai2;
137 139
138static struct clk ** const uart_clks[] __initconst = { 140static struct clk ** const uart_clks[] __initconst = {
139 &clks[IMX6SX_CLK_UART_IPG], 141 &clks[IMX6SX_CLK_UART_IPG],
@@ -469,10 +471,10 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
469 clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); 471 clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3);
470 clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); 472 clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
471 clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26); 473 clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26);
472 clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28); 474 clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1);
473 clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30); 475 clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2);
474 clks[IMX6SX_CLK_SAI1] = imx_clk_gate2("sai1", "ssi1_podf", base + 0x7c, 28); 476 clks[IMX6SX_CLK_SAI1] = imx_clk_gate2_shared("sai1", "ssi1_podf", base + 0x7c, 28, &share_count_sai1);
475 clks[IMX6SX_CLK_SAI2] = imx_clk_gate2("sai2", "ssi2_podf", base + 0x7c, 30); 477 clks[IMX6SX_CLK_SAI2] = imx_clk_gate2_shared("sai2", "ssi2_podf", base + 0x7c, 30, &share_count_sai2);
476 478
477 /* CCGR6 */ 479 /* CCGR6 */
478 clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); 480 clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index fbb6a8c8653d..522996800d5b 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -56,7 +56,7 @@ static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
56 "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", 56 "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk",
57 "pll_audio_main_clk", }; 57 "pll_audio_main_clk", };
58 58
59static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 59static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
60 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", 60 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
61 "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk", 61 "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk",
62 "pll_video_main_clk", }; 62 "pll_video_main_clk", };
@@ -342,7 +342,7 @@ static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
342 342
343static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk", 343static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
344 "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk", 344 "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
345 "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", }; 345 "pll_audio_main_clk", "pll_video_main_clk", "ckil", };
346 346
347static const char *lvds1_sel[] = { "pll_arm_main_clk", 347static const char *lvds1_sel[] = { "pll_arm_main_clk",
348 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk", 348 "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)
382 382
383 clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 383 clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
384 clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc"); 384 clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc");
385 clks[IMX7D_CKIL] = of_clk_get_by_name(ccm_node, "ckil");
385 386
386 np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); 387 np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop");
387 base = of_iomap(np, 0); 388 base = of_iomap(np, 0);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index c05c43d56a94..4826b3c9e19e 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -44,6 +44,7 @@ struct clk_pllv3 {
44 u32 powerdown; 44 u32 powerdown;
45 u32 div_mask; 45 u32 div_mask;
46 u32 div_shift; 46 u32 div_shift;
47 unsigned long ref_clock;
47}; 48};
48 49
49#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) 50#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
@@ -286,7 +287,9 @@ static const struct clk_ops clk_pllv3_av_ops = {
286static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, 287static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
287 unsigned long parent_rate) 288 unsigned long parent_rate)
288{ 289{
289 return 500000000; 290 struct clk_pllv3 *pll = to_clk_pllv3(hw);
291
292 return pll->ref_clock;
290} 293}
291 294
292static const struct clk_ops clk_pllv3_enet_ops = { 295static const struct clk_ops clk_pllv3_enet_ops = {
@@ -326,7 +329,11 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
326 break; 329 break;
327 case IMX_PLLV3_ENET_IMX7: 330 case IMX_PLLV3_ENET_IMX7:
328 pll->powerdown = IMX7_ENET_PLL_POWER; 331 pll->powerdown = IMX7_ENET_PLL_POWER;
332 pll->ref_clock = 1000000000;
333 ops = &clk_pllv3_enet_ops;
334 break;
329 case IMX_PLLV3_ENET: 335 case IMX_PLLV3_ENET:
336 pll->ref_clock = 500000000;
330 ops = &clk_pllv3_enet_ops; 337 ops = &clk_pllv3_enet_ops;
331 break; 338 break;
332 default: 339 default:
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 0a94d9661d91..3a1f24475ee4 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/of_address.h> 11#include <linux/of_address.h>
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/syscore_ops.h>
13#include <dt-bindings/clock/vf610-clock.h> 14#include <dt-bindings/clock/vf610-clock.h>
14 15
15#include "clk.h" 16#include "clk.h"
@@ -40,6 +41,7 @@
40#define CCM_CCGR9 (ccm_base + 0x64) 41#define CCM_CCGR9 (ccm_base + 0x64)
41#define CCM_CCGR10 (ccm_base + 0x68) 42#define CCM_CCGR10 (ccm_base + 0x68)
42#define CCM_CCGR11 (ccm_base + 0x6c) 43#define CCM_CCGR11 (ccm_base + 0x6c)
44#define CCM_CCGRx(x) (CCM_CCGR0 + (x) * 4)
43#define CCM_CMEOR0 (ccm_base + 0x70) 45#define CCM_CMEOR0 (ccm_base + 0x70)
44#define CCM_CMEOR1 (ccm_base + 0x74) 46#define CCM_CMEOR1 (ccm_base + 0x74)
45#define CCM_CMEOR2 (ccm_base + 0x78) 47#define CCM_CMEOR2 (ccm_base + 0x78)
@@ -115,10 +117,19 @@ static struct clk_div_table pll4_audio_div_table[] = {
115static struct clk *clk[VF610_CLK_END]; 117static struct clk *clk[VF610_CLK_END];
116static struct clk_onecell_data clk_data; 118static struct clk_onecell_data clk_data;
117 119
120static u32 cscmr1;
121static u32 cscmr2;
122static u32 cscdr1;
123static u32 cscdr2;
124static u32 cscdr3;
125static u32 ccgr[12];
126
118static unsigned int const clks_init_on[] __initconst = { 127static unsigned int const clks_init_on[] __initconst = {
119 VF610_CLK_SYS_BUS, 128 VF610_CLK_SYS_BUS,
120 VF610_CLK_DDR_SEL, 129 VF610_CLK_DDR_SEL,
121 VF610_CLK_DAP, 130 VF610_CLK_DAP,
131 VF610_CLK_DDRMC,
132 VF610_CLK_WKPU,
122}; 133};
123 134
124static struct clk * __init vf610_get_fixed_clock( 135static struct clk * __init vf610_get_fixed_clock(
@@ -132,6 +143,43 @@ static struct clk * __init vf610_get_fixed_clock(
132 return clk; 143 return clk;
133}; 144};
134 145
146static int vf610_clk_suspend(void)
147{
148 int i;
149
150 cscmr1 = readl_relaxed(CCM_CSCMR1);
151 cscmr2 = readl_relaxed(CCM_CSCMR2);
152
153 cscdr1 = readl_relaxed(CCM_CSCDR1);
154 cscdr2 = readl_relaxed(CCM_CSCDR2);
155 cscdr3 = readl_relaxed(CCM_CSCDR3);
156
157 for (i = 0; i < 12; i++)
158 ccgr[i] = readl_relaxed(CCM_CCGRx(i));
159
160 return 0;
161}
162
163static void vf610_clk_resume(void)
164{
165 int i;
166
167 writel_relaxed(cscmr1, CCM_CSCMR1);
168 writel_relaxed(cscmr2, CCM_CSCMR2);
169
170 writel_relaxed(cscdr1, CCM_CSCDR1);
171 writel_relaxed(cscdr2, CCM_CSCDR2);
172 writel_relaxed(cscdr3, CCM_CSCDR3);
173
174 for (i = 0; i < 12; i++)
175 writel_relaxed(ccgr[i], CCM_CCGRx(i));
176}
177
178static struct syscore_ops vf610_clk_syscore_ops = {
179 .suspend = vf610_clk_suspend,
180 .resume = vf610_clk_resume,
181};
182
135static void __init vf610_clocks_init(struct device_node *ccm_node) 183static void __init vf610_clocks_init(struct device_node *ccm_node)
136{ 184{
137 struct device_node *np; 185 struct device_node *np;
@@ -233,6 +281,9 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
233 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); 281 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);
234 clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1); 282 clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
235 283
284 clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
285 clk[VF610_CLK_WKPU] = imx_clk_gate2_cgr("wkpu", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(10), 0x2);
286
236 clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6); 287 clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6);
237 clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6); 288 clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6);
238 289
@@ -321,11 +372,14 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
321 clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2); 372 clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
322 clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19); 373 clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
323 clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3); 374 clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
324 clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8)); 375 clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, CCM_CCGRx_CGn(8));
325 clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2); 376 clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
326 clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23); 377 clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
327 clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3); 378 clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
328 clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8)); 379 clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(8));
380
381 clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", CCM_CCGR1, CCM_CCGRx_CGn(13));
382 clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", CCM_CCGR7, CCM_CCGRx_CGn(13));
329 383
330 clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4); 384 clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
331 clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30); 385 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)
409 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 463 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
410 clk_prepare_enable(clk[clks_init_on[i]]); 464 clk_prepare_enable(clk[clks_init_on[i]]);
411 465
466 register_syscore_ops(&vf610_clk_syscore_ops);
467
412 /* Add the clocks to provider list */ 468 /* Add the clocks to provider list */
413 clk_data.clks = clk; 469 clk_data.clks = clk;
414 clk_data.clk_num = ARRAY_SIZE(clk); 470 clk_data.clk_num = ARRAY_SIZE(clk);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index d942f5748d08..508d0fad84cf 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -41,7 +41,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
41 41
42struct clk *clk_register_gate2(struct device *dev, const char *name, 42struct clk *clk_register_gate2(struct device *dev, const char *name,
43 const char *parent_name, unsigned long flags, 43 const char *parent_name, unsigned long flags,
44 void __iomem *reg, u8 bit_idx, 44 void __iomem *reg, u8 bit_idx, u8 cgr_val,
45 u8 clk_gate_flags, spinlock_t *lock, 45 u8 clk_gate_flags, spinlock_t *lock,
46 unsigned int *share_count); 46 unsigned int *share_count);
47 47
@@ -55,7 +55,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
55 void __iomem *reg, u8 shift) 55 void __iomem *reg, u8 shift)
56{ 56{
57 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 57 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
58 shift, 0, &imx_ccm_lock, NULL); 58 shift, 0x3, 0, &imx_ccm_lock, NULL);
59} 59}
60 60
61static inline struct clk *imx_clk_gate2_shared(const char *name, 61static 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,
63 unsigned int *share_count) 63 unsigned int *share_count)
64{ 64{
65 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 65 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
66 shift, 0, &imx_ccm_lock, share_count); 66 shift, 0x3, 0, &imx_ccm_lock, share_count);
67}
68
69static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent,
70 void __iomem *reg, u8 shift, u8 cgr_val)
71{
72 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
73 shift, cgr_val, 0, &imx_ccm_lock, NULL);
67} 74}
68 75
69struct clk *imx_clk_pfd(const char *name, const char *parent_name, 76struct clk *imx_clk_pfd(const char *name, const char *parent_name,
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 7cfb7b2a2ed6..e8248f9185f7 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -325,6 +325,7 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
325 div = (div_reg >> clk_info->div.shift) & 325 div = (div_reg >> clk_info->div.shift) &
326 GENMASK(clk_info->div.bits - 1, 0); 326 GENMASK(clk_info->div.bits - 1, 0);
327 div += 1; 327 div += 1;
328 div *= clk_info->div.div;
328 329
329 rate /= div; 330 rate /= div;
330 } 331 }
@@ -345,6 +346,14 @@ ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info,
345 div = min_t(unsigned, div, 1 << clk_info->div.bits); 346 div = min_t(unsigned, div, 1 << clk_info->div.bits);
346 div = max_t(unsigned, div, 1); 347 div = max_t(unsigned, div, 1);
347 348
349 /*
350 * If the divider value itself must be divided before being written to
351 * the divider register, we must ensure we don't have any bits set that
352 * would be lost as a result of doing so.
353 */
354 div /= clk_info->div.div;
355 div *= clk_info->div.div;
356
348 return div; 357 return div;
349} 358}
350 359
@@ -395,7 +404,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
395 /* update the divide */ 404 /* update the divide */
396 mask = GENMASK(clk_info->div.bits - 1, 0); 405 mask = GENMASK(clk_info->div.bits - 1, 0);
397 reg &= ~(mask << clk_info->div.shift); 406 reg &= ~(mask << clk_info->div.shift);
398 reg |= (div - 1) << clk_info->div.shift; 407 reg |= ((div / clk_info->div.div) - 1) << clk_info->div.shift;
399 408
400 /* clear the stop bit */ 409 /* clear the stop bit */
401 if (clk_info->div.stop_bit != -1) 410 if (clk_info->div.stop_bit != -1)
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 99347e2b97e8..09700b2c555d 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -76,8 +76,11 @@ struct ingenic_cgu_mux_info {
76/** 76/**
77 * struct ingenic_cgu_div_info - information about a divider 77 * struct ingenic_cgu_div_info - information about a divider
78 * @reg: offset of the divider control register within the CGU 78 * @reg: offset of the divider control register within the CGU
79 * @shift: number of bits to shift the divide value by (ie. the index of 79 * @shift: number of bits to left shift the divide value by (ie. the index of
80 * the lowest bit of the divide value within its control register) 80 * the lowest bit of the divide value within its control register)
81 * @div: number of bits to divide the divider value by (i.e. if the
82 * effective divider value is the value written to the register
83 * multiplied by some constant)
81 * @bits: the size of the divide value in bits 84 * @bits: the size of the divide value in bits
82 * @ce_bit: the index of the change enable bit within reg, or -1 if there 85 * @ce_bit: the index of the change enable bit within reg, or -1 if there
83 * isn't one 86 * isn't one
@@ -87,6 +90,7 @@ struct ingenic_cgu_mux_info {
87struct ingenic_cgu_div_info { 90struct ingenic_cgu_div_info {
88 unsigned reg; 91 unsigned reg;
89 u8 shift; 92 u8 shift;
93 u8 div;
90 u8 bits; 94 u8 bits;
91 s8 ce_bit; 95 s8 ce_bit;
92 s8 busy_bit; 96 s8 busy_bit;
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
index 305a26c2a800..510fe7e0c8f1 100644
--- a/drivers/clk/ingenic/jz4740-cgu.c
+++ b/drivers/clk/ingenic/jz4740-cgu.c
@@ -90,51 +90,51 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
90 [JZ4740_CLK_PLL_HALF] = { 90 [JZ4740_CLK_PLL_HALF] = {
91 "pll half", CGU_CLK_DIV, 91 "pll half", CGU_CLK_DIV,
92 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 92 .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
93 .div = { CGU_REG_CPCCR, 21, 1, -1, -1, -1 }, 93 .div = { CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1 },
94 }, 94 },
95 95
96 [JZ4740_CLK_CCLK] = { 96 [JZ4740_CLK_CCLK] = {
97 "cclk", CGU_CLK_DIV, 97 "cclk", CGU_CLK_DIV,
98 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 98 .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
99 .div = { CGU_REG_CPCCR, 0, 4, 22, -1, -1 }, 99 .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
100 }, 100 },
101 101
102 [JZ4740_CLK_HCLK] = { 102 [JZ4740_CLK_HCLK] = {
103 "hclk", CGU_CLK_DIV, 103 "hclk", CGU_CLK_DIV,
104 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 104 .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
105 .div = { CGU_REG_CPCCR, 4, 4, 22, -1, -1 }, 105 .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
106 }, 106 },
107 107
108 [JZ4740_CLK_PCLK] = { 108 [JZ4740_CLK_PCLK] = {
109 "pclk", CGU_CLK_DIV, 109 "pclk", CGU_CLK_DIV,
110 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 110 .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
111 .div = { CGU_REG_CPCCR, 8, 4, 22, -1, -1 }, 111 .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 },
112 }, 112 },
113 113
114 [JZ4740_CLK_MCLK] = { 114 [JZ4740_CLK_MCLK] = {
115 "mclk", CGU_CLK_DIV, 115 "mclk", CGU_CLK_DIV,
116 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 116 .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
117 .div = { CGU_REG_CPCCR, 12, 4, 22, -1, -1 }, 117 .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 },
118 }, 118 },
119 119
120 [JZ4740_CLK_LCD] = { 120 [JZ4740_CLK_LCD] = {
121 "lcd", CGU_CLK_DIV | CGU_CLK_GATE, 121 "lcd", CGU_CLK_DIV | CGU_CLK_GATE,
122 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 122 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
123 .div = { CGU_REG_CPCCR, 16, 5, 22, -1, -1 }, 123 .div = { CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1 },
124 .gate = { CGU_REG_CLKGR, 10 }, 124 .gate = { CGU_REG_CLKGR, 10 },
125 }, 125 },
126 126
127 [JZ4740_CLK_LCD_PCLK] = { 127 [JZ4740_CLK_LCD_PCLK] = {
128 "lcd_pclk", CGU_CLK_DIV, 128 "lcd_pclk", CGU_CLK_DIV,
129 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 129 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
130 .div = { CGU_REG_LPCDR, 0, 11, -1, -1, -1 }, 130 .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
131 }, 131 },
132 132
133 [JZ4740_CLK_I2S] = { 133 [JZ4740_CLK_I2S] = {
134 "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 134 "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
135 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 135 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
136 .mux = { CGU_REG_CPCCR, 31, 1 }, 136 .mux = { CGU_REG_CPCCR, 31, 1 },
137 .div = { CGU_REG_I2SCDR, 0, 8, -1, -1, -1 }, 137 .div = { CGU_REG_I2SCDR, 0, 1, 8, -1, -1, -1 },
138 .gate = { CGU_REG_CLKGR, 6 }, 138 .gate = { CGU_REG_CLKGR, 6 },
139 }, 139 },
140 140
@@ -142,21 +142,21 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
142 "spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 142 "spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
143 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1, -1 }, 143 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1, -1 },
144 .mux = { CGU_REG_SSICDR, 31, 1 }, 144 .mux = { CGU_REG_SSICDR, 31, 1 },
145 .div = { CGU_REG_SSICDR, 0, 4, -1, -1, -1 }, 145 .div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 },
146 .gate = { CGU_REG_CLKGR, 4 }, 146 .gate = { CGU_REG_CLKGR, 4 },
147 }, 147 },
148 148
149 [JZ4740_CLK_MMC] = { 149 [JZ4740_CLK_MMC] = {
150 "mmc", CGU_CLK_DIV | CGU_CLK_GATE, 150 "mmc", CGU_CLK_DIV | CGU_CLK_GATE,
151 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 151 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
152 .div = { CGU_REG_MSCCDR, 0, 5, -1, -1, -1 }, 152 .div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
153 .gate = { CGU_REG_CLKGR, 7 }, 153 .gate = { CGU_REG_CLKGR, 7 },
154 }, 154 },
155 155
156 [JZ4740_CLK_UHC] = { 156 [JZ4740_CLK_UHC] = {
157 "uhc", CGU_CLK_DIV | CGU_CLK_GATE, 157 "uhc", CGU_CLK_DIV | CGU_CLK_GATE,
158 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 158 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
159 .div = { CGU_REG_UHCCDR, 0, 4, -1, -1, -1 }, 159 .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 },
160 .gate = { CGU_REG_CLKGR, 14 }, 160 .gate = { CGU_REG_CLKGR, 14 },
161 }, 161 },
162 162
@@ -164,7 +164,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
164 "udc", CGU_CLK_MUX | CGU_CLK_DIV, 164 "udc", CGU_CLK_MUX | CGU_CLK_DIV,
165 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 165 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
166 .mux = { CGU_REG_CPCCR, 29, 1 }, 166 .mux = { CGU_REG_CPCCR, 29, 1 },
167 .div = { CGU_REG_CPCCR, 23, 6, -1, -1, -1 }, 167 .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
168 .gate = { CGU_REG_SCR, 6 }, 168 .gate = { CGU_REG_SCR, 6 },
169 }, 169 },
170 170
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index 431f962300b6..b35d6d9dd5aa 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -296,13 +296,13 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
296 [JZ4780_CLK_CPU] = { 296 [JZ4780_CLK_CPU] = {
297 "cpu", CGU_CLK_DIV, 297 "cpu", CGU_CLK_DIV,
298 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 298 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
299 .div = { CGU_REG_CLOCKCONTROL, 0, 4, 22, -1, -1 }, 299 .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 },
300 }, 300 },
301 301
302 [JZ4780_CLK_L2CACHE] = { 302 [JZ4780_CLK_L2CACHE] = {
303 "l2cache", CGU_CLK_DIV, 303 "l2cache", CGU_CLK_DIV,
304 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 304 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
305 .div = { CGU_REG_CLOCKCONTROL, 4, 4, -1, -1, -1 }, 305 .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 },
306 }, 306 },
307 307
308 [JZ4780_CLK_AHB0] = { 308 [JZ4780_CLK_AHB0] = {
@@ -310,7 +310,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
310 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 310 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
311 JZ4780_CLK_EPLL }, 311 JZ4780_CLK_EPLL },
312 .mux = { CGU_REG_CLOCKCONTROL, 26, 2 }, 312 .mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
313 .div = { CGU_REG_CLOCKCONTROL, 8, 4, 21, -1, -1 }, 313 .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 },
314 }, 314 },
315 315
316 [JZ4780_CLK_AHB2PMUX] = { 316 [JZ4780_CLK_AHB2PMUX] = {
@@ -323,20 +323,20 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
323 [JZ4780_CLK_AHB2] = { 323 [JZ4780_CLK_AHB2] = {
324 "ahb2", CGU_CLK_DIV, 324 "ahb2", CGU_CLK_DIV,
325 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 325 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
326 .div = { CGU_REG_CLOCKCONTROL, 12, 4, 20, -1, -1 }, 326 .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 },
327 }, 327 },
328 328
329 [JZ4780_CLK_PCLK] = { 329 [JZ4780_CLK_PCLK] = {
330 "pclk", CGU_CLK_DIV, 330 "pclk", CGU_CLK_DIV,
331 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 331 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
332 .div = { CGU_REG_CLOCKCONTROL, 16, 4, 20, -1, -1 }, 332 .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 },
333 }, 333 },
334 334
335 [JZ4780_CLK_DDR] = { 335 [JZ4780_CLK_DDR] = {
336 "ddr", CGU_CLK_MUX | CGU_CLK_DIV, 336 "ddr", CGU_CLK_MUX | CGU_CLK_DIV,
337 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, 337 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
338 .mux = { CGU_REG_DDRCDR, 30, 2 }, 338 .mux = { CGU_REG_DDRCDR, 30, 2 },
339 .div = { CGU_REG_DDRCDR, 0, 4, 29, 28, 27 }, 339 .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
340 }, 340 },
341 341
342 [JZ4780_CLK_VPU] = { 342 [JZ4780_CLK_VPU] = {
@@ -344,7 +344,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
344 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 344 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
345 JZ4780_CLK_EPLL, -1 }, 345 JZ4780_CLK_EPLL, -1 },
346 .mux = { CGU_REG_VPUCDR, 30, 2 }, 346 .mux = { CGU_REG_VPUCDR, 30, 2 },
347 .div = { CGU_REG_VPUCDR, 0, 4, 29, 28, 27 }, 347 .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 },
348 .gate = { CGU_REG_CLKGR1, 2 }, 348 .gate = { CGU_REG_CLKGR1, 2 },
349 }, 349 },
350 350
@@ -352,7 +352,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
352 "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV, 352 "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
353 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 }, 353 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 },
354 .mux = { CGU_REG_I2SCDR, 30, 1 }, 354 .mux = { CGU_REG_I2SCDR, 30, 1 },
355 .div = { CGU_REG_I2SCDR, 0, 8, 29, 28, 27 }, 355 .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 },
356 }, 356 },
357 357
358 [JZ4780_CLK_I2S] = { 358 [JZ4780_CLK_I2S] = {
@@ -366,7 +366,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
366 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 366 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
367 JZ4780_CLK_VPLL, -1 }, 367 JZ4780_CLK_VPLL, -1 },
368 .mux = { CGU_REG_LP0CDR, 30, 2 }, 368 .mux = { CGU_REG_LP0CDR, 30, 2 },
369 .div = { CGU_REG_LP0CDR, 0, 8, 28, 27, 26 }, 369 .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 },
370 }, 370 },
371 371
372 [JZ4780_CLK_LCD1PIXCLK] = { 372 [JZ4780_CLK_LCD1PIXCLK] = {
@@ -374,7 +374,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
374 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 374 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
375 JZ4780_CLK_VPLL, -1 }, 375 JZ4780_CLK_VPLL, -1 },
376 .mux = { CGU_REG_LP1CDR, 30, 2 }, 376 .mux = { CGU_REG_LP1CDR, 30, 2 },
377 .div = { CGU_REG_LP1CDR, 0, 8, 28, 27, 26 }, 377 .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 },
378 }, 378 },
379 379
380 [JZ4780_CLK_MSCMUX] = { 380 [JZ4780_CLK_MSCMUX] = {
@@ -386,21 +386,21 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
386 [JZ4780_CLK_MSC0] = { 386 [JZ4780_CLK_MSC0] = {
387 "msc0", CGU_CLK_DIV | CGU_CLK_GATE, 387 "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
388 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 388 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
389 .div = { CGU_REG_MSC0CDR, 0, 8, 29, 28, 27 }, 389 .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
390 .gate = { CGU_REG_CLKGR0, 3 }, 390 .gate = { CGU_REG_CLKGR0, 3 },
391 }, 391 },
392 392
393 [JZ4780_CLK_MSC1] = { 393 [JZ4780_CLK_MSC1] = {
394 "msc1", CGU_CLK_DIV | CGU_CLK_GATE, 394 "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
395 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 395 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
396 .div = { CGU_REG_MSC1CDR, 0, 8, 29, 28, 27 }, 396 .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
397 .gate = { CGU_REG_CLKGR0, 11 }, 397 .gate = { CGU_REG_CLKGR0, 11 },
398 }, 398 },
399 399
400 [JZ4780_CLK_MSC2] = { 400 [JZ4780_CLK_MSC2] = {
401 "msc2", CGU_CLK_DIV | CGU_CLK_GATE, 401 "msc2", CGU_CLK_DIV | CGU_CLK_GATE,
402 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 402 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
403 .div = { CGU_REG_MSC2CDR, 0, 8, 29, 28, 27 }, 403 .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 },
404 .gate = { CGU_REG_CLKGR0, 12 }, 404 .gate = { CGU_REG_CLKGR0, 12 },
405 }, 405 },
406 406
@@ -409,7 +409,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
409 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 409 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
410 JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY }, 410 JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
411 .mux = { CGU_REG_UHCCDR, 30, 2 }, 411 .mux = { CGU_REG_UHCCDR, 30, 2 },
412 .div = { CGU_REG_UHCCDR, 0, 8, 29, 28, 27 }, 412 .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 },
413 .gate = { CGU_REG_CLKGR0, 24 }, 413 .gate = { CGU_REG_CLKGR0, 24 },
414 }, 414 },
415 415
@@ -417,7 +417,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
417 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, 417 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
418 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 418 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
419 .mux = { CGU_REG_SSICDR, 30, 1 }, 419 .mux = { CGU_REG_SSICDR, 30, 1 },
420 .div = { CGU_REG_SSICDR, 0, 8, 29, 28, 27 }, 420 .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
421 }, 421 },
422 422
423 [JZ4780_CLK_SSI] = { 423 [JZ4780_CLK_SSI] = {
@@ -430,7 +430,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
430 "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV, 430 "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
431 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 431 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
432 .mux = { CGU_REG_CIMCDR, 31, 1 }, 432 .mux = { CGU_REG_CIMCDR, 31, 1 },
433 .div = { CGU_REG_CIMCDR, 0, 8, 30, 29, 28 }, 433 .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 },
434 }, 434 },
435 435
436 [JZ4780_CLK_PCMPLL] = { 436 [JZ4780_CLK_PCMPLL] = {
@@ -438,7 +438,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
438 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 438 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
439 JZ4780_CLK_EPLL, JZ4780_CLK_VPLL }, 439 JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
440 .mux = { CGU_REG_PCMCDR, 29, 2 }, 440 .mux = { CGU_REG_PCMCDR, 29, 2 },
441 .div = { CGU_REG_PCMCDR, 0, 8, 28, 27, 26 }, 441 .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 },
442 }, 442 },
443 443
444 [JZ4780_CLK_PCM] = { 444 [JZ4780_CLK_PCM] = {
@@ -453,7 +453,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
453 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 453 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
454 JZ4780_CLK_EPLL }, 454 JZ4780_CLK_EPLL },
455 .mux = { CGU_REG_GPUCDR, 30, 2 }, 455 .mux = { CGU_REG_GPUCDR, 30, 2 },
456 .div = { CGU_REG_GPUCDR, 0, 4, 29, 28, 27 }, 456 .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 },
457 .gate = { CGU_REG_CLKGR1, 4 }, 457 .gate = { CGU_REG_CLKGR1, 4 },
458 }, 458 },
459 459
@@ -462,7 +462,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
462 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 462 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
463 JZ4780_CLK_VPLL, -1 }, 463 JZ4780_CLK_VPLL, -1 },
464 .mux = { CGU_REG_HDMICDR, 30, 2 }, 464 .mux = { CGU_REG_HDMICDR, 30, 2 },
465 .div = { CGU_REG_HDMICDR, 0, 8, 29, 28, 26 }, 465 .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 },
466 .gate = { CGU_REG_CLKGR1, 9 }, 466 .gate = { CGU_REG_CLKGR1, 9 },
467 }, 467 },
468 468
@@ -471,7 +471,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
471 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 471 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
472 JZ4780_CLK_EPLL }, 472 JZ4780_CLK_EPLL },
473 .mux = { CGU_REG_BCHCDR, 30, 2 }, 473 .mux = { CGU_REG_BCHCDR, 30, 2 },
474 .div = { CGU_REG_BCHCDR, 0, 4, 29, 28, 27 }, 474 .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 },
475 .gate = { CGU_REG_CLKGR0, 1 }, 475 .gate = { CGU_REG_CLKGR0, 1 },
476 }, 476 },
477 477
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 61f6d55c4ac7..4d057b3e21b2 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -141,11 +141,11 @@ static const struct composite_conf mali_conf __initconst = {
141}; 141};
142 142
143static const struct clk_conf meson8b_xtal_conf __initconst = 143static const struct clk_conf meson8b_xtal_conf __initconst =
144 FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 144 FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 0,
145 CLK_IS_ROOT, PARM(0x00, 4, 7)); 145 PARM(0x00, 4, 7));
146 146
147static const struct clk_conf meson8b_clk_confs[] __initconst = { 147static const struct clk_conf meson8b_clk_confs[] __initconst = {
148 FIXED_RATE(CLKID_ZERO, "zero", CLK_IS_ROOT, 0), 148 FIXED_RATE(CLKID_ZERO, "zero", 0, 0),
149 PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll", 149 PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
150 p_xtal, 0, &pll_confs), 150 p_xtal, 0, &pll_confs),
151 PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll", 151 PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 38931dbd1eff..383f6a4f64f0 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -99,23 +99,19 @@ void __init mmp2_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
99 return; 99 return;
100 } 100 }
101 101
102 clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); 102 clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200);
103 clk_register_clkdev(clk, "clk32", NULL); 103 clk_register_clkdev(clk, "clk32", NULL);
104 104
105 vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, 105 vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000);
106 26000000);
107 clk_register_clkdev(vctcxo, "vctcxo", NULL); 106 clk_register_clkdev(vctcxo, "vctcxo", NULL);
108 107
109 clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, 108 clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 800000000);
110 800000000);
111 clk_register_clkdev(clk, "pll1", NULL); 109 clk_register_clkdev(clk, "pll1", NULL);
112 110
113 clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, CLK_IS_ROOT, 111 clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, 0, 480000000);
114 480000000);
115 clk_register_clkdev(clk, "usb_pll", NULL); 112 clk_register_clkdev(clk, "usb_pll", NULL);
116 113
117 clk = clk_register_fixed_rate(NULL, "pll2", NULL, CLK_IS_ROOT, 114 clk = clk_register_fixed_rate(NULL, "pll2", NULL, 0, 960000000);
118 960000000);
119 clk_register_clkdev(clk, "pll2", NULL); 115 clk_register_clkdev(clk, "pll2", NULL);
120 116
121 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1", 117 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 251533d87c65..3a51fff1b0e7 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -63,11 +63,11 @@ struct mmp2_clk_unit {
63}; 63};
64 64
65static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 65static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
66 {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 66 {MMP2_CLK_CLK32, "clk32", NULL, 0, 32768},
67 {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 67 {MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
68 {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 800000000}, 68 {MMP2_CLK_PLL1, "pll1", NULL, 0, 800000000},
69 {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 960000000}, 69 {MMP2_CLK_PLL2, "pll2", NULL, 0, 960000000},
70 {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 70 {MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
71}; 71};
72 72
73static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 73static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 64eaf4141c69..87f2317b2a00 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -56,10 +56,10 @@ struct pxa168_clk_unit {
56}; 56};
57 57
58static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 58static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
59 {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 59 {PXA168_CLK_CLK32, "clk32", NULL, 0, 32768},
60 {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 60 {PXA168_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
61 {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, 61 {PXA168_CLK_PLL1, "pll1", NULL, 0, 624000000},
62 {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 62 {PXA168_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
63}; 63};
64 64
65static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 65static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa1928.c b/drivers/clk/mmp/clk-of-pxa1928.c
index 433a5ae1eae0..e478ff44e170 100644
--- a/drivers/clk/mmp/clk-of-pxa1928.c
+++ b/drivers/clk/mmp/clk-of-pxa1928.c
@@ -34,12 +34,12 @@ struct pxa1928_clk_unit {
34}; 34};
35 35
36static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 36static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
37 {0, "clk32", NULL, CLK_IS_ROOT, 32768}, 37 {0, "clk32", NULL, 0, 32768},
38 {0, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 38 {0, "vctcxo", NULL, 0, 26000000},
39 {0, "pll1_624", NULL, CLK_IS_ROOT, 624000000}, 39 {0, "pll1_624", NULL, 0, 624000000},
40 {0, "pll5p", NULL, CLK_IS_ROOT, 832000000}, 40 {0, "pll5p", NULL, 0, 832000000},
41 {0, "pll5", NULL, CLK_IS_ROOT, 1248000000}, 41 {0, "pll5", NULL, 0, 1248000000},
42 {0, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 42 {0, "usb_pll", NULL, 0, 480000000},
43}; 43};
44 44
45static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 45static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
index 13d6173326a4..e22a67f76d93 100644
--- a/drivers/clk/mmp/clk-of-pxa910.c
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -56,10 +56,10 @@ struct pxa910_clk_unit {
56}; 56};
57 57
58static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 58static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
59 {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 59 {PXA910_CLK_CLK32, "clk32", NULL, 0, 32768},
60 {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 60 {PXA910_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
61 {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, 61 {PXA910_CLK_PLL1, "pll1", NULL, 0, 624000000},
62 {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 62 {PXA910_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
63}; 63};
64 64
65static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 65static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c
index 0dd83fb950c9..a9ef9209532a 100644
--- a/drivers/clk/mmp/clk-pxa168.c
+++ b/drivers/clk/mmp/clk-pxa168.c
@@ -92,15 +92,13 @@ void __init pxa168_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
92 return; 92 return;
93 } 93 }
94 94
95 clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); 95 clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200);
96 clk_register_clkdev(clk, "clk32", NULL); 96 clk_register_clkdev(clk, "clk32", NULL);
97 97
98 clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, 98 clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000);
99 26000000);
100 clk_register_clkdev(clk, "vctcxo", NULL); 99 clk_register_clkdev(clk, "vctcxo", NULL);
101 100
102 clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, 101 clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 624000000);
103 624000000);
104 clk_register_clkdev(clk, "pll1", NULL); 102 clk_register_clkdev(clk, "pll1", NULL);
105 103
106 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1", 104 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c
index e1d2ce22cdf1..a520cf7702a1 100644
--- a/drivers/clk/mmp/clk-pxa910.c
+++ b/drivers/clk/mmp/clk-pxa910.c
@@ -97,15 +97,13 @@ void __init pxa910_clk_init(phys_addr_t mpmu_phys, phys_addr_t apmu_phys,
97 return; 97 return;
98 } 98 }
99 99
100 clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); 100 clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200);
101 clk_register_clkdev(clk, "clk32", NULL); 101 clk_register_clkdev(clk, "clk32", NULL);
102 102
103 clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, 103 clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000);
104 26000000);
105 clk_register_clkdev(clk, "vctcxo", NULL); 104 clk_register_clkdev(clk, "vctcxo", NULL);
106 105
107 clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, 106 clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 624000000);
108 624000000);
109 clk_register_clkdev(clk, "pll1", NULL); 107 clk_register_clkdev(clk, "pll1", NULL);
110 108
111 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1", 109 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index eaee8f099c8c..3165da77d525 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -29,6 +29,12 @@ config ARMADA_XP_CLK
29 select MVEBU_CLK_COMMON 29 select MVEBU_CLK_COMMON
30 select MVEBU_CLK_CPU 30 select MVEBU_CLK_CPU
31 31
32config ARMADA_AP806_SYSCON
33 bool
34
35config ARMADA_CP110_SYSCON
36 bool
37
32config DOVE_CLK 38config DOVE_CLK
33 bool 39 bool
34 select MVEBU_CLK_COMMON 40 select MVEBU_CLK_COMMON
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 8866115486f7..7172ef65693d 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o
7obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o 7obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o
8obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o 8obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o
9obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o 9obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o
10obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
11obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
10obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o 12obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o
11obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o 13obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o
12obj-$(CONFIG_ORION_CLK) += orion.o 14obj-$(CONFIG_ORION_CLK) += orion.o
diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
new file mode 100644
index 000000000000..02023baf86c9
--- /dev/null
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -0,0 +1,168 @@
1/*
2 * Marvell Armada AP806 System Controller
3 *
4 * Copyright (C) 2016 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#define pr_fmt(fmt) "ap806-system-controller: " fmt
14
15#include <linux/clk-provider.h>
16#include <linux/mfd/syscon.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/platform_device.h>
21#include <linux/regmap.h>
22
23#define AP806_SAR_REG 0x400
24#define AP806_SAR_CLKFREQ_MODE_MASK 0x1f
25
26#define AP806_CLK_NUM 4
27
28static struct clk *ap806_clks[AP806_CLK_NUM];
29
30static struct clk_onecell_data ap806_clk_data = {
31 .clks = ap806_clks,
32 .clk_num = AP806_CLK_NUM,
33};
34
35static int ap806_syscon_clk_probe(struct platform_device *pdev)
36{
37 unsigned int freq_mode, cpuclk_freq;
38 const char *name, *fixedclk_name;
39 struct device_node *np = pdev->dev.of_node;
40 struct regmap *regmap;
41 u32 reg;
42 int ret;
43
44 regmap = syscon_node_to_regmap(np);
45 if (IS_ERR(regmap)) {
46 dev_err(&pdev->dev, "cannot get regmap\n");
47 return PTR_ERR(regmap);
48 }
49
50 ret = regmap_read(regmap, AP806_SAR_REG, &reg);
51 if (ret) {
52 dev_err(&pdev->dev, "cannot read from regmap\n");
53 return ret;
54 }
55
56 freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
57 switch (freq_mode) {
58 case 0x0 ... 0x5:
59 cpuclk_freq = 2000;
60 break;
61 case 0x6 ... 0xB:
62 cpuclk_freq = 1800;
63 break;
64 case 0xC ... 0x11:
65 cpuclk_freq = 1600;
66 break;
67 case 0x12 ... 0x16:
68 cpuclk_freq = 1400;
69 break;
70 case 0x17 ... 0x19:
71 cpuclk_freq = 1300;
72 break;
73 default:
74 dev_err(&pdev->dev, "invalid SAR value\n");
75 return -EINVAL;
76 }
77
78 /* Convert to hertz */
79 cpuclk_freq *= 1000 * 1000;
80
81 /* CPU clocks depend on the Sample At Reset configuration */
82 of_property_read_string_index(np, "clock-output-names",
83 0, &name);
84 ap806_clks[0] = clk_register_fixed_rate(&pdev->dev, name, NULL,
85 0, cpuclk_freq);
86 if (IS_ERR(ap806_clks[0])) {
87 ret = PTR_ERR(ap806_clks[0]);
88 goto fail0;
89 }
90
91 of_property_read_string_index(np, "clock-output-names",
92 1, &name);
93 ap806_clks[1] = clk_register_fixed_rate(&pdev->dev, name, NULL, 0,
94 cpuclk_freq);
95 if (IS_ERR(ap806_clks[1])) {
96 ret = PTR_ERR(ap806_clks[1]);
97 goto fail1;
98 }
99
100 /* Fixed clock is always 1200 Mhz */
101 of_property_read_string_index(np, "clock-output-names",
102 2, &fixedclk_name);
103 ap806_clks[2] = clk_register_fixed_rate(&pdev->dev, fixedclk_name, NULL,
104 0, 1200 * 1000 * 1000);
105 if (IS_ERR(ap806_clks[2])) {
106 ret = PTR_ERR(ap806_clks[2]);
107 goto fail2;
108 }
109
110 /* MSS Clock is fixed clock divided by 6 */
111 of_property_read_string_index(np, "clock-output-names",
112 3, &name);
113 ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name,
114 0, 1, 6);
115 if (IS_ERR(ap806_clks[3])) {
116 ret = PTR_ERR(ap806_clks[3]);
117 goto fail3;
118 }
119
120 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
121 if (ret)
122 goto fail_clk_add;
123
124 return 0;
125
126fail_clk_add:
127 clk_unregister_fixed_factor(ap806_clks[3]);
128fail3:
129 clk_unregister_fixed_rate(ap806_clks[2]);
130fail2:
131 clk_unregister_fixed_rate(ap806_clks[1]);
132fail1:
133 clk_unregister_fixed_rate(ap806_clks[0]);
134fail0:
135 return ret;
136}
137
138static int ap806_syscon_clk_remove(struct platform_device *pdev)
139{
140 of_clk_del_provider(pdev->dev.of_node);
141 clk_unregister_fixed_factor(ap806_clks[3]);
142 clk_unregister_fixed_rate(ap806_clks[2]);
143 clk_unregister_fixed_rate(ap806_clks[1]);
144 clk_unregister_fixed_rate(ap806_clks[0]);
145
146 return 0;
147}
148
149static const struct of_device_id ap806_syscon_of_match[] = {
150 { .compatible = "marvell,ap806-system-controller", },
151 { }
152};
153MODULE_DEVICE_TABLE(of, armada8k_pcie_of_match);
154
155static struct platform_driver ap806_syscon_driver = {
156 .probe = ap806_syscon_clk_probe,
157 .remove = ap806_syscon_clk_remove,
158 .driver = {
159 .name = "marvell-ap806-system-controller",
160 .of_match_table = ap806_syscon_of_match,
161 },
162};
163
164module_platform_driver(ap806_syscon_driver);
165
166MODULE_DESCRIPTION("Marvell AP806 System Controller driver");
167MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
168MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
new file mode 100644
index 000000000000..7fa42d6b2b92
--- /dev/null
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -0,0 +1,406 @@
1/*
2 * Marvell Armada CP110 System Controller
3 *
4 * Copyright (C) 2016 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13/*
14 * CP110 has 5 core clocks:
15 *
16 * - APLL (1 Ghz)
17 * - PPv2 core (1/3 APLL)
18 * - EIP (1/2 APLL)
19 * - Core (1/2 EIP)
20 *
21 * - NAND clock, which is either:
22 * - Equal to the core clock
23 * - 2/5 APLL
24 *
25 * CP110 has 32 gatable clocks, for the various peripherals in the
26 * IP. They have fairly complicated parent/child relationships.
27 */
28
29#define pr_fmt(fmt) "cp110-system-controller: " fmt
30
31#include <linux/clk-provider.h>
32#include <linux/mfd/syscon.h>
33#include <linux/module.h>
34#include <linux/of.h>
35#include <linux/of_address.h>
36#include <linux/platform_device.h>
37#include <linux/regmap.h>
38#include <linux/slab.h>
39
40#define CP110_PM_CLOCK_GATING_REG 0x220
41#define CP110_NAND_FLASH_CLK_CTRL_REG 0x700
42#define NF_CLOCK_SEL_400_MASK BIT(0)
43
44enum {
45 CP110_CLK_TYPE_CORE,
46 CP110_CLK_TYPE_GATABLE,
47};
48
49#define CP110_MAX_CORE_CLOCKS 5
50#define CP110_MAX_GATABLE_CLOCKS 32
51
52#define CP110_CLK_NUM \
53 (CP110_MAX_CORE_CLOCKS + CP110_MAX_GATABLE_CLOCKS)
54
55#define CP110_CORE_APLL 0
56#define CP110_CORE_PPV2 1
57#define CP110_CORE_EIP 2
58#define CP110_CORE_CORE 3
59#define CP110_CORE_NAND 4
60
61/* A number of gatable clocks need special handling */
62#define CP110_GATE_AUDIO 0
63#define CP110_GATE_COMM_UNIT 1
64#define CP110_GATE_NAND 2
65#define CP110_GATE_PPV2 3
66#define CP110_GATE_SDIO 4
67#define CP110_GATE_XOR1 7
68#define CP110_GATE_XOR0 8
69#define CP110_GATE_PCIE_X1_0 11
70#define CP110_GATE_PCIE_X1_1 12
71#define CP110_GATE_PCIE_X4 13
72#define CP110_GATE_PCIE_XOR 14
73#define CP110_GATE_SATA 15
74#define CP110_GATE_SATA_USB 16
75#define CP110_GATE_MAIN 17
76#define CP110_GATE_SDMMC 18
77#define CP110_GATE_SLOW_IO 21
78#define CP110_GATE_USB3H0 22
79#define CP110_GATE_USB3H1 23
80#define CP110_GATE_USB3DEV 24
81#define CP110_GATE_EIP150 25
82#define CP110_GATE_EIP197 26
83
84static struct clk *cp110_clks[CP110_CLK_NUM];
85
86static struct clk_onecell_data cp110_clk_data = {
87 .clks = cp110_clks,
88 .clk_num = CP110_CLK_NUM,
89};
90
91struct cp110_gate_clk {
92 struct clk_hw hw;
93 struct regmap *regmap;
94 u8 bit_idx;
95};
96
97#define to_cp110_gate_clk(clk) container_of(clk, struct cp110_gate_clk, hw)
98
99static int cp110_gate_enable(struct clk_hw *hw)
100{
101 struct cp110_gate_clk *gate = to_cp110_gate_clk(hw);
102
103 regmap_update_bits(gate->regmap, CP110_PM_CLOCK_GATING_REG,
104 BIT(gate->bit_idx), BIT(gate->bit_idx));
105
106 return 0;
107}
108
109static void cp110_gate_disable(struct clk_hw *hw)
110{
111 struct cp110_gate_clk *gate = to_cp110_gate_clk(hw);
112
113 regmap_update_bits(gate->regmap, CP110_PM_CLOCK_GATING_REG,
114 BIT(gate->bit_idx), 0);
115}
116
117static int cp110_gate_is_enabled(struct clk_hw *hw)
118{
119 struct cp110_gate_clk *gate = to_cp110_gate_clk(hw);
120 u32 val;
121
122 regmap_read(gate->regmap, CP110_PM_CLOCK_GATING_REG, &val);
123
124 return val & BIT(gate->bit_idx);
125}
126
127static const struct clk_ops cp110_gate_ops = {
128 .enable = cp110_gate_enable,
129 .disable = cp110_gate_disable,
130 .is_enabled = cp110_gate_is_enabled,
131};
132
133static struct clk *cp110_register_gate(const char *name,
134 const char *parent_name,
135 struct regmap *regmap, u8 bit_idx)
136{
137 struct cp110_gate_clk *gate;
138 struct clk *clk;
139 struct clk_init_data init;
140
141 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
142 if (!gate)
143 return ERR_PTR(-ENOMEM);
144
145 init.name = name;
146 init.ops = &cp110_gate_ops;
147 init.parent_names = &parent_name;
148 init.num_parents = 1;
149
150 gate->regmap = regmap;
151 gate->bit_idx = bit_idx;
152 gate->hw.init = &init;
153
154 clk = clk_register(NULL, &gate->hw);
155 if (IS_ERR(clk))
156 kfree(gate);
157
158 return clk;
159}
160
161static void cp110_unregister_gate(struct clk *clk)
162{
163 struct clk_hw *hw;
164
165 hw = __clk_get_hw(clk);
166 if (!hw)
167 return;
168
169 clk_unregister(clk);
170 kfree(to_cp110_gate_clk(hw));
171}
172
173static struct clk *cp110_of_clk_get(struct of_phandle_args *clkspec, void *data)
174{
175 struct clk_onecell_data *clk_data = data;
176 unsigned int type = clkspec->args[0];
177 unsigned int idx = clkspec->args[1];
178
179 if (type == CP110_CLK_TYPE_CORE) {
180 if (idx > CP110_MAX_CORE_CLOCKS)
181 return ERR_PTR(-EINVAL);
182 return clk_data->clks[idx];
183 } else if (type == CP110_CLK_TYPE_GATABLE) {
184 if (idx > CP110_MAX_GATABLE_CLOCKS)
185 return ERR_PTR(-EINVAL);
186 return clk_data->clks[CP110_MAX_CORE_CLOCKS + idx];
187 }
188
189 return ERR_PTR(-EINVAL);
190}
191
192static int cp110_syscon_clk_probe(struct platform_device *pdev)
193{
194 struct regmap *regmap;
195 struct device_node *np = pdev->dev.of_node;
196 const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
197 struct clk *clk;
198 u32 nand_clk_ctrl;
199 int i, ret;
200
201 regmap = syscon_node_to_regmap(np);
202 if (IS_ERR(regmap))
203 return PTR_ERR(regmap);
204
205 ret = regmap_read(regmap, CP110_NAND_FLASH_CLK_CTRL_REG,
206 &nand_clk_ctrl);
207 if (ret)
208 return ret;
209
210 /* Register the APLL which is the root of the clk tree */
211 of_property_read_string_index(np, "core-clock-output-names",
212 CP110_CORE_APLL, &apll_name);
213 clk = clk_register_fixed_rate(NULL, apll_name, NULL, 0,
214 1000 * 1000 * 1000);
215 if (IS_ERR(clk)) {
216 ret = PTR_ERR(clk);
217 goto fail0;
218 }
219
220 cp110_clks[CP110_CORE_APLL] = clk;
221
222 /* PPv2 is APLL/3 */
223 of_property_read_string_index(np, "core-clock-output-names",
224 CP110_CORE_PPV2, &ppv2_name);
225 clk = clk_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
226 if (IS_ERR(clk)) {
227 ret = PTR_ERR(clk);
228 goto fail1;
229 }
230
231 cp110_clks[CP110_CORE_PPV2] = clk;
232
233 /* EIP clock is APLL/2 */
234 of_property_read_string_index(np, "core-clock-output-names",
235 CP110_CORE_EIP, &eip_name);
236 clk = clk_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
237 if (IS_ERR(clk)) {
238 ret = PTR_ERR(clk);
239 goto fail2;
240 }
241
242 cp110_clks[CP110_CORE_EIP] = clk;
243
244 /* Core clock is EIP/2 */
245 of_property_read_string_index(np, "core-clock-output-names",
246 CP110_CORE_CORE, &core_name);
247 clk = clk_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
248 if (IS_ERR(clk)) {
249 ret = PTR_ERR(clk);
250 goto fail3;
251 }
252
253 cp110_clks[CP110_CORE_CORE] = clk;
254
255 /* NAND can be either APLL/2.5 or core clock */
256 of_property_read_string_index(np, "core-clock-output-names",
257 CP110_CORE_NAND, &nand_name);
258 if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
259 clk = clk_register_fixed_factor(NULL, nand_name,
260 apll_name, 0, 2, 5);
261 else
262 clk = clk_register_fixed_factor(NULL, nand_name,
263 core_name, 0, 1, 1);
264 if (IS_ERR(clk)) {
265 ret = PTR_ERR(clk);
266 goto fail4;
267 }
268
269 cp110_clks[CP110_CORE_NAND] = clk;
270
271 for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
272 const char *parent, *name;
273 int ret;
274
275 ret = of_property_read_string_index(np,
276 "gate-clock-output-names",
277 i, &name);
278 /* Reached the end of the list? */
279 if (ret < 0)
280 break;
281
282 if (!strcmp(name, "none"))
283 continue;
284
285 switch (i) {
286 case CP110_GATE_AUDIO:
287 case CP110_GATE_COMM_UNIT:
288 case CP110_GATE_EIP150:
289 case CP110_GATE_EIP197:
290 case CP110_GATE_SLOW_IO:
291 of_property_read_string_index(np,
292 "gate-clock-output-names",
293 CP110_GATE_MAIN, &parent);
294 break;
295 case CP110_GATE_NAND:
296 parent = nand_name;
297 break;
298 case CP110_GATE_PPV2:
299 parent = ppv2_name;
300 break;
301 case CP110_GATE_SDIO:
302 of_property_read_string_index(np,
303 "gate-clock-output-names",
304 CP110_GATE_SDMMC, &parent);
305 break;
306 case CP110_GATE_XOR1:
307 case CP110_GATE_XOR0:
308 case CP110_GATE_PCIE_X1_0:
309 case CP110_GATE_PCIE_X1_1:
310 case CP110_GATE_PCIE_X4:
311 of_property_read_string_index(np,
312 "gate-clock-output-names",
313 CP110_GATE_PCIE_XOR, &parent);
314 break;
315 case CP110_GATE_SATA:
316 case CP110_GATE_USB3H0:
317 case CP110_GATE_USB3H1:
318 case CP110_GATE_USB3DEV:
319 of_property_read_string_index(np,
320 "gate-clock-output-names",
321 CP110_GATE_SATA_USB, &parent);
322 break;
323 default:
324 parent = core_name;
325 break;
326 }
327
328 clk = cp110_register_gate(name, parent, regmap, i);
329 if (IS_ERR(clk)) {
330 ret = PTR_ERR(clk);
331 goto fail_gate;
332 }
333
334 cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk;
335 }
336
337 ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data);
338 if (ret)
339 goto fail_clk_add;
340
341 return 0;
342
343fail_clk_add:
344fail_gate:
345 for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
346 clk = cp110_clks[CP110_MAX_CORE_CLOCKS + i];
347
348 if (clk)
349 cp110_unregister_gate(clk);
350 }
351
352 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
353fail4:
354 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
355fail3:
356 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
357fail2:
358 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
359fail1:
360 clk_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
361fail0:
362 return ret;
363}
364
365static int cp110_syscon_clk_remove(struct platform_device *pdev)
366{
367 int i;
368
369 of_clk_del_provider(pdev->dev.of_node);
370
371 for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
372 struct clk *clk = cp110_clks[CP110_MAX_CORE_CLOCKS + i];
373
374 if (clk)
375 cp110_unregister_gate(clk);
376 }
377
378 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
379 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
380 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
381 clk_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
382 clk_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
383
384 return 0;
385}
386
387static const struct of_device_id cp110_syscon_of_match[] = {
388 { .compatible = "marvell,cp110-system-controller0", },
389 { }
390};
391MODULE_DEVICE_TABLE(of, armada8k_pcie_of_match);
392
393static struct platform_driver cp110_syscon_driver = {
394 .probe = cp110_syscon_clk_probe,
395 .remove = cp110_syscon_clk_remove,
396 .driver = {
397 .name = "marvell-cp110-system-controller0",
398 .of_match_table = cp110_syscon_of_match,
399 },
400};
401
402module_platform_driver(cp110_syscon_driver);
403
404MODULE_DESCRIPTION("Marvell CP110 System Controller 0 driver");
405MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
406MODULE_LICENSE("GPL");
diff --git a/drivers/clk/nxp/clk-lpc18xx-creg.c b/drivers/clk/nxp/clk-lpc18xx-creg.c
index d44b61afa2dc..9e35749dafdf 100644
--- a/drivers/clk/nxp/clk-lpc18xx-creg.c
+++ b/drivers/clk/nxp/clk-lpc18xx-creg.c
@@ -147,6 +147,7 @@ static struct clk *clk_register_creg_clk(struct device *dev,
147 init.name = creg_clk->name; 147 init.name = creg_clk->name;
148 init.parent_names = parent_name; 148 init.parent_names = parent_name;
149 init.num_parents = 1; 149 init.num_parents = 1;
150 init.flags = 0;
150 151
151 creg_clk->reg = syscon; 152 creg_clk->reg = syscon;
152 creg_clk->hw.init = &init; 153 creg_clk->hw.init = &init;
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index 9c29080a84d8..5c4e193164d4 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -2346,6 +2346,7 @@ static struct clk_branch gcc_crypto_ahb_clk = {
2346 "pcnoc_bfdcd_clk_src", 2346 "pcnoc_bfdcd_clk_src",
2347 }, 2347 },
2348 .num_parents = 1, 2348 .num_parents = 1,
2349 .flags = CLK_SET_RATE_PARENT,
2349 .ops = &clk_branch2_ops, 2350 .ops = &clk_branch2_ops,
2350 }, 2351 },
2351 }, 2352 },
@@ -2381,6 +2382,7 @@ static struct clk_branch gcc_crypto_clk = {
2381 "crypto_clk_src", 2382 "crypto_clk_src",
2382 }, 2383 },
2383 .num_parents = 1, 2384 .num_parents = 1,
2385 .flags = CLK_SET_RATE_PARENT,
2384 .ops = &clk_branch2_ops, 2386 .ops = &clk_branch2_ops,
2385 }, 2387 },
2386 }, 2388 },
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index 6df7ff36b416..847dd9dadeca 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -1279,21 +1279,6 @@ static struct clk_branch mmss_misc_cxo_clk = {
1279 }, 1279 },
1280}; 1280};
1281 1281
1282static struct clk_branch mmss_mmagic_axi_clk = {
1283 .halt_reg = 0x506c,
1284 .clkr = {
1285 .enable_reg = 0x506c,
1286 .enable_mask = BIT(0),
1287 .hw.init = &(struct clk_init_data){
1288 .name = "mmss_mmagic_axi_clk",
1289 .parent_names = (const char *[]){ "axi_clk_src" },
1290 .num_parents = 1,
1291 .flags = CLK_SET_RATE_PARENT,
1292 .ops = &clk_branch2_ops,
1293 },
1294 },
1295};
1296
1297static struct clk_branch mmss_mmagic_maxi_clk = { 1282static struct clk_branch mmss_mmagic_maxi_clk = {
1298 .halt_reg = 0x5074, 1283 .halt_reg = 0x5074,
1299 .clkr = { 1284 .clkr = {
@@ -1579,21 +1564,6 @@ static struct clk_branch smmu_video_axi_clk = {
1579 }, 1564 },
1580}; 1565};
1581 1566
1582static struct clk_branch mmagic_bimc_axi_clk = {
1583 .halt_reg = 0x5294,
1584 .clkr = {
1585 .enable_reg = 0x5294,
1586 .enable_mask = BIT(0),
1587 .hw.init = &(struct clk_init_data){
1588 .name = "mmagic_bimc_axi_clk",
1589 .parent_names = (const char *[]){ "axi_clk_src" },
1590 .num_parents = 1,
1591 .flags = CLK_SET_RATE_PARENT,
1592 .ops = &clk_branch2_ops,
1593 },
1594 },
1595};
1596
1597static struct clk_branch mmagic_bimc_noc_cfg_ahb_clk = { 1567static struct clk_branch mmagic_bimc_noc_cfg_ahb_clk = {
1598 .halt_reg = 0x5298, 1568 .halt_reg = 0x5298,
1599 .clkr = { 1569 .clkr = {
@@ -3121,7 +3091,6 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = {
3121 [MMSS_MMAGIC_CFG_AHB_CLK] = &mmss_mmagic_cfg_ahb_clk.clkr, 3091 [MMSS_MMAGIC_CFG_AHB_CLK] = &mmss_mmagic_cfg_ahb_clk.clkr,
3122 [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr, 3092 [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr,
3123 [MMSS_MISC_CXO_CLK] = &mmss_misc_cxo_clk.clkr, 3093 [MMSS_MISC_CXO_CLK] = &mmss_misc_cxo_clk.clkr,
3124 [MMSS_MMAGIC_AXI_CLK] = &mmss_mmagic_axi_clk.clkr,
3125 [MMSS_MMAGIC_MAXI_CLK] = &mmss_mmagic_maxi_clk.clkr, 3094 [MMSS_MMAGIC_MAXI_CLK] = &mmss_mmagic_maxi_clk.clkr,
3126 [MMAGIC_CAMSS_AXI_CLK] = &mmagic_camss_axi_clk.clkr, 3095 [MMAGIC_CAMSS_AXI_CLK] = &mmagic_camss_axi_clk.clkr,
3127 [MMAGIC_CAMSS_NOC_CFG_AHB_CLK] = &mmagic_camss_noc_cfg_ahb_clk.clkr, 3096 [MMAGIC_CAMSS_NOC_CFG_AHB_CLK] = &mmagic_camss_noc_cfg_ahb_clk.clkr,
@@ -3141,7 +3110,6 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = {
3141 [MMAGIC_VIDEO_NOC_CFG_AHB_CLK] = &mmagic_video_noc_cfg_ahb_clk.clkr, 3110 [MMAGIC_VIDEO_NOC_CFG_AHB_CLK] = &mmagic_video_noc_cfg_ahb_clk.clkr,
3142 [SMMU_VIDEO_AHB_CLK] = &smmu_video_ahb_clk.clkr, 3111 [SMMU_VIDEO_AHB_CLK] = &smmu_video_ahb_clk.clkr,
3143 [SMMU_VIDEO_AXI_CLK] = &smmu_video_axi_clk.clkr, 3112 [SMMU_VIDEO_AXI_CLK] = &smmu_video_axi_clk.clkr,
3144 [MMAGIC_BIMC_AXI_CLK] = &mmagic_bimc_axi_clk.clkr,
3145 [MMAGIC_BIMC_NOC_CFG_AHB_CLK] = &mmagic_bimc_noc_cfg_ahb_clk.clkr, 3113 [MMAGIC_BIMC_NOC_CFG_AHB_CLK] = &mmagic_bimc_noc_cfg_ahb_clk.clkr,
3146 [GPU_GX_GFX3D_CLK] = &gpu_gx_gfx3d_clk.clkr, 3114 [GPU_GX_GFX3D_CLK] = &gpu_gx_gfx3d_clk.clkr,
3147 [GPU_GX_RBBMTIMER_CLK] = &gpu_gx_rbbmtimer_clk.clkr, 3115 [GPU_GX_RBBMTIMER_CLK] = &gpu_gx_rbbmtimer_clk.clkr,
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c
index 8b597b9a3804..5093a250650d 100644
--- a/drivers/clk/renesas/clk-mstp.c
+++ b/drivers/clk/renesas/clk-mstp.c
@@ -316,11 +316,10 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np)
316 return; 316 return;
317 317
318 pd->name = np->name; 318 pd->name = np->name;
319
320 pd->flags = GENPD_FLAG_PM_CLK; 319 pd->flags = GENPD_FLAG_PM_CLK;
321 pm_genpd_init(pd, &simple_qos_governor, false);
322 pd->attach_dev = cpg_mstp_attach_dev; 320 pd->attach_dev = cpg_mstp_attach_dev;
323 pd->detach_dev = cpg_mstp_detach_dev; 321 pd->detach_dev = cpg_mstp_detach_dev;
322 pm_genpd_init(pd, &pm_domain_always_on_gov, false);
324 323
325 of_genpd_add_provider_simple(np, pd); 324 of_genpd_add_provider_simple(np, pd);
326} 325}
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index 6af7f5b6e824..ca5519c583d4 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -120,6 +120,7 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
120 DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), 120 DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014),
121 DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), 121 DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250),
122 DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), 122 DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
123 DEF_DIV6P1("csi0", R8A7795_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
123 124
124 DEF_DIV6_RO("osc", R8A7795_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), 125 DEF_DIV6_RO("osc", R8A7795_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8),
125 DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), 126 DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
@@ -190,6 +191,10 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
190 DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), 191 DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4),
191 DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), 192 DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4),
192 DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), 193 DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4),
194 DEF_MOD("csi21", 713, R8A7795_CLK_CSI0),
195 DEF_MOD("csi20", 714, R8A7795_CLK_CSI0),
196 DEF_MOD("csi41", 715, R8A7795_CLK_CSI0),
197 DEF_MOD("csi40", 716, R8A7795_CLK_CSI0),
193 DEF_MOD("du3", 721, R8A7795_CLK_S2D1), 198 DEF_MOD("du3", 721, R8A7795_CLK_S2D1),
194 DEF_MOD("du2", 722, R8A7795_CLK_S2D1), 199 DEF_MOD("du2", 722, R8A7795_CLK_S2D1),
195 DEF_MOD("du1", 723, R8A7795_CLK_S2D1), 200 DEF_MOD("du1", 723, R8A7795_CLK_S2D1),
@@ -197,6 +202,14 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
197 DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), 202 DEF_MOD("lvds", 727, R8A7795_CLK_S2D1),
198 DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), 203 DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI),
199 DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), 204 DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI),
205 DEF_MOD("vin7", 804, R8A7795_CLK_S2D1),
206 DEF_MOD("vin6", 805, R8A7795_CLK_S2D1),
207 DEF_MOD("vin5", 806, R8A7795_CLK_S2D1),
208 DEF_MOD("vin4", 807, R8A7795_CLK_S2D1),
209 DEF_MOD("vin3", 808, R8A7795_CLK_S2D1),
210 DEF_MOD("vin2", 809, R8A7795_CLK_S2D1),
211 DEF_MOD("vin1", 810, R8A7795_CLK_S2D1),
212 DEF_MOD("vin0", 811, R8A7795_CLK_S2D1),
200 DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), 213 DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2),
201 DEF_MOD("sata0", 815, R8A7795_CLK_S3D2), 214 DEF_MOD("sata0", 815, R8A7795_CLK_S3D2),
202 DEF_MOD("gpio7", 905, R8A7795_CLK_CP), 215 DEF_MOD("gpio7", 905, R8A7795_CLK_CP),
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 1f2dc3629f0e..210cd744a7a9 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -493,9 +493,9 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
493 genpd = &pd->genpd; 493 genpd = &pd->genpd;
494 genpd->name = np->name; 494 genpd->name = np->name;
495 genpd->flags = GENPD_FLAG_PM_CLK; 495 genpd->flags = GENPD_FLAG_PM_CLK;
496 pm_genpd_init(genpd, &simple_qos_governor, false);
497 genpd->attach_dev = cpg_mssr_attach_dev; 496 genpd->attach_dev = cpg_mssr_attach_dev;
498 genpd->detach_dev = cpg_mssr_detach_dev; 497 genpd->detach_dev = cpg_mssr_detach_dev;
498 pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
499 cpg_mssr_clk_domain = pd; 499 cpg_mssr_clk_domain = pd;
500 500
501 of_genpd_add_provider_simple(np, genpd); 501 of_genpd_add_provider_simple(np, genpd);
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 80b9a379beb4..f47a2fa962d2 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -15,3 +15,4 @@ obj-y += clk-rk3188.o
15obj-y += clk-rk3228.o 15obj-y += clk-rk3228.o
16obj-y += clk-rk3288.o 16obj-y += clk-rk3288.o
17obj-y += clk-rk3368.o 17obj-y += clk-rk3368.o
18obj-y += clk-rk3399.o
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index 4e73ed5cab58..4bb130cd0062 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -158,12 +158,16 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
158 158
159 writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask, 159 writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
160 reg_data->div_core_shift) | 160 reg_data->div_core_shift) |
161 HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), 161 HIWORD_UPDATE(reg_data->mux_core_alt,
162 reg_data->mux_core_mask,
163 reg_data->mux_core_shift),
162 cpuclk->reg_base + reg_data->core_reg); 164 cpuclk->reg_base + reg_data->core_reg);
163 } else { 165 } else {
164 /* select alternate parent */ 166 /* select alternate parent */
165 writel(HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), 167 writel(HIWORD_UPDATE(reg_data->mux_core_alt,
166 cpuclk->reg_base + reg_data->core_reg); 168 reg_data->mux_core_mask,
169 reg_data->mux_core_shift),
170 cpuclk->reg_base + reg_data->core_reg);
167 } 171 }
168 172
169 spin_unlock_irqrestore(cpuclk->lock, flags); 173 spin_unlock_irqrestore(cpuclk->lock, flags);
@@ -198,7 +202,9 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
198 202
199 writel(HIWORD_UPDATE(0, reg_data->div_core_mask, 203 writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
200 reg_data->div_core_shift) | 204 reg_data->div_core_shift) |
201 HIWORD_UPDATE(0, 1, reg_data->mux_core_shift), 205 HIWORD_UPDATE(reg_data->mux_core_main,
206 reg_data->mux_core_mask,
207 reg_data->mux_core_shift),
202 cpuclk->reg_base + reg_data->core_reg); 208 cpuclk->reg_base + reg_data->core_reg);
203 209
204 if (ndata->old_rate > ndata->new_rate) 210 if (ndata->old_rate > ndata->new_rate)
@@ -252,7 +258,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
252 return ERR_PTR(-ENOMEM); 258 return ERR_PTR(-ENOMEM);
253 259
254 init.name = name; 260 init.name = name;
255 init.parent_names = &parent_names[0]; 261 init.parent_names = &parent_names[reg_data->mux_core_main];
256 init.num_parents = 1; 262 init.num_parents = 1;
257 init.ops = &rockchip_cpuclk_ops; 263 init.ops = &rockchip_cpuclk_ops;
258 264
@@ -270,10 +276,10 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
270 cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb; 276 cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb;
271 cpuclk->hw.init = &init; 277 cpuclk->hw.init = &init;
272 278
273 cpuclk->alt_parent = __clk_lookup(parent_names[1]); 279 cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]);
274 if (!cpuclk->alt_parent) { 280 if (!cpuclk->alt_parent) {
275 pr_err("%s: could not lookup alternate parent\n", 281 pr_err("%s: could not lookup alternate parent: (%d)\n",
276 __func__); 282 __func__, reg_data->mux_core_alt);
277 ret = -EINVAL; 283 ret = -EINVAL;
278 goto free_cpuclk; 284 goto free_cpuclk;
279 } 285 }
@@ -285,10 +291,11 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
285 goto free_cpuclk; 291 goto free_cpuclk;
286 } 292 }
287 293
288 clk = __clk_lookup(parent_names[0]); 294 clk = __clk_lookup(parent_names[reg_data->mux_core_main]);
289 if (!clk) { 295 if (!clk) {
290 pr_err("%s: could not lookup parent clock %s\n", 296 pr_err("%s: could not lookup parent clock: (%d) %s\n",
291 __func__, parent_names[0]); 297 __func__, reg_data->mux_core_main,
298 parent_names[reg_data->mux_core_main]);
292 ret = -EINVAL; 299 ret = -EINVAL;
293 goto free_alt_parent; 300 goto free_alt_parent;
294 } 301 }
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index e0dc7e83403a..bc856f21f6b2 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -123,7 +123,8 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
123 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 123 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
124 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 124 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
125 raw_value |= nineties; 125 raw_value |= nineties;
126 writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg); 126 writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift),
127 mmc_clock->reg);
127 128
128 pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n", 129 pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
129 clk_hw_get_name(hw), degrees, delay_num, 130 clk_hw_get_name(hw), degrees, delay_num,
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 5de797e34d54..db81e454166b 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -46,6 +46,8 @@ struct rockchip_clk_pll {
46 const struct rockchip_pll_rate_table *rate_table; 46 const struct rockchip_pll_rate_table *rate_table;
47 unsigned int rate_count; 47 unsigned int rate_count;
48 spinlock_t *lock; 48 spinlock_t *lock;
49
50 struct rockchip_clk_provider *ctx;
49}; 51};
50 52
51#define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw) 53#define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
@@ -90,15 +92,10 @@ static long rockchip_pll_round_rate(struct clk_hw *hw,
90 */ 92 */
91static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) 93static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
92{ 94{
93 struct regmap *grf = rockchip_clk_get_grf(); 95 struct regmap *grf = pll->ctx->grf;
94 unsigned int val; 96 unsigned int val;
95 int delay = 24000000, ret; 97 int delay = 24000000, ret;
96 98
97 if (IS_ERR(grf)) {
98 pr_err("%s: grf regmap not available\n", __func__);
99 return PTR_ERR(grf);
100 }
101
102 while (delay > 0) { 99 while (delay > 0) {
103 ret = regmap_read(grf, pll->lock_offset, &val); 100 ret = regmap_read(grf, pll->lock_offset, &val);
104 if (ret) { 101 if (ret) {
@@ -234,7 +231,7 @@ static int rockchip_rk3036_pll_set_params(struct rockchip_clk_pll *pll,
234 /* wait for the pll to lock */ 231 /* wait for the pll to lock */
235 ret = rockchip_pll_wait_lock(pll); 232 ret = rockchip_pll_wait_lock(pll);
236 if (ret) { 233 if (ret) {
237 pr_warn("%s: pll update unsucessful, trying to restore old params\n", 234 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
238 __func__); 235 __func__);
239 rockchip_rk3036_pll_set_params(pll, &cur); 236 rockchip_rk3036_pll_set_params(pll, &cur);
240 } 237 }
@@ -250,17 +247,9 @@ static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
250{ 247{
251 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 248 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
252 const struct rockchip_pll_rate_table *rate; 249 const struct rockchip_pll_rate_table *rate;
253 unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
254 struct regmap *grf = rockchip_clk_get_grf();
255 250
256 if (IS_ERR(grf)) { 251 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
257 pr_debug("%s: grf regmap not available, aborting rate change\n", 252 __func__, __clk_get_name(hw->clk), drate, prate);
258 __func__);
259 return PTR_ERR(grf);
260 }
261
262 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
263 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
264 253
265 /* Get required rate settings from table */ 254 /* Get required rate settings from table */
266 rate = rockchip_get_pll_settings(pll, drate); 255 rate = rockchip_get_pll_settings(pll, drate);
@@ -473,7 +462,7 @@ static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
473 /* wait for the pll to lock */ 462 /* wait for the pll to lock */
474 ret = rockchip_pll_wait_lock(pll); 463 ret = rockchip_pll_wait_lock(pll);
475 if (ret) { 464 if (ret) {
476 pr_warn("%s: pll update unsucessful, trying to restore old params\n", 465 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
477 __func__); 466 __func__);
478 rockchip_rk3066_pll_set_params(pll, &cur); 467 rockchip_rk3066_pll_set_params(pll, &cur);
479 } 468 }
@@ -489,17 +478,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
489{ 478{
490 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 479 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
491 const struct rockchip_pll_rate_table *rate; 480 const struct rockchip_pll_rate_table *rate;
492 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
493 struct regmap *grf = rockchip_clk_get_grf();
494 481
495 if (IS_ERR(grf)) { 482 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
496 pr_debug("%s: grf regmap not available, aborting rate change\n", 483 __func__, clk_hw_get_name(hw), drate, prate);
497 __func__);
498 return PTR_ERR(grf);
499 }
500
501 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
502 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
503 484
504 /* Get required rate settings from table */ 485 /* Get required rate settings from table */
505 rate = rockchip_get_pll_settings(pll, drate); 486 rate = rockchip_get_pll_settings(pll, drate);
@@ -563,11 +544,6 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
563 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb); 544 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
564 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf 545 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
565 || rate->nb != cur.nb) { 546 || rate->nb != cur.nb) {
566 struct regmap *grf = rockchip_clk_get_grf();
567
568 if (IS_ERR(grf))
569 return;
570
571 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 547 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
572 __func__, clk_hw_get_name(hw)); 548 __func__, clk_hw_get_name(hw));
573 rockchip_rk3066_pll_set_params(pll, rate); 549 rockchip_rk3066_pll_set_params(pll, rate);
@@ -591,16 +567,277 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
591 .init = rockchip_rk3066_pll_init, 567 .init = rockchip_rk3066_pll_init,
592}; 568};
593 569
570/**
571 * PLL used in RK3399
572 */
573
574#define RK3399_PLLCON(i) (i * 0x4)
575#define RK3399_PLLCON0_FBDIV_MASK 0xfff
576#define RK3399_PLLCON0_FBDIV_SHIFT 0
577#define RK3399_PLLCON1_REFDIV_MASK 0x3f
578#define RK3399_PLLCON1_REFDIV_SHIFT 0
579#define RK3399_PLLCON1_POSTDIV1_MASK 0x7
580#define RK3399_PLLCON1_POSTDIV1_SHIFT 8
581#define RK3399_PLLCON1_POSTDIV2_MASK 0x7
582#define RK3399_PLLCON1_POSTDIV2_SHIFT 12
583#define RK3399_PLLCON2_FRAC_MASK 0xffffff
584#define RK3399_PLLCON2_FRAC_SHIFT 0
585#define RK3399_PLLCON2_LOCK_STATUS BIT(31)
586#define RK3399_PLLCON3_PWRDOWN BIT(0)
587#define RK3399_PLLCON3_DSMPD_MASK 0x1
588#define RK3399_PLLCON3_DSMPD_SHIFT 3
589
590static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll)
591{
592 u32 pllcon;
593 int delay = 24000000;
594
595 /* poll check the lock status in rk3399 xPLLCON2 */
596 while (delay > 0) {
597 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
598 if (pllcon & RK3399_PLLCON2_LOCK_STATUS)
599 return 0;
600
601 delay--;
602 }
603
604 pr_err("%s: timeout waiting for pll to lock\n", __func__);
605 return -ETIMEDOUT;
606}
607
608static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll,
609 struct rockchip_pll_rate_table *rate)
610{
611 u32 pllcon;
612
613 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0));
614 rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT)
615 & RK3399_PLLCON0_FBDIV_MASK);
616
617 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1));
618 rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT)
619 & RK3399_PLLCON1_REFDIV_MASK);
620 rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT)
621 & RK3399_PLLCON1_POSTDIV1_MASK);
622 rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT)
623 & RK3399_PLLCON1_POSTDIV2_MASK);
624
625 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
626 rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT)
627 & RK3399_PLLCON2_FRAC_MASK);
628
629 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3));
630 rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT)
631 & RK3399_PLLCON3_DSMPD_MASK);
632}
633
634static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw,
635 unsigned long prate)
636{
637 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
638 struct rockchip_pll_rate_table cur;
639 u64 rate64 = prate;
640
641 rockchip_rk3399_pll_get_params(pll, &cur);
642
643 rate64 *= cur.fbdiv;
644 do_div(rate64, cur.refdiv);
645
646 if (cur.dsmpd == 0) {
647 /* fractional mode */
648 u64 frac_rate64 = prate * cur.frac;
649
650 do_div(frac_rate64, cur.refdiv);
651 rate64 += frac_rate64 >> 24;
652 }
653
654 do_div(rate64, cur.postdiv1);
655 do_div(rate64, cur.postdiv2);
656
657 return (unsigned long)rate64;
658}
659
660static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll,
661 const struct rockchip_pll_rate_table *rate)
662{
663 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
664 struct clk_mux *pll_mux = &pll->pll_mux;
665 struct rockchip_pll_rate_table cur;
666 u32 pllcon;
667 int rate_change_remuxed = 0;
668 int cur_parent;
669 int ret;
670
671 pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
672 __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv,
673 rate->postdiv2, rate->dsmpd, rate->frac);
674
675 rockchip_rk3399_pll_get_params(pll, &cur);
676 cur.rate = 0;
677
678 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
679 if (cur_parent == PLL_MODE_NORM) {
680 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
681 rate_change_remuxed = 1;
682 }
683
684 /* update pll values */
685 writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK,
686 RK3399_PLLCON0_FBDIV_SHIFT),
687 pll->reg_base + RK3399_PLLCON(0));
688
689 writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK,
690 RK3399_PLLCON1_REFDIV_SHIFT) |
691 HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK,
692 RK3399_PLLCON1_POSTDIV1_SHIFT) |
693 HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK,
694 RK3399_PLLCON1_POSTDIV2_SHIFT),
695 pll->reg_base + RK3399_PLLCON(1));
696
697 /* xPLL CON2 is not HIWORD_MASK */
698 pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2));
699 pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
700 pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
701 writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2));
702
703 writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK,
704 RK3399_PLLCON3_DSMPD_SHIFT),
705 pll->reg_base + RK3399_PLLCON(3));
706
707 /* wait for the pll to lock */
708 ret = rockchip_rk3399_pll_wait_lock(pll);
709 if (ret) {
710 pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
711 __func__);
712 rockchip_rk3399_pll_set_params(pll, &cur);
713 }
714
715 if (rate_change_remuxed)
716 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
717
718 return ret;
719}
720
721static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate,
722 unsigned long prate)
723{
724 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
725 const struct rockchip_pll_rate_table *rate;
726
727 pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
728 __func__, __clk_get_name(hw->clk), drate, prate);
729
730 /* Get required rate settings from table */
731 rate = rockchip_get_pll_settings(pll, drate);
732 if (!rate) {
733 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
734 drate, __clk_get_name(hw->clk));
735 return -EINVAL;
736 }
737
738 return rockchip_rk3399_pll_set_params(pll, rate);
739}
740
741static int rockchip_rk3399_pll_enable(struct clk_hw *hw)
742{
743 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
744
745 writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0),
746 pll->reg_base + RK3399_PLLCON(3));
747
748 return 0;
749}
750
751static void rockchip_rk3399_pll_disable(struct clk_hw *hw)
752{
753 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
754
755 writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN,
756 RK3399_PLLCON3_PWRDOWN, 0),
757 pll->reg_base + RK3399_PLLCON(3));
758}
759
760static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
761{
762 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
763 u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3));
764
765 return !(pllcon & RK3399_PLLCON3_PWRDOWN);
766}
767
768static void rockchip_rk3399_pll_init(struct clk_hw *hw)
769{
770 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
771 const struct rockchip_pll_rate_table *rate;
772 struct rockchip_pll_rate_table cur;
773 unsigned long drate;
774
775 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
776 return;
777
778 drate = clk_hw_get_rate(hw);
779 rate = rockchip_get_pll_settings(pll, drate);
780
781 /* when no rate setting for the current rate, rely on clk_set_rate */
782 if (!rate)
783 return;
784
785 rockchip_rk3399_pll_get_params(pll, &cur);
786
787 pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk),
788 drate);
789 pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
790 cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2,
791 cur.dsmpd, cur.frac);
792 pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
793 rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2,
794 rate->dsmpd, rate->frac);
795
796 if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
797 rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
798 rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) {
799 struct clk *parent = clk_get_parent(hw->clk);
800
801 if (!parent) {
802 pr_warn("%s: parent of %s not available\n",
803 __func__, __clk_get_name(hw->clk));
804 return;
805 }
806
807 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
808 __func__, __clk_get_name(hw->clk));
809 rockchip_rk3399_pll_set_params(pll, rate);
810 }
811}
812
813static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
814 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
815 .enable = rockchip_rk3399_pll_enable,
816 .disable = rockchip_rk3399_pll_disable,
817 .is_enabled = rockchip_rk3399_pll_is_enabled,
818};
819
820static const struct clk_ops rockchip_rk3399_pll_clk_ops = {
821 .recalc_rate = rockchip_rk3399_pll_recalc_rate,
822 .round_rate = rockchip_pll_round_rate,
823 .set_rate = rockchip_rk3399_pll_set_rate,
824 .enable = rockchip_rk3399_pll_enable,
825 .disable = rockchip_rk3399_pll_disable,
826 .is_enabled = rockchip_rk3399_pll_is_enabled,
827 .init = rockchip_rk3399_pll_init,
828};
829
594/* 830/*
595 * Common registering of pll clocks 831 * Common registering of pll clocks
596 */ 832 */
597 833
598struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 834struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
835 enum rockchip_pll_type pll_type,
599 const char *name, const char *const *parent_names, 836 const char *name, const char *const *parent_names,
600 u8 num_parents, void __iomem *base, int con_offset, 837 u8 num_parents, int con_offset, int grf_lock_offset,
601 int grf_lock_offset, int lock_shift, int mode_offset, 838 int lock_shift, int mode_offset, int mode_shift,
602 int mode_shift, struct rockchip_pll_rate_table *rate_table, 839 struct rockchip_pll_rate_table *rate_table,
603 u8 clk_pll_flags, spinlock_t *lock) 840 u8 clk_pll_flags)
604{ 841{
605 const char *pll_parents[3]; 842 const char *pll_parents[3];
606 struct clk_init_data init; 843 struct clk_init_data init;
@@ -624,14 +861,16 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
624 /* create the mux on top of the real pll */ 861 /* create the mux on top of the real pll */
625 pll->pll_mux_ops = &clk_mux_ops; 862 pll->pll_mux_ops = &clk_mux_ops;
626 pll_mux = &pll->pll_mux; 863 pll_mux = &pll->pll_mux;
627 pll_mux->reg = base + mode_offset; 864 pll_mux->reg = ctx->reg_base + mode_offset;
628 pll_mux->shift = mode_shift; 865 pll_mux->shift = mode_shift;
629 pll_mux->mask = PLL_MODE_MASK; 866 pll_mux->mask = PLL_MODE_MASK;
630 pll_mux->flags = 0; 867 pll_mux->flags = 0;
631 pll_mux->lock = lock; 868 pll_mux->lock = &ctx->lock;
632 pll_mux->hw.init = &init; 869 pll_mux->hw.init = &init;
633 870
634 if (pll_type == pll_rk3036 || pll_type == pll_rk3066) 871 if (pll_type == pll_rk3036 ||
872 pll_type == pll_rk3066 ||
873 pll_type == pll_rk3399)
635 pll_mux->flags |= CLK_MUX_HIWORD_MASK; 874 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
636 875
637 /* the actual muxing is xin24m, pll-output, xin32k */ 876 /* the actual muxing is xin24m, pll-output, xin32k */
@@ -677,17 +916,23 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
677 916
678 switch (pll_type) { 917 switch (pll_type) {
679 case pll_rk3036: 918 case pll_rk3036:
680 if (!pll->rate_table) 919 if (!pll->rate_table || IS_ERR(ctx->grf))
681 init.ops = &rockchip_rk3036_pll_clk_norate_ops; 920 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
682 else 921 else
683 init.ops = &rockchip_rk3036_pll_clk_ops; 922 init.ops = &rockchip_rk3036_pll_clk_ops;
684 break; 923 break;
685 case pll_rk3066: 924 case pll_rk3066:
686 if (!pll->rate_table) 925 if (!pll->rate_table || IS_ERR(ctx->grf))
687 init.ops = &rockchip_rk3066_pll_clk_norate_ops; 926 init.ops = &rockchip_rk3066_pll_clk_norate_ops;
688 else 927 else
689 init.ops = &rockchip_rk3066_pll_clk_ops; 928 init.ops = &rockchip_rk3066_pll_clk_ops;
690 break; 929 break;
930 case pll_rk3399:
931 if (!pll->rate_table)
932 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
933 else
934 init.ops = &rockchip_rk3399_pll_clk_ops;
935 break;
691 default: 936 default:
692 pr_warn("%s: Unknown pll type for pll clk %s\n", 937 pr_warn("%s: Unknown pll type for pll clk %s\n",
693 __func__, name); 938 __func__, name);
@@ -695,11 +940,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
695 940
696 pll->hw.init = &init; 941 pll->hw.init = &init;
697 pll->type = pll_type; 942 pll->type = pll_type;
698 pll->reg_base = base + con_offset; 943 pll->reg_base = ctx->reg_base + con_offset;
699 pll->lock_offset = grf_lock_offset; 944 pll->lock_offset = grf_lock_offset;
700 pll->lock_shift = lock_shift; 945 pll->lock_shift = lock_shift;
701 pll->flags = clk_pll_flags; 946 pll->flags = clk_pll_flags;
702 pll->lock = lock; 947 pll->lock = &ctx->lock;
948 pll->ctx = ctx;
703 949
704 pll_clk = clk_register(NULL, &pll->hw); 950 pll_clk = clk_register(NULL, &pll->hw);
705 if (IS_ERR(pll_clk)) { 951 if (IS_ERR(pll_clk)) {
diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c
index 7cdb2d61f3e0..924f560dcf80 100644
--- a/drivers/clk/rockchip/clk-rk3036.c
+++ b/drivers/clk/rockchip/clk-rk3036.c
@@ -113,7 +113,10 @@ static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
113 .core_reg = RK2928_CLKSEL_CON(0), 113 .core_reg = RK2928_CLKSEL_CON(0),
114 .div_core_shift = 0, 114 .div_core_shift = 0,
115 .div_core_mask = 0x1f, 115 .div_core_mask = 0x1f,
116 .mux_core_alt = 1,
117 .mux_core_main = 0,
116 .mux_core_shift = 7, 118 .mux_core_shift = 7,
119 .mux_core_mask = 0x1,
117}; 120};
118 121
119PNAME(mux_pll_p) = { "xin24m", "xin24m" }; 122PNAME(mux_pll_p) = { "xin24m", "xin24m" };
@@ -437,6 +440,7 @@ static const char *const rk3036_critical_clocks[] __initconst = {
437 440
438static void __init rk3036_clk_init(struct device_node *np) 441static void __init rk3036_clk_init(struct device_node *np)
439{ 442{
443 struct rockchip_clk_provider *ctx;
440 void __iomem *reg_base; 444 void __iomem *reg_base;
441 struct clk *clk; 445 struct clk *clk;
442 446
@@ -446,22 +450,27 @@ static void __init rk3036_clk_init(struct device_node *np)
446 return; 450 return;
447 } 451 }
448 452
449 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 453 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
454 if (IS_ERR(ctx)) {
455 pr_err("%s: rockchip clk init failed\n", __func__);
456 iounmap(reg_base);
457 return;
458 }
450 459
451 clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); 460 clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
452 if (IS_ERR(clk)) 461 if (IS_ERR(clk))
453 pr_warn("%s: could not register clock usb480m: %ld\n", 462 pr_warn("%s: could not register clock usb480m: %ld\n",
454 __func__, PTR_ERR(clk)); 463 __func__, PTR_ERR(clk));
455 464
456 rockchip_clk_register_plls(rk3036_pll_clks, 465 rockchip_clk_register_plls(ctx, rk3036_pll_clks,
457 ARRAY_SIZE(rk3036_pll_clks), 466 ARRAY_SIZE(rk3036_pll_clks),
458 RK3036_GRF_SOC_STATUS0); 467 RK3036_GRF_SOC_STATUS0);
459 rockchip_clk_register_branches(rk3036_clk_branches, 468 rockchip_clk_register_branches(ctx, rk3036_clk_branches,
460 ARRAY_SIZE(rk3036_clk_branches)); 469 ARRAY_SIZE(rk3036_clk_branches));
461 rockchip_clk_protect_critical(rk3036_critical_clocks, 470 rockchip_clk_protect_critical(rk3036_critical_clocks,
462 ARRAY_SIZE(rk3036_critical_clocks)); 471 ARRAY_SIZE(rk3036_critical_clocks));
463 472
464 rockchip_clk_register_armclk(ARMCLK, "armclk", 473 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
465 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 474 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
466 &rk3036_cpuclk_data, rk3036_cpuclk_rates, 475 &rk3036_cpuclk_data, rk3036_cpuclk_rates,
467 ARRAY_SIZE(rk3036_cpuclk_rates)); 476 ARRAY_SIZE(rk3036_cpuclk_rates));
@@ -469,6 +478,8 @@ static void __init rk3036_clk_init(struct device_node *np)
469 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 478 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
470 ROCKCHIP_SOFTRST_HIWORD_MASK); 479 ROCKCHIP_SOFTRST_HIWORD_MASK);
471 480
472 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); 481 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
482
483 rockchip_clk_of_add_provider(np, ctx);
473} 484}
474CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init); 485CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 40bab3901491..d0e722a0e8cf 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -155,7 +155,10 @@ static const struct rockchip_cpuclk_reg_data rk3066_cpuclk_data = {
155 .core_reg = RK2928_CLKSEL_CON(0), 155 .core_reg = RK2928_CLKSEL_CON(0),
156 .div_core_shift = 0, 156 .div_core_shift = 0,
157 .div_core_mask = 0x1f, 157 .div_core_mask = 0x1f,
158 .mux_core_alt = 1,
159 .mux_core_main = 0,
158 .mux_core_shift = 8, 160 .mux_core_shift = 8,
161 .mux_core_mask = 0x1,
159}; 162};
160 163
161#define RK3188_DIV_ACLK_CORE_MASK 0x7 164#define RK3188_DIV_ACLK_CORE_MASK 0x7
@@ -191,7 +194,10 @@ static const struct rockchip_cpuclk_reg_data rk3188_cpuclk_data = {
191 .core_reg = RK2928_CLKSEL_CON(0), 194 .core_reg = RK2928_CLKSEL_CON(0),
192 .div_core_shift = 9, 195 .div_core_shift = 9,
193 .div_core_mask = 0x1f, 196 .div_core_mask = 0x1f,
197 .mux_core_alt = 1,
198 .mux_core_main = 0,
194 .mux_core_shift = 8, 199 .mux_core_shift = 8,
200 .mux_core_mask = 0x1,
195}; 201};
196 202
197PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 203PNAME(mux_pll_p) = { "xin24m", "xin32k" };
@@ -753,57 +759,75 @@ static const char *const rk3188_critical_clocks[] __initconst = {
753 "hclk_cpubus" 759 "hclk_cpubus"
754}; 760};
755 761
756static void __init rk3188_common_clk_init(struct device_node *np) 762static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np)
757{ 763{
764 struct rockchip_clk_provider *ctx;
758 void __iomem *reg_base; 765 void __iomem *reg_base;
759 766
760 reg_base = of_iomap(np, 0); 767 reg_base = of_iomap(np, 0);
761 if (!reg_base) { 768 if (!reg_base) {
762 pr_err("%s: could not map cru region\n", __func__); 769 pr_err("%s: could not map cru region\n", __func__);
763 return; 770 return ERR_PTR(-ENOMEM);
764 } 771 }
765 772
766 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 773 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
774 if (IS_ERR(ctx)) {
775 pr_err("%s: rockchip clk init failed\n", __func__);
776 iounmap(reg_base);
777 return ERR_PTR(-ENOMEM);
778 }
767 779
768 rockchip_clk_register_branches(common_clk_branches, 780 rockchip_clk_register_branches(ctx, common_clk_branches,
769 ARRAY_SIZE(common_clk_branches)); 781 ARRAY_SIZE(common_clk_branches));
770 782
771 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 783 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
772 ROCKCHIP_SOFTRST_HIWORD_MASK); 784 ROCKCHIP_SOFTRST_HIWORD_MASK);
773 785
774 rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); 786 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
787
788 return ctx;
775} 789}
776 790
777static void __init rk3066a_clk_init(struct device_node *np) 791static void __init rk3066a_clk_init(struct device_node *np)
778{ 792{
779 rk3188_common_clk_init(np); 793 struct rockchip_clk_provider *ctx;
780 rockchip_clk_register_plls(rk3066_pll_clks, 794
795 ctx = rk3188_common_clk_init(np);
796 if (IS_ERR(ctx))
797 return;
798
799 rockchip_clk_register_plls(ctx, rk3066_pll_clks,
781 ARRAY_SIZE(rk3066_pll_clks), 800 ARRAY_SIZE(rk3066_pll_clks),
782 RK3066_GRF_SOC_STATUS); 801 RK3066_GRF_SOC_STATUS);
783 rockchip_clk_register_branches(rk3066a_clk_branches, 802 rockchip_clk_register_branches(ctx, rk3066a_clk_branches,
784 ARRAY_SIZE(rk3066a_clk_branches)); 803 ARRAY_SIZE(rk3066a_clk_branches));
785 rockchip_clk_register_armclk(ARMCLK, "armclk", 804 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
786 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 805 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
787 &rk3066_cpuclk_data, rk3066_cpuclk_rates, 806 &rk3066_cpuclk_data, rk3066_cpuclk_rates,
788 ARRAY_SIZE(rk3066_cpuclk_rates)); 807 ARRAY_SIZE(rk3066_cpuclk_rates));
789 rockchip_clk_protect_critical(rk3188_critical_clocks, 808 rockchip_clk_protect_critical(rk3188_critical_clocks,
790 ARRAY_SIZE(rk3188_critical_clocks)); 809 ARRAY_SIZE(rk3188_critical_clocks));
810 rockchip_clk_of_add_provider(np, ctx);
791} 811}
792CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); 812CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
793 813
794static void __init rk3188a_clk_init(struct device_node *np) 814static void __init rk3188a_clk_init(struct device_node *np)
795{ 815{
816 struct rockchip_clk_provider *ctx;
796 struct clk *clk1, *clk2; 817 struct clk *clk1, *clk2;
797 unsigned long rate; 818 unsigned long rate;
798 int ret; 819 int ret;
799 820
800 rk3188_common_clk_init(np); 821 ctx = rk3188_common_clk_init(np);
801 rockchip_clk_register_plls(rk3188_pll_clks, 822 if (IS_ERR(ctx))
823 return;
824
825 rockchip_clk_register_plls(ctx, rk3188_pll_clks,
802 ARRAY_SIZE(rk3188_pll_clks), 826 ARRAY_SIZE(rk3188_pll_clks),
803 RK3188_GRF_SOC_STATUS); 827 RK3188_GRF_SOC_STATUS);
804 rockchip_clk_register_branches(rk3188_clk_branches, 828 rockchip_clk_register_branches(ctx, rk3188_clk_branches,
805 ARRAY_SIZE(rk3188_clk_branches)); 829 ARRAY_SIZE(rk3188_clk_branches));
806 rockchip_clk_register_armclk(ARMCLK, "armclk", 830 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
807 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 831 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
808 &rk3188_cpuclk_data, rk3188_cpuclk_rates, 832 &rk3188_cpuclk_data, rk3188_cpuclk_rates,
809 ARRAY_SIZE(rk3188_cpuclk_rates)); 833 ARRAY_SIZE(rk3188_cpuclk_rates));
@@ -827,6 +851,7 @@ static void __init rk3188a_clk_init(struct device_node *np)
827 851
828 rockchip_clk_protect_critical(rk3188_critical_clocks, 852 rockchip_clk_protect_critical(rk3188_critical_clocks,
829 ARRAY_SIZE(rk3188_critical_clocks)); 853 ARRAY_SIZE(rk3188_critical_clocks));
854 rockchip_clk_of_add_provider(np, ctx);
830} 855}
831CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); 856CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
832 857
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index 7702d2855e9c..016bdb0b793a 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -111,7 +111,10 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = {
111 .core_reg = RK2928_CLKSEL_CON(0), 111 .core_reg = RK2928_CLKSEL_CON(0),
112 .div_core_shift = 0, 112 .div_core_shift = 0,
113 .div_core_mask = 0x1f, 113 .div_core_mask = 0x1f,
114 .mux_core_alt = 1,
115 .mux_core_main = 0,
114 .mux_core_shift = 6, 116 .mux_core_shift = 6,
117 .mux_core_mask = 0x1,
115}; 118};
116 119
117PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; 120PNAME(mux_pll_p) = { "clk_24m", "xin24m" };
@@ -625,6 +628,7 @@ static const char *const rk3228_critical_clocks[] __initconst = {
625 628
626static void __init rk3228_clk_init(struct device_node *np) 629static void __init rk3228_clk_init(struct device_node *np)
627{ 630{
631 struct rockchip_clk_provider *ctx;
628 void __iomem *reg_base; 632 void __iomem *reg_base;
629 633
630 reg_base = of_iomap(np, 0); 634 reg_base = of_iomap(np, 0);
@@ -633,17 +637,22 @@ static void __init rk3228_clk_init(struct device_node *np)
633 return; 637 return;
634 } 638 }
635 639
636 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 640 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
641 if (IS_ERR(ctx)) {
642 pr_err("%s: rockchip clk init failed\n", __func__);
643 iounmap(reg_base);
644 return;
645 }
637 646
638 rockchip_clk_register_plls(rk3228_pll_clks, 647 rockchip_clk_register_plls(ctx, rk3228_pll_clks,
639 ARRAY_SIZE(rk3228_pll_clks), 648 ARRAY_SIZE(rk3228_pll_clks),
640 RK3228_GRF_SOC_STATUS0); 649 RK3228_GRF_SOC_STATUS0);
641 rockchip_clk_register_branches(rk3228_clk_branches, 650 rockchip_clk_register_branches(ctx, rk3228_clk_branches,
642 ARRAY_SIZE(rk3228_clk_branches)); 651 ARRAY_SIZE(rk3228_clk_branches));
643 rockchip_clk_protect_critical(rk3228_critical_clocks, 652 rockchip_clk_protect_critical(rk3228_critical_clocks,
644 ARRAY_SIZE(rk3228_critical_clocks)); 653 ARRAY_SIZE(rk3228_critical_clocks));
645 654
646 rockchip_clk_register_armclk(ARMCLK, "armclk", 655 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
647 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 656 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
648 &rk3228_cpuclk_data, rk3228_cpuclk_rates, 657 &rk3228_cpuclk_data, rk3228_cpuclk_rates,
649 ARRAY_SIZE(rk3228_cpuclk_rates)); 658 ARRAY_SIZE(rk3228_cpuclk_rates));
@@ -651,6 +660,8 @@ static void __init rk3228_clk_init(struct device_node *np)
651 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 660 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
652 ROCKCHIP_SOFTRST_HIWORD_MASK); 661 ROCKCHIP_SOFTRST_HIWORD_MASK);
653 662
654 rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL); 663 rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, NULL);
664
665 rockchip_clk_of_add_provider(np, ctx);
655} 666}
656CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init); 667CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 3cb72163a512..39af05a589b3 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -165,7 +165,10 @@ static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {
165 .core_reg = RK3288_CLKSEL_CON(0), 165 .core_reg = RK3288_CLKSEL_CON(0),
166 .div_core_shift = 8, 166 .div_core_shift = 8,
167 .div_core_mask = 0x1f, 167 .div_core_mask = 0x1f,
168 .mux_core_alt = 1,
169 .mux_core_main = 0,
168 .mux_core_shift = 15, 170 .mux_core_shift = 15,
171 .mux_core_mask = 0x1,
169}; 172};
170 173
171PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 174PNAME(mux_pll_p) = { "xin24m", "xin32k" };
@@ -878,6 +881,7 @@ static struct syscore_ops rk3288_clk_syscore_ops = {
878 881
879static void __init rk3288_clk_init(struct device_node *np) 882static void __init rk3288_clk_init(struct device_node *np)
880{ 883{
884 struct rockchip_clk_provider *ctx;
881 struct clk *clk; 885 struct clk *clk;
882 886
883 rk3288_cru_base = of_iomap(np, 0); 887 rk3288_cru_base = of_iomap(np, 0);
@@ -886,7 +890,12 @@ static void __init rk3288_clk_init(struct device_node *np)
886 return; 890 return;
887 } 891 }
888 892
889 rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); 893 ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS);
894 if (IS_ERR(ctx)) {
895 pr_err("%s: rockchip clk init failed\n", __func__);
896 iounmap(rk3288_cru_base);
897 return;
898 }
890 899
891 /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ 900 /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
892 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); 901 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)
894 pr_warn("%s: could not register clock pclk_wdt: %ld\n", 903 pr_warn("%s: could not register clock pclk_wdt: %ld\n",
895 __func__, PTR_ERR(clk)); 904 __func__, PTR_ERR(clk));
896 else 905 else
897 rockchip_clk_add_lookup(clk, PCLK_WDT); 906 rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
898 907
899 rockchip_clk_register_plls(rk3288_pll_clks, 908 rockchip_clk_register_plls(ctx, rk3288_pll_clks,
900 ARRAY_SIZE(rk3288_pll_clks), 909 ARRAY_SIZE(rk3288_pll_clks),
901 RK3288_GRF_SOC_STATUS1); 910 RK3288_GRF_SOC_STATUS1);
902 rockchip_clk_register_branches(rk3288_clk_branches, 911 rockchip_clk_register_branches(ctx, rk3288_clk_branches,
903 ARRAY_SIZE(rk3288_clk_branches)); 912 ARRAY_SIZE(rk3288_clk_branches));
904 rockchip_clk_protect_critical(rk3288_critical_clocks, 913 rockchip_clk_protect_critical(rk3288_critical_clocks,
905 ARRAY_SIZE(rk3288_critical_clocks)); 914 ARRAY_SIZE(rk3288_critical_clocks));
906 915
907 rockchip_clk_register_armclk(ARMCLK, "armclk", 916 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
908 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 917 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
909 &rk3288_cpuclk_data, rk3288_cpuclk_rates, 918 &rk3288_cpuclk_data, rk3288_cpuclk_rates,
910 ARRAY_SIZE(rk3288_cpuclk_rates)); 919 ARRAY_SIZE(rk3288_cpuclk_rates));
@@ -913,8 +922,10 @@ static void __init rk3288_clk_init(struct device_node *np)
913 rk3288_cru_base + RK3288_SOFTRST_CON(0), 922 rk3288_cru_base + RK3288_SOFTRST_CON(0),
914 ROCKCHIP_SOFTRST_HIWORD_MASK); 923 ROCKCHIP_SOFTRST_HIWORD_MASK);
915 924
916 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST, 925 rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST,
917 rk3288_clk_shutdown); 926 rk3288_clk_shutdown);
918 register_syscore_ops(&rk3288_clk_syscore_ops); 927 register_syscore_ops(&rk3288_clk_syscore_ops);
928
929 rockchip_clk_of_add_provider(np, ctx);
919} 930}
920CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); 931CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c
index a2bb12200465..6cb474c593e7 100644
--- a/drivers/clk/rockchip/clk-rk3368.c
+++ b/drivers/clk/rockchip/clk-rk3368.c
@@ -165,14 +165,20 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = {
165 .core_reg = RK3368_CLKSEL_CON(0), 165 .core_reg = RK3368_CLKSEL_CON(0),
166 .div_core_shift = 0, 166 .div_core_shift = 0,
167 .div_core_mask = 0x1f, 167 .div_core_mask = 0x1f,
168 .mux_core_alt = 1,
169 .mux_core_main = 0,
168 .mux_core_shift = 7, 170 .mux_core_shift = 7,
171 .mux_core_mask = 0x1,
169}; 172};
170 173
171static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { 174static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = {
172 .core_reg = RK3368_CLKSEL_CON(2), 175 .core_reg = RK3368_CLKSEL_CON(2),
173 .div_core_shift = 0, 176 .div_core_shift = 0,
177 .mux_core_alt = 1,
178 .mux_core_main = 0,
174 .div_core_mask = 0x1f, 179 .div_core_mask = 0x1f,
175 .mux_core_shift = 7, 180 .mux_core_shift = 7,
181 .mux_core_mask = 0x1,
176}; 182};
177 183
178#define RK3368_DIV_ACLKM_MASK 0x1f 184#define RK3368_DIV_ACLKM_MASK 0x1f
@@ -856,6 +862,7 @@ static const char *const rk3368_critical_clocks[] __initconst = {
856 862
857static void __init rk3368_clk_init(struct device_node *np) 863static void __init rk3368_clk_init(struct device_node *np)
858{ 864{
865 struct rockchip_clk_provider *ctx;
859 void __iomem *reg_base; 866 void __iomem *reg_base;
860 struct clk *clk; 867 struct clk *clk;
861 868
@@ -865,7 +872,12 @@ static void __init rk3368_clk_init(struct device_node *np)
865 return; 872 return;
866 } 873 }
867 874
868 rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 875 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
876 if (IS_ERR(ctx)) {
877 pr_err("%s: rockchip clk init failed\n", __func__);
878 iounmap(reg_base);
879 return;
880 }
869 881
870 /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ 882 /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */
871 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); 883 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)
873 pr_warn("%s: could not register clock pclk_wdt: %ld\n", 885 pr_warn("%s: could not register clock pclk_wdt: %ld\n",
874 __func__, PTR_ERR(clk)); 886 __func__, PTR_ERR(clk));
875 else 887 else
876 rockchip_clk_add_lookup(clk, PCLK_WDT); 888 rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
877 889
878 rockchip_clk_register_plls(rk3368_pll_clks, 890 rockchip_clk_register_plls(ctx, rk3368_pll_clks,
879 ARRAY_SIZE(rk3368_pll_clks), 891 ARRAY_SIZE(rk3368_pll_clks),
880 RK3368_GRF_SOC_STATUS0); 892 RK3368_GRF_SOC_STATUS0);
881 rockchip_clk_register_branches(rk3368_clk_branches, 893 rockchip_clk_register_branches(ctx, rk3368_clk_branches,
882 ARRAY_SIZE(rk3368_clk_branches)); 894 ARRAY_SIZE(rk3368_clk_branches));
883 rockchip_clk_protect_critical(rk3368_critical_clocks, 895 rockchip_clk_protect_critical(rk3368_critical_clocks,
884 ARRAY_SIZE(rk3368_critical_clocks)); 896 ARRAY_SIZE(rk3368_critical_clocks));
885 897
886 rockchip_clk_register_armclk(ARMCLKB, "armclkb", 898 rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb",
887 mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p), 899 mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
888 &rk3368_cpuclkb_data, rk3368_cpuclkb_rates, 900 &rk3368_cpuclkb_data, rk3368_cpuclkb_rates,
889 ARRAY_SIZE(rk3368_cpuclkb_rates)); 901 ARRAY_SIZE(rk3368_cpuclkb_rates));
890 902
891 rockchip_clk_register_armclk(ARMCLKL, "armclkl", 903 rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl",
892 mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), 904 mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
893 &rk3368_cpuclkl_data, rk3368_cpuclkl_rates, 905 &rk3368_cpuclkl_data, rk3368_cpuclkl_rates,
894 ARRAY_SIZE(rk3368_cpuclkl_rates)); 906 ARRAY_SIZE(rk3368_cpuclkl_rates));
@@ -896,6 +908,8 @@ static void __init rk3368_clk_init(struct device_node *np)
896 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0), 908 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
897 ROCKCHIP_SOFTRST_HIWORD_MASK); 909 ROCKCHIP_SOFTRST_HIWORD_MASK);
898 910
899 rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL); 911 rockchip_register_restart_notifier(ctx, RK3368_GLB_SRST_FST, NULL);
912
913 rockchip_clk_of_add_provider(np, ctx);
900} 914}
901CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init); 915CLK_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
index 000000000000..291543f52caa
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -0,0 +1,1573 @@
1/*
2 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
3 * Author: Xing Zheng <zhengxing@rock-chips.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/platform_device.h>
20#include <linux/regmap.h>
21#include <dt-bindings/clock/rk3399-cru.h>
22#include "clk.h"
23
24enum rk3399_plls {
25 lpll, bpll, dpll, cpll, gpll, npll, vpll,
26};
27
28enum rk3399_pmu_plls {
29 ppll,
30};
31
32static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
33 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
34 RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0),
35 RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0),
36 RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0),
37 RK3036_PLL_RATE(2136000000, 1, 89, 1, 1, 1, 0),
38 RK3036_PLL_RATE(2112000000, 1, 88, 1, 1, 1, 0),
39 RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0),
40 RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0),
41 RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0),
42 RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
43 RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0),
44 RK3036_PLL_RATE(1968000000, 1, 82, 1, 1, 1, 0),
45 RK3036_PLL_RATE(1944000000, 1, 81, 1, 1, 1, 0),
46 RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0),
47 RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
48 RK3036_PLL_RATE(1872000000, 1, 78, 1, 1, 1, 0),
49 RK3036_PLL_RATE(1848000000, 1, 77, 1, 1, 1, 0),
50 RK3036_PLL_RATE(1824000000, 1, 76, 1, 1, 1, 0),
51 RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
52 RK3036_PLL_RATE(1776000000, 1, 74, 1, 1, 1, 0),
53 RK3036_PLL_RATE(1752000000, 1, 73, 1, 1, 1, 0),
54 RK3036_PLL_RATE(1728000000, 1, 72, 1, 1, 1, 0),
55 RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
56 RK3036_PLL_RATE(1680000000, 1, 70, 1, 1, 1, 0),
57 RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0),
58 RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0),
59 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
60 RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
61 RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
62 RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
63 RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
64 RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
65 RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
66 RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
67 RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
68 RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
69 RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
70 RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
71 RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
72 RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
73 RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
74 RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
75 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
76 RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
77 RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
78 RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
79 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
80 RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
81 RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
82 RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
83 RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
84 RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
85 RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
86 RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
87 RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
88 RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
89 RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
90 RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
91 RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
92 RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
93 RK3036_PLL_RATE( 676000000, 3, 169, 2, 1, 1, 0),
94 RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
95 RK3036_PLL_RATE( 594000000, 1, 99, 4, 1, 1, 0),
96 RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
97 RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
98 RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
99 RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
100 RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0),
101 RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
102 RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0),
103 RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
104 RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0),
105 RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0),
106 RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0),
107 { /* sentinel */ },
108};
109
110/* CRU parents */
111PNAME(mux_pll_p) = { "xin24m", "xin32k" };
112
113PNAME(mux_armclkl_p) = { "clk_core_l_lpll_src",
114 "clk_core_l_bpll_src",
115 "clk_core_l_dpll_src",
116 "clk_core_l_gpll_src" };
117PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src",
118 "clk_core_b_bpll_src",
119 "clk_core_b_dpll_src",
120 "clk_core_b_gpll_src" };
121PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src",
122 "gpll_aclk_cci_src",
123 "npll_aclk_cci_src",
124 "vpll_aclk_cci_src" };
125PNAME(mux_cci_trace_p) = { "cpll_cci_trace",
126 "gpll_cci_trace" };
127PNAME(mux_cs_p) = { "cpll_cs", "gpll_cs",
128 "npll_cs"};
129PNAME(mux_aclk_perihp_p) = { "cpll_aclk_perihp_src",
130 "gpll_aclk_perihp_src" };
131
132PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
133PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
134PNAME(mux_pll_src_cpll_gpll_ppll_p) = { "cpll", "gpll", "ppll" };
135PNAME(mux_pll_src_cpll_gpll_upll_p) = { "cpll", "gpll", "upll" };
136PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
137PNAME(mux_pll_src_cpll_gpll_npll_ppll_p) = { "cpll", "gpll", "npll",
138 "ppll" };
139PNAME(mux_pll_src_cpll_gpll_npll_24m_p) = { "cpll", "gpll", "npll",
140 "xin24m" };
141PNAME(mux_pll_src_cpll_gpll_npll_usbphy480m_p) = { "cpll", "gpll", "npll",
142 "clk_usbphy_480m" };
143PNAME(mux_pll_src_ppll_cpll_gpll_npll_p) = { "ppll", "cpll", "gpll",
144 "npll", "upll" };
145PNAME(mux_pll_src_cpll_gpll_npll_upll_24m_p) = { "cpll", "gpll", "npll",
146 "upll", "xin24m" };
147PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "cpll", "gpll", "npll",
148 "ppll", "upll", "xin24m" };
149
150PNAME(mux_pll_src_vpll_cpll_gpll_p) = { "vpll", "cpll", "gpll" };
151PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "vpll", "cpll", "gpll",
152 "npll" };
153PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "vpll", "cpll", "gpll",
154 "xin24m" };
155
156PNAME(mux_dclk_vop0_p) = { "dclk_vop0_div",
157 "dclk_vop0_frac" };
158PNAME(mux_dclk_vop1_p) = { "dclk_vop1_div",
159 "dclk_vop1_frac" };
160
161PNAME(mux_clk_cif_p) = { "clk_cifout_src", "xin24m" };
162
163PNAME(mux_pll_src_24m_usbphy480m_p) = { "xin24m", "clk_usbphy_480m" };
164PNAME(mux_pll_src_24m_pciephy_p) = { "xin24m", "clk_pciephy_ref100m" };
165PNAME(mux_pll_src_24m_32k_cpll_gpll_p) = { "xin24m", "xin32k",
166 "cpll", "gpll" };
167PNAME(mux_pciecore_cru_phy_p) = { "clk_pcie_core_cru",
168 "clk_pcie_core_phy" };
169
170PNAME(mux_aclk_emmc_p) = { "cpll_aclk_emmc_src",
171 "gpll_aclk_emmc_src" };
172
173PNAME(mux_aclk_perilp0_p) = { "cpll_aclk_perilp0_src",
174 "gpll_aclk_perilp0_src" };
175
176PNAME(mux_fclk_cm0s_p) = { "cpll_fclk_cm0s_src",
177 "gpll_fclk_cm0s_src" };
178
179PNAME(mux_hclk_perilp1_p) = { "cpll_hclk_perilp1_src",
180 "gpll_hclk_perilp1_src" };
181
182PNAME(mux_clk_testout1_p) = { "clk_testout1_pll_src", "xin24m" };
183PNAME(mux_clk_testout2_p) = { "clk_testout2_pll_src", "xin24m" };
184
185PNAME(mux_usbphy_480m_p) = { "clk_usbphy0_480m_src",
186 "clk_usbphy1_480m_src" };
187PNAME(mux_aclk_gmac_p) = { "cpll_aclk_gmac_src",
188 "gpll_aclk_gmac_src" };
189PNAME(mux_rmii_p) = { "clk_gmac", "clkin_gmac" };
190PNAME(mux_spdif_p) = { "clk_spdif_div", "clk_spdif_frac",
191 "clkin_i2s", "xin12m" };
192PNAME(mux_i2s0_p) = { "clk_i2s0_div", "clk_i2s0_frac",
193 "clkin_i2s", "xin12m" };
194PNAME(mux_i2s1_p) = { "clk_i2s1_div", "clk_i2s1_frac",
195 "clkin_i2s", "xin12m" };
196PNAME(mux_i2s2_p) = { "clk_i2s2_div", "clk_i2s2_frac",
197 "clkin_i2s", "xin12m" };
198PNAME(mux_i2sch_p) = { "clk_i2s0", "clk_i2s1",
199 "clk_i2s2" };
200PNAME(mux_i2sout_p) = { "clk_i2sout_src", "xin12m" };
201
202PNAME(mux_uart0_p) = { "clk_uart0_div", "clk_uart0_frac", "xin24m" };
203PNAME(mux_uart1_p) = { "clk_uart1_div", "clk_uart1_frac", "xin24m" };
204PNAME(mux_uart2_p) = { "clk_uart2_div", "clk_uart2_frac", "xin24m" };
205PNAME(mux_uart3_p) = { "clk_uart3_div", "clk_uart3_frac", "xin24m" };
206
207/* PMU CRU parents */
208PNAME(mux_ppll_24m_p) = { "ppll", "xin24m" };
209PNAME(mux_24m_ppll_p) = { "xin24m", "ppll" };
210PNAME(mux_fclk_cm0s_pmu_ppll_p) = { "fclk_cm0s_pmu_ppll_src", "xin24m" };
211PNAME(mux_wifi_pmu_p) = { "clk_wifi_div", "clk_wifi_frac" };
212PNAME(mux_uart4_pmu_p) = { "clk_uart4_div", "clk_uart4_frac",
213 "xin24m" };
214PNAME(mux_clk_testout2_2io_p) = { "clk_testout2", "clk_32k_suspend_pmu" };
215
216static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = {
217 [lpll] = PLL(pll_rk3399, PLL_APLLL, "lpll", mux_pll_p, 0, RK3399_PLL_CON(0),
218 RK3399_PLL_CON(3), 8, 31, 0, rk3399_pll_rates),
219 [bpll] = PLL(pll_rk3399, PLL_APLLB, "bpll", mux_pll_p, 0, RK3399_PLL_CON(8),
220 RK3399_PLL_CON(11), 8, 31, 0, rk3399_pll_rates),
221 [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RK3399_PLL_CON(16),
222 RK3399_PLL_CON(19), 8, 31, 0, NULL),
223 [cpll] = PLL(pll_rk3399, PLL_CPLL, "cpll", mux_pll_p, 0, RK3399_PLL_CON(24),
224 RK3399_PLL_CON(27), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
225 [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RK3399_PLL_CON(32),
226 RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
227 [npll] = PLL(pll_rk3399, PLL_NPLL, "npll", mux_pll_p, 0, RK3399_PLL_CON(40),
228 RK3399_PLL_CON(43), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
229 [vpll] = PLL(pll_rk3399, PLL_VPLL, "vpll", mux_pll_p, 0, RK3399_PLL_CON(48),
230 RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
231};
232
233static struct rockchip_pll_clock rk3399_pmu_pll_clks[] __initdata = {
234 [ppll] = PLL(pll_rk3399, PLL_PPLL, "ppll", mux_pll_p, 0, RK3399_PMU_PLL_CON(0),
235 RK3399_PMU_PLL_CON(3), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates),
236};
237
238#define MFLAGS CLK_MUX_HIWORD_MASK
239#define DFLAGS CLK_DIVIDER_HIWORD_MASK
240#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
241#define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK
242
243static struct rockchip_clk_branch rk3399_spdif_fracmux __initdata =
244 MUX(0, "clk_spdif_mux", mux_spdif_p, CLK_SET_RATE_PARENT,
245 RK3399_CLKSEL_CON(32), 13, 2, MFLAGS);
246
247static struct rockchip_clk_branch rk3399_i2s0_fracmux __initdata =
248 MUX(0, "clk_i2s0_mux", mux_i2s0_p, CLK_SET_RATE_PARENT,
249 RK3399_CLKSEL_CON(28), 8, 2, MFLAGS);
250
251static struct rockchip_clk_branch rk3399_i2s1_fracmux __initdata =
252 MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT,
253 RK3399_CLKSEL_CON(29), 8, 2, MFLAGS);
254
255static struct rockchip_clk_branch rk3399_i2s2_fracmux __initdata =
256 MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT,
257 RK3399_CLKSEL_CON(30), 8, 2, MFLAGS);
258
259static struct rockchip_clk_branch rk3399_uart0_fracmux __initdata =
260 MUX(SCLK_UART0, "clk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
261 RK3399_CLKSEL_CON(33), 8, 2, MFLAGS);
262
263static struct rockchip_clk_branch rk3399_uart1_fracmux __initdata =
264 MUX(SCLK_UART1, "clk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
265 RK3399_CLKSEL_CON(34), 8, 2, MFLAGS);
266
267static struct rockchip_clk_branch rk3399_uart2_fracmux __initdata =
268 MUX(SCLK_UART2, "clk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
269 RK3399_CLKSEL_CON(35), 8, 2, MFLAGS);
270
271static struct rockchip_clk_branch rk3399_uart3_fracmux __initdata =
272 MUX(SCLK_UART3, "clk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
273 RK3399_CLKSEL_CON(36), 8, 2, MFLAGS);
274
275static struct rockchip_clk_branch rk3399_uart4_pmu_fracmux __initdata =
276 MUX(SCLK_UART4_PMU, "clk_uart4_pmu", mux_uart4_pmu_p, CLK_SET_RATE_PARENT,
277 RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS);
278
279static struct rockchip_clk_branch rk3399_dclk_vop0_fracmux __initdata =
280 MUX(DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_p, CLK_SET_RATE_PARENT,
281 RK3399_CLKSEL_CON(49), 11, 1, MFLAGS);
282
283static struct rockchip_clk_branch rk3399_dclk_vop1_fracmux __initdata =
284 MUX(DCLK_VOP1, "dclk_vop1", mux_dclk_vop1_p, CLK_SET_RATE_PARENT,
285 RK3399_CLKSEL_CON(50), 11, 1, MFLAGS);
286
287static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata =
288 MUX(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT,
289 RK3399_PMU_CLKSEL_CON(1), 14, 1, MFLAGS);
290
291static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = {
292 .core_reg = RK3399_CLKSEL_CON(0),
293 .div_core_shift = 0,
294 .div_core_mask = 0x1f,
295 .mux_core_alt = 3,
296 .mux_core_main = 0,
297 .mux_core_shift = 6,
298 .mux_core_mask = 0x3,
299};
300
301static const struct rockchip_cpuclk_reg_data rk3399_cpuclkb_data = {
302 .core_reg = RK3399_CLKSEL_CON(2),
303 .div_core_shift = 0,
304 .div_core_mask = 0x1f,
305 .mux_core_alt = 3,
306 .mux_core_main = 1,
307 .mux_core_shift = 6,
308 .mux_core_mask = 0x3,
309};
310
311#define RK3399_DIV_ACLKM_MASK 0x1f
312#define RK3399_DIV_ACLKM_SHIFT 8
313#define RK3399_DIV_ATCLK_MASK 0x1f
314#define RK3399_DIV_ATCLK_SHIFT 0
315#define RK3399_DIV_PCLK_DBG_MASK 0x1f
316#define RK3399_DIV_PCLK_DBG_SHIFT 8
317
318#define RK3399_CLKSEL0(_offs, _aclkm) \
319 { \
320 .reg = RK3399_CLKSEL_CON(0 + _offs), \
321 .val = HIWORD_UPDATE(_aclkm, RK3399_DIV_ACLKM_MASK, \
322 RK3399_DIV_ACLKM_SHIFT), \
323 }
324#define RK3399_CLKSEL1(_offs, _atclk, _pdbg) \
325 { \
326 .reg = RK3399_CLKSEL_CON(1 + _offs), \
327 .val = HIWORD_UPDATE(_atclk, RK3399_DIV_ATCLK_MASK, \
328 RK3399_DIV_ATCLK_SHIFT) | \
329 HIWORD_UPDATE(_pdbg, RK3399_DIV_PCLK_DBG_MASK, \
330 RK3399_DIV_PCLK_DBG_SHIFT), \
331 }
332
333/* cluster_l: aclkm in clksel0, rest in clksel1 */
334#define RK3399_CPUCLKL_RATE(_prate, _aclkm, _atclk, _pdbg) \
335 { \
336 .prate = _prate##U, \
337 .divs = { \
338 RK3399_CLKSEL0(0, _aclkm), \
339 RK3399_CLKSEL1(0, _atclk, _pdbg), \
340 }, \
341 }
342
343/* cluster_b: aclkm in clksel2, rest in clksel3 */
344#define RK3399_CPUCLKB_RATE(_prate, _aclkm, _atclk, _pdbg) \
345 { \
346 .prate = _prate##U, \
347 .divs = { \
348 RK3399_CLKSEL0(2, _aclkm), \
349 RK3399_CLKSEL1(2, _atclk, _pdbg), \
350 }, \
351 }
352
353static struct rockchip_cpuclk_rate_table rk3399_cpuclkl_rates[] __initdata = {
354 RK3399_CPUCLKL_RATE(1800000000, 1, 8, 8),
355 RK3399_CPUCLKL_RATE(1704000000, 1, 8, 8),
356 RK3399_CPUCLKL_RATE(1608000000, 1, 7, 7),
357 RK3399_CPUCLKL_RATE(1512000000, 1, 7, 7),
358 RK3399_CPUCLKL_RATE(1488000000, 1, 6, 6),
359 RK3399_CPUCLKL_RATE(1416000000, 1, 6, 6),
360 RK3399_CPUCLKL_RATE(1200000000, 1, 5, 5),
361 RK3399_CPUCLKL_RATE(1008000000, 1, 5, 5),
362 RK3399_CPUCLKL_RATE( 816000000, 1, 4, 4),
363 RK3399_CPUCLKL_RATE( 696000000, 1, 3, 3),
364 RK3399_CPUCLKL_RATE( 600000000, 1, 3, 3),
365 RK3399_CPUCLKL_RATE( 408000000, 1, 2, 2),
366 RK3399_CPUCLKL_RATE( 312000000, 1, 1, 1),
367 RK3399_CPUCLKL_RATE( 216000000, 1, 1, 1),
368 RK3399_CPUCLKL_RATE( 96000000, 1, 1, 1),
369};
370
371static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = {
372 RK3399_CPUCLKB_RATE(2208000000, 1, 11, 11),
373 RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11),
374 RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10),
375 RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10),
376 RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9),
377 RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9),
378 RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8),
379 RK3399_CPUCLKB_RATE(1704000000, 1, 8, 8),
380 RK3399_CPUCLKB_RATE(1608000000, 1, 7, 7),
381 RK3399_CPUCLKB_RATE(1512000000, 1, 7, 7),
382 RK3399_CPUCLKB_RATE(1488000000, 1, 6, 6),
383 RK3399_CPUCLKB_RATE(1416000000, 1, 6, 6),
384 RK3399_CPUCLKB_RATE(1200000000, 1, 5, 5),
385 RK3399_CPUCLKB_RATE(1008000000, 1, 5, 5),
386 RK3399_CPUCLKB_RATE( 816000000, 1, 4, 4),
387 RK3399_CPUCLKB_RATE( 696000000, 1, 3, 3),
388 RK3399_CPUCLKB_RATE( 600000000, 1, 3, 3),
389 RK3399_CPUCLKB_RATE( 408000000, 1, 2, 2),
390 RK3399_CPUCLKB_RATE( 312000000, 1, 1, 1),
391 RK3399_CPUCLKB_RATE( 216000000, 1, 1, 1),
392 RK3399_CPUCLKB_RATE( 96000000, 1, 1, 1),
393};
394
395static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
396 /*
397 * CRU Clock-Architecture
398 */
399
400 /* usbphy */
401 GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", CLK_IGNORE_UNUSED,
402 RK3399_CLKGATE_CON(6), 5, GFLAGS),
403 GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", CLK_IGNORE_UNUSED,
404 RK3399_CLKGATE_CON(6), 6, GFLAGS),
405
406 GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", CLK_IGNORE_UNUSED,
407 RK3399_CLKGATE_CON(13), 12, GFLAGS),
408 GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", CLK_IGNORE_UNUSED,
409 RK3399_CLKGATE_CON(13), 12, GFLAGS),
410 MUX(0, "clk_usbphy_480m", mux_usbphy_480m_p, CLK_IGNORE_UNUSED,
411 RK3399_CLKSEL_CON(14), 6, 1, MFLAGS),
412
413 MUX(0, "upll", mux_pll_src_24m_usbphy480m_p, 0,
414 RK3399_CLKSEL_CON(14), 15, 1, MFLAGS),
415
416 COMPOSITE_NODIV(SCLK_HSICPHY, "clk_hsicphy", mux_pll_src_cpll_gpll_npll_usbphy480m_p, 0,
417 RK3399_CLKSEL_CON(19), 0, 2, MFLAGS,
418 RK3399_CLKGATE_CON(6), 4, GFLAGS),
419
420 COMPOSITE(ACLK_USB3, "aclk_usb3", mux_pll_src_cpll_gpll_npll_p, 0,
421 RK3399_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS,
422 RK3399_CLKGATE_CON(12), 0, GFLAGS),
423 GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", CLK_IGNORE_UNUSED,
424 RK3399_CLKGATE_CON(30), 0, GFLAGS),
425 GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb3", 0,
426 RK3399_CLKGATE_CON(30), 1, GFLAGS),
427 GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb3", 0,
428 RK3399_CLKGATE_CON(30), 2, GFLAGS),
429 GATE(ACLK_USB3_RKSOC_AXI_PERF, "aclk_usb3_rksoc_axi_perf", "aclk_usb3", 0,
430 RK3399_CLKGATE_CON(30), 3, GFLAGS),
431 GATE(ACLK_USB3_GRF, "aclk_usb3_grf", "aclk_usb3", 0,
432 RK3399_CLKGATE_CON(30), 4, GFLAGS),
433
434 GATE(SCLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0,
435 RK3399_CLKGATE_CON(12), 1, GFLAGS),
436 GATE(SCLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0,
437 RK3399_CLKGATE_CON(12), 2, GFLAGS),
438
439 COMPOSITE(SCLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", mux_pll_p, 0,
440 RK3399_CLKSEL_CON(40), 15, 1, MFLAGS, 0, 10, DFLAGS,
441 RK3399_CLKGATE_CON(12), 3, GFLAGS),
442
443 COMPOSITE(SCLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", mux_pll_p, 0,
444 RK3399_CLKSEL_CON(41), 15, 1, MFLAGS, 0, 10, DFLAGS,
445 RK3399_CLKGATE_CON(12), 4, GFLAGS),
446
447 COMPOSITE(SCLK_UPHY0_TCPDPHY_REF, "clk_uphy0_tcpdphy_ref", mux_pll_p, 0,
448 RK3399_CLKSEL_CON(64), 15, 1, MFLAGS, 8, 5, DFLAGS,
449 RK3399_CLKGATE_CON(13), 4, GFLAGS),
450
451 COMPOSITE(SCLK_UPHY0_TCPDCORE, "clk_uphy0_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, 0,
452 RK3399_CLKSEL_CON(64), 6, 2, MFLAGS, 0, 5, DFLAGS,
453 RK3399_CLKGATE_CON(13), 5, GFLAGS),
454
455 COMPOSITE(SCLK_UPHY1_TCPDPHY_REF, "clk_uphy1_tcpdphy_ref", mux_pll_p, 0,
456 RK3399_CLKSEL_CON(65), 15, 1, MFLAGS, 8, 5, DFLAGS,
457 RK3399_CLKGATE_CON(13), 6, GFLAGS),
458
459 COMPOSITE(SCLK_UPHY1_TCPDCORE, "clk_uphy1_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, 0,
460 RK3399_CLKSEL_CON(65), 6, 2, MFLAGS, 0, 5, DFLAGS,
461 RK3399_CLKGATE_CON(13), 7, GFLAGS),
462
463 /* little core */
464 GATE(0, "clk_core_l_lpll_src", "lpll", CLK_IGNORE_UNUSED,
465 RK3399_CLKGATE_CON(0), 0, GFLAGS),
466 GATE(0, "clk_core_l_bpll_src", "bpll", CLK_IGNORE_UNUSED,
467 RK3399_CLKGATE_CON(0), 1, GFLAGS),
468 GATE(0, "clk_core_l_dpll_src", "dpll", CLK_IGNORE_UNUSED,
469 RK3399_CLKGATE_CON(0), 2, GFLAGS),
470 GATE(0, "clk_core_l_gpll_src", "gpll", CLK_IGNORE_UNUSED,
471 RK3399_CLKGATE_CON(0), 3, GFLAGS),
472
473 COMPOSITE_NOMUX(0, "aclkm_core_l", "armclkl", CLK_IGNORE_UNUSED,
474 RK3399_CLKSEL_CON(0), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
475 RK3399_CLKGATE_CON(0), 4, GFLAGS),
476 COMPOSITE_NOMUX(0, "atclk_core_l", "armclkl", CLK_IGNORE_UNUSED,
477 RK3399_CLKSEL_CON(1), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
478 RK3399_CLKGATE_CON(0), 5, GFLAGS),
479 COMPOSITE_NOMUX(0, "pclk_dbg_core_l", "armclkl", CLK_IGNORE_UNUSED,
480 RK3399_CLKSEL_CON(1), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
481 RK3399_CLKGATE_CON(0), 6, GFLAGS),
482
483 GATE(ACLK_CORE_ADB400_CORE_L_2_CCI500, "aclk_core_adb400_core_l_2_cci500", "aclkm_core_l", CLK_IGNORE_UNUSED,
484 RK3399_CLKGATE_CON(14), 12, GFLAGS),
485 GATE(ACLK_PERF_CORE_L, "aclk_perf_core_l", "aclkm_core_l", CLK_IGNORE_UNUSED,
486 RK3399_CLKGATE_CON(14), 13, GFLAGS),
487
488 GATE(0, "clk_dbg_pd_core_l", "armclkl", CLK_IGNORE_UNUSED,
489 RK3399_CLKGATE_CON(14), 9, GFLAGS),
490 GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_core_adb400_gic_2_core_l", "armclkl", CLK_IGNORE_UNUSED,
491 RK3399_CLKGATE_CON(14), 10, GFLAGS),
492 GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_core_adb400_core_l_2_gic", "armclkl", CLK_IGNORE_UNUSED,
493 RK3399_CLKGATE_CON(14), 11, GFLAGS),
494 GATE(SCLK_PVTM_CORE_L, "clk_pvtm_core_l", "xin24m", CLK_IGNORE_UNUSED,
495 RK3399_CLKGATE_CON(0), 7, GFLAGS),
496
497 /* big core */
498 GATE(0, "clk_core_b_lpll_src", "lpll", CLK_IGNORE_UNUSED,
499 RK3399_CLKGATE_CON(1), 0, GFLAGS),
500 GATE(0, "clk_core_b_bpll_src", "bpll", CLK_IGNORE_UNUSED,
501 RK3399_CLKGATE_CON(1), 1, GFLAGS),
502 GATE(0, "clk_core_b_dpll_src", "dpll", CLK_IGNORE_UNUSED,
503 RK3399_CLKGATE_CON(1), 2, GFLAGS),
504 GATE(0, "clk_core_b_gpll_src", "gpll", CLK_IGNORE_UNUSED,
505 RK3399_CLKGATE_CON(1), 3, GFLAGS),
506
507 COMPOSITE_NOMUX(0, "aclkm_core_b", "armclkb", CLK_IGNORE_UNUSED,
508 RK3399_CLKSEL_CON(2), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
509 RK3399_CLKGATE_CON(1), 4, GFLAGS),
510 COMPOSITE_NOMUX(0, "atclk_core_b", "armclkb", CLK_IGNORE_UNUSED,
511 RK3399_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
512 RK3399_CLKGATE_CON(1), 5, GFLAGS),
513 COMPOSITE_NOMUX(0, "pclk_dbg_core_b", "armclkb", CLK_IGNORE_UNUSED,
514 RK3399_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
515 RK3399_CLKGATE_CON(1), 6, GFLAGS),
516
517 GATE(ACLK_CORE_ADB400_CORE_B_2_CCI500, "aclk_core_adb400_core_b_2_cci500", "aclkm_core_b", CLK_IGNORE_UNUSED,
518 RK3399_CLKGATE_CON(14), 5, GFLAGS),
519 GATE(ACLK_PERF_CORE_B, "aclk_perf_core_b", "aclkm_core_b", CLK_IGNORE_UNUSED,
520 RK3399_CLKGATE_CON(14), 6, GFLAGS),
521
522 GATE(0, "clk_dbg_pd_core_b", "armclkb", CLK_IGNORE_UNUSED,
523 RK3399_CLKGATE_CON(14), 1, GFLAGS),
524 GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_core_adb400_gic_2_core_b", "armclkb", CLK_IGNORE_UNUSED,
525 RK3399_CLKGATE_CON(14), 3, GFLAGS),
526 GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_core_adb400_core_b_2_gic", "armclkb", CLK_IGNORE_UNUSED,
527 RK3399_CLKGATE_CON(14), 4, GFLAGS),
528
529 DIV(0, "pclken_dbg_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED,
530 RK3399_CLKSEL_CON(3), 13, 2, DFLAGS | CLK_DIVIDER_READ_ONLY),
531
532 GATE(0, "pclk_dbg_cxcs_pd_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED,
533 RK3399_CLKGATE_CON(14), 2, GFLAGS),
534
535 GATE(SCLK_PVTM_CORE_B, "clk_pvtm_core_b", "xin24m", CLK_IGNORE_UNUSED,
536 RK3399_CLKGATE_CON(1), 7, GFLAGS),
537
538 /* gmac */
539 GATE(0, "cpll_aclk_gmac_src", "cpll", CLK_IGNORE_UNUSED,
540 RK3399_CLKGATE_CON(6), 9, GFLAGS),
541 GATE(0, "gpll_aclk_gmac_src", "gpll", CLK_IGNORE_UNUSED,
542 RK3399_CLKGATE_CON(6), 8, GFLAGS),
543 COMPOSITE(0, "aclk_gmac_pre", mux_aclk_gmac_p, 0,
544 RK3399_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 5, DFLAGS,
545 RK3399_CLKGATE_CON(6), 10, GFLAGS),
546
547 GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", 0,
548 RK3399_CLKGATE_CON(32), 0, GFLAGS),
549 GATE(ACLK_GMAC_NOC, "aclk_gmac_noc", "aclk_gmac_pre", CLK_IGNORE_UNUSED,
550 RK3399_CLKGATE_CON(32), 1, GFLAGS),
551 GATE(ACLK_PERF_GMAC, "aclk_perf_gmac", "aclk_gmac_pre", 0,
552 RK3399_CLKGATE_CON(32), 4, GFLAGS),
553
554 COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0,
555 RK3399_CLKSEL_CON(19), 8, 3, DFLAGS,
556 RK3399_CLKGATE_CON(6), 11, GFLAGS),
557 GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", 0,
558 RK3399_CLKGATE_CON(32), 2, GFLAGS),
559 GATE(PCLK_GMAC_NOC, "pclk_gmac_noc", "pclk_gmac_pre", CLK_IGNORE_UNUSED,
560 RK3399_CLKGATE_CON(32), 3, GFLAGS),
561
562 COMPOSITE(SCLK_MAC, "clk_gmac", mux_pll_src_cpll_gpll_npll_p, 0,
563 RK3399_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS,
564 RK3399_CLKGATE_CON(5), 5, GFLAGS),
565
566 MUX(SCLK_RMII_SRC, "clk_rmii_src", mux_rmii_p, CLK_SET_RATE_PARENT,
567 RK3399_CLKSEL_CON(19), 4, 1, MFLAGS),
568 GATE(SCLK_MACREF_OUT, "clk_mac_refout", "clk_rmii_src", 0,
569 RK3399_CLKGATE_CON(5), 6, GFLAGS),
570 GATE(SCLK_MACREF, "clk_mac_ref", "clk_rmii_src", 0,
571 RK3399_CLKGATE_CON(5), 7, GFLAGS),
572 GATE(SCLK_MAC_RX, "clk_rmii_rx", "clk_rmii_src", 0,
573 RK3399_CLKGATE_CON(5), 8, GFLAGS),
574 GATE(SCLK_MAC_TX, "clk_rmii_tx", "clk_rmii_src", 0,
575 RK3399_CLKGATE_CON(5), 9, GFLAGS),
576
577 /* spdif */
578 COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
579 RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS,
580 RK3399_CLKGATE_CON(8), 13, GFLAGS),
581 COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT,
582 RK3399_CLKSEL_CON(99), 0,
583 RK3399_CLKGATE_CON(8), 14, GFLAGS,
584 &rk3399_spdif_fracmux),
585 GATE(SCLK_SPDIF_8CH, "clk_spdif", "clk_spdif_mux", CLK_SET_RATE_PARENT,
586 RK3399_CLKGATE_CON(8), 15, GFLAGS),
587
588 COMPOSITE(SCLK_SPDIF_REC_DPTX, "clk_spdif_rec_dptx", mux_pll_src_cpll_gpll_p, 0,
589 RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 5, DFLAGS,
590 RK3399_CLKGATE_CON(10), 6, GFLAGS),
591 /* i2s */
592 COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
593 RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS,
594 RK3399_CLKGATE_CON(8), 3, GFLAGS),
595 COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT,
596 RK3399_CLKSEL_CON(96), 0,
597 RK3399_CLKGATE_CON(8), 4, GFLAGS,
598 &rk3399_i2s0_fracmux),
599 GATE(SCLK_I2S0_8CH, "clk_i2s0", "clk_i2s0_mux", CLK_SET_RATE_PARENT,
600 RK3399_CLKGATE_CON(8), 5, GFLAGS),
601
602 COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
603 RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS,
604 RK3399_CLKGATE_CON(8), 6, GFLAGS),
605 COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT,
606 RK3399_CLKSEL_CON(97), 0,
607 RK3399_CLKGATE_CON(8), 7, GFLAGS,
608 &rk3399_i2s1_fracmux),
609 GATE(SCLK_I2S1_8CH, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT,
610 RK3399_CLKGATE_CON(8), 8, GFLAGS),
611
612 COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
613 RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS,
614 RK3399_CLKGATE_CON(8), 9, GFLAGS),
615 COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT,
616 RK3399_CLKSEL_CON(98), 0,
617 RK3399_CLKGATE_CON(8), 10, GFLAGS,
618 &rk3399_i2s2_fracmux),
619 GATE(SCLK_I2S2_8CH, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT,
620 RK3399_CLKGATE_CON(8), 11, GFLAGS),
621
622 MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,
623 RK3399_CLKSEL_CON(31), 0, 2, MFLAGS),
624 COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT,
625 RK3399_CLKSEL_CON(30), 8, 2, MFLAGS,
626 RK3399_CLKGATE_CON(8), 12, GFLAGS),
627
628 /* uart */
629 MUX(0, "clk_uart0_src", mux_pll_src_cpll_gpll_upll_p, 0,
630 RK3399_CLKSEL_CON(33), 12, 2, MFLAGS),
631 COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0,
632 RK3399_CLKSEL_CON(33), 0, 7, DFLAGS,
633 RK3399_CLKGATE_CON(9), 0, GFLAGS),
634 COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT,
635 RK3399_CLKSEL_CON(100), 0,
636 RK3399_CLKGATE_CON(9), 1, GFLAGS,
637 &rk3399_uart0_fracmux),
638
639 MUX(0, "clk_uart_src", mux_pll_src_cpll_gpll_p, 0,
640 RK3399_CLKSEL_CON(33), 15, 1, MFLAGS),
641 COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0,
642 RK3399_CLKSEL_CON(34), 0, 7, DFLAGS,
643 RK3399_CLKGATE_CON(9), 2, GFLAGS),
644 COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT,
645 RK3399_CLKSEL_CON(101), 0,
646 RK3399_CLKGATE_CON(9), 3, GFLAGS,
647 &rk3399_uart1_fracmux),
648
649 COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0,
650 RK3399_CLKSEL_CON(35), 0, 7, DFLAGS,
651 RK3399_CLKGATE_CON(9), 4, GFLAGS),
652 COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT,
653 RK3399_CLKSEL_CON(102), 0,
654 RK3399_CLKGATE_CON(9), 5, GFLAGS,
655 &rk3399_uart2_fracmux),
656
657 COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0,
658 RK3399_CLKSEL_CON(36), 0, 7, DFLAGS,
659 RK3399_CLKGATE_CON(9), 6, GFLAGS),
660 COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT,
661 RK3399_CLKSEL_CON(103), 0,
662 RK3399_CLKGATE_CON(9), 7, GFLAGS,
663 &rk3399_uart3_fracmux),
664
665 COMPOSITE(0, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
666 RK3399_CLKSEL_CON(6), 15, 1, MFLAGS, 8, 5, DFLAGS,
667 RK3399_CLKGATE_CON(3), 4, GFLAGS),
668
669 GATE(PCLK_CENTER_MAIN_NOC, "pclk_center_main_noc", "pclk_ddr", CLK_IGNORE_UNUSED,
670 RK3399_CLKGATE_CON(18), 10, GFLAGS),
671 GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED,
672 RK3399_CLKGATE_CON(18), 12, GFLAGS),
673 GATE(PCLK_CIC, "pclk_cic", "pclk_ddr", CLK_IGNORE_UNUSED,
674 RK3399_CLKGATE_CON(18), 15, GFLAGS),
675 GATE(PCLK_DDR_SGRF, "pclk_ddr_sgrf", "pclk_ddr", CLK_IGNORE_UNUSED,
676 RK3399_CLKGATE_CON(19), 2, GFLAGS),
677
678 GATE(SCLK_PVTM_DDR, "clk_pvtm_ddr", "xin24m", CLK_IGNORE_UNUSED,
679 RK3399_CLKGATE_CON(4), 11, GFLAGS),
680 GATE(SCLK_DFIMON0_TIMER, "clk_dfimon0_timer", "xin24m", CLK_IGNORE_UNUSED,
681 RK3399_CLKGATE_CON(3), 5, GFLAGS),
682 GATE(SCLK_DFIMON1_TIMER, "clk_dfimon1_timer", "xin24m", CLK_IGNORE_UNUSED,
683 RK3399_CLKGATE_CON(3), 6, GFLAGS),
684
685 /* cci */
686 GATE(0, "cpll_aclk_cci_src", "cpll", CLK_IGNORE_UNUSED,
687 RK3399_CLKGATE_CON(2), 0, GFLAGS),
688 GATE(0, "gpll_aclk_cci_src", "gpll", CLK_IGNORE_UNUSED,
689 RK3399_CLKGATE_CON(2), 1, GFLAGS),
690 GATE(0, "npll_aclk_cci_src", "npll", CLK_IGNORE_UNUSED,
691 RK3399_CLKGATE_CON(2), 2, GFLAGS),
692 GATE(0, "vpll_aclk_cci_src", "vpll", CLK_IGNORE_UNUSED,
693 RK3399_CLKGATE_CON(2), 3, GFLAGS),
694
695 COMPOSITE(0, "aclk_cci_pre", mux_aclk_cci_p, CLK_IGNORE_UNUSED,
696 RK3399_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS,
697 RK3399_CLKGATE_CON(2), 4, GFLAGS),
698
699 GATE(ACLK_ADB400M_PD_CORE_L, "aclk_adb400m_pd_core_l", "aclk_cci_pre", CLK_IGNORE_UNUSED,
700 RK3399_CLKGATE_CON(15), 0, GFLAGS),
701 GATE(ACLK_ADB400M_PD_CORE_B, "aclk_adb400m_pd_core_b", "aclk_cci_pre", CLK_IGNORE_UNUSED,
702 RK3399_CLKGATE_CON(15), 1, GFLAGS),
703 GATE(ACLK_CCI, "aclk_cci", "aclk_cci_pre", CLK_IGNORE_UNUSED,
704 RK3399_CLKGATE_CON(15), 2, GFLAGS),
705 GATE(ACLK_CCI_NOC0, "aclk_cci_noc0", "aclk_cci_pre", CLK_IGNORE_UNUSED,
706 RK3399_CLKGATE_CON(15), 3, GFLAGS),
707 GATE(ACLK_CCI_NOC1, "aclk_cci_noc1", "aclk_cci_pre", CLK_IGNORE_UNUSED,
708 RK3399_CLKGATE_CON(15), 4, GFLAGS),
709 GATE(ACLK_CCI_GRF, "aclk_cci_grf", "aclk_cci_pre", CLK_IGNORE_UNUSED,
710 RK3399_CLKGATE_CON(15), 7, GFLAGS),
711
712 GATE(0, "cpll_cci_trace", "cpll", CLK_IGNORE_UNUSED,
713 RK3399_CLKGATE_CON(2), 5, GFLAGS),
714 GATE(0, "gpll_cci_trace", "gpll", CLK_IGNORE_UNUSED,
715 RK3399_CLKGATE_CON(2), 6, GFLAGS),
716 COMPOSITE(SCLK_CCI_TRACE, "clk_cci_trace", mux_cci_trace_p, CLK_IGNORE_UNUSED,
717 RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS,
718 RK3399_CLKGATE_CON(2), 7, GFLAGS),
719
720 GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED,
721 RK3399_CLKGATE_CON(2), 8, GFLAGS),
722 GATE(0, "gpll_cs", "gpll", CLK_IGNORE_UNUSED,
723 RK3399_CLKGATE_CON(2), 9, GFLAGS),
724 GATE(0, "npll_cs", "npll", CLK_IGNORE_UNUSED,
725 RK3399_CLKGATE_CON(2), 10, GFLAGS),
726 COMPOSITE_NOGATE(0, "clk_cs", mux_cs_p, CLK_IGNORE_UNUSED,
727 RK3399_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS),
728 GATE(0, "clk_dbg_cxcs", "clk_cs", CLK_IGNORE_UNUSED,
729 RK3399_CLKGATE_CON(15), 5, GFLAGS),
730 GATE(0, "clk_dbg_noc", "clk_cs", CLK_IGNORE_UNUSED,
731 RK3399_CLKGATE_CON(15), 6, GFLAGS),
732
733 /* vcodec */
734 COMPOSITE(0, "aclk_vcodec_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
735 RK3399_CLKSEL_CON(7), 6, 2, MFLAGS, 0, 5, DFLAGS,
736 RK3399_CLKGATE_CON(4), 0, GFLAGS),
737 COMPOSITE_NOMUX(0, "hclk_vcodec_pre", "aclk_vcodec_pre", 0,
738 RK3399_CLKSEL_CON(7), 8, 5, DFLAGS,
739 RK3399_CLKGATE_CON(4), 1, GFLAGS),
740 GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0,
741 RK3399_CLKGATE_CON(17), 2, GFLAGS),
742 GATE(0, "hclk_vcodec_noc", "hclk_vcodec_pre", CLK_IGNORE_UNUSED,
743 RK3399_CLKGATE_CON(17), 3, GFLAGS),
744
745 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
746 RK3399_CLKGATE_CON(17), 0, GFLAGS),
747 GATE(0, "aclk_vcodec_noc", "aclk_vcodec_pre", CLK_IGNORE_UNUSED,
748 RK3399_CLKGATE_CON(17), 1, GFLAGS),
749
750 /* vdu */
751 COMPOSITE(SCLK_VDU_CORE, "clk_vdu_core", mux_pll_src_cpll_gpll_npll_p, 0,
752 RK3399_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
753 RK3399_CLKGATE_CON(4), 4, GFLAGS),
754 COMPOSITE(SCLK_VDU_CA, "clk_vdu_ca", mux_pll_src_cpll_gpll_npll_p, 0,
755 RK3399_CLKSEL_CON(9), 14, 2, MFLAGS, 8, 5, DFLAGS,
756 RK3399_CLKGATE_CON(4), 5, GFLAGS),
757
758 COMPOSITE(0, "aclk_vdu_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
759 RK3399_CLKSEL_CON(8), 6, 2, MFLAGS, 0, 5, DFLAGS,
760 RK3399_CLKGATE_CON(4), 2, GFLAGS),
761 COMPOSITE_NOMUX(0, "hclk_vdu_pre", "aclk_vdu_pre", 0,
762 RK3399_CLKSEL_CON(8), 8, 5, DFLAGS,
763 RK3399_CLKGATE_CON(4), 3, GFLAGS),
764 GATE(HCLK_VDU, "hclk_vdu", "hclk_vdu_pre", 0,
765 RK3399_CLKGATE_CON(17), 10, GFLAGS),
766 GATE(HCLK_VDU_NOC, "hclk_vdu_noc", "hclk_vdu_pre", CLK_IGNORE_UNUSED,
767 RK3399_CLKGATE_CON(17), 11, GFLAGS),
768
769 GATE(ACLK_VDU, "aclk_vdu", "aclk_vdu_pre", 0,
770 RK3399_CLKGATE_CON(17), 8, GFLAGS),
771 GATE(ACLK_VDU_NOC, "aclk_vdu_noc", "aclk_vdu_pre", CLK_IGNORE_UNUSED,
772 RK3399_CLKGATE_CON(17), 9, GFLAGS),
773
774 /* iep */
775 COMPOSITE(0, "aclk_iep_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
776 RK3399_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS,
777 RK3399_CLKGATE_CON(4), 6, GFLAGS),
778 COMPOSITE_NOMUX(0, "hclk_iep_pre", "aclk_iep_pre", 0,
779 RK3399_CLKSEL_CON(10), 8, 5, DFLAGS,
780 RK3399_CLKGATE_CON(4), 7, GFLAGS),
781 GATE(HCLK_IEP, "hclk_iep", "hclk_iep_pre", 0,
782 RK3399_CLKGATE_CON(16), 2, GFLAGS),
783 GATE(HCLK_IEP_NOC, "hclk_iep_noc", "hclk_iep_pre", CLK_IGNORE_UNUSED,
784 RK3399_CLKGATE_CON(16), 3, GFLAGS),
785
786 GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0,
787 RK3399_CLKGATE_CON(16), 0, GFLAGS),
788 GATE(ACLK_IEP_NOC, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED,
789 RK3399_CLKGATE_CON(16), 1, GFLAGS),
790
791 /* rga */
792 COMPOSITE(SCLK_RGA_CORE, "clk_rga_core", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
793 RK3399_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS,
794 RK3399_CLKGATE_CON(4), 10, GFLAGS),
795
796 COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0,
797 RK3399_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS,
798 RK3399_CLKGATE_CON(4), 8, GFLAGS),
799 COMPOSITE_NOMUX(0, "hclk_rga_pre", "aclk_rga_pre", 0,
800 RK3399_CLKSEL_CON(11), 8, 5, DFLAGS,
801 RK3399_CLKGATE_CON(4), 9, GFLAGS),
802 GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0,
803 RK3399_CLKGATE_CON(16), 10, GFLAGS),
804 GATE(HCLK_RGA_NOC, "hclk_rga_noc", "hclk_rga_pre", CLK_IGNORE_UNUSED,
805 RK3399_CLKGATE_CON(16), 11, GFLAGS),
806
807 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0,
808 RK3399_CLKGATE_CON(16), 8, GFLAGS),
809 GATE(ACLK_RGA_NOC, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED,
810 RK3399_CLKGATE_CON(16), 9, GFLAGS),
811
812 /* center */
813 COMPOSITE(0, "aclk_center", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED,
814 RK3399_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS,
815 RK3399_CLKGATE_CON(3), 7, GFLAGS),
816 GATE(ACLK_CENTER_MAIN_NOC, "aclk_center_main_noc", "aclk_center", CLK_IGNORE_UNUSED,
817 RK3399_CLKGATE_CON(19), 0, GFLAGS),
818 GATE(ACLK_CENTER_PERI_NOC, "aclk_center_peri_noc", "aclk_center", CLK_IGNORE_UNUSED,
819 RK3399_CLKGATE_CON(19), 1, GFLAGS),
820
821 /* gpu */
822 COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_ppll_cpll_gpll_npll_p, CLK_IGNORE_UNUSED,
823 RK3399_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS,
824 RK3399_CLKGATE_CON(13), 0, GFLAGS),
825 GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0,
826 RK3399_CLKGATE_CON(30), 8, GFLAGS),
827 GATE(ACLK_PERF_GPU, "aclk_perf_gpu", "aclk_gpu_pre", 0,
828 RK3399_CLKGATE_CON(30), 10, GFLAGS),
829 GATE(ACLK_GPU_GRF, "aclk_gpu_grf", "aclk_gpu_pre", 0,
830 RK3399_CLKGATE_CON(30), 11, GFLAGS),
831 GATE(SCLK_PVTM_GPU, "aclk_pvtm_gpu", "xin24m", 0,
832 RK3399_CLKGATE_CON(13), 1, GFLAGS),
833
834 /* perihp */
835 GATE(0, "cpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED,
836 RK3399_CLKGATE_CON(5), 0, GFLAGS),
837 GATE(0, "gpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED,
838 RK3399_CLKGATE_CON(5), 1, GFLAGS),
839 COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED,
840 RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS,
841 RK3399_CLKGATE_CON(5), 2, GFLAGS),
842 COMPOSITE_NOMUX(HCLK_PERIHP, "hclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
843 RK3399_CLKSEL_CON(14), 8, 2, DFLAGS,
844 RK3399_CLKGATE_CON(5), 3, GFLAGS),
845 COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED,
846 RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
847 RK3399_CLKGATE_CON(5), 4, GFLAGS),
848
849 GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED,
850 RK3399_CLKGATE_CON(20), 2, GFLAGS),
851 GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED,
852 RK3399_CLKGATE_CON(20), 10, GFLAGS),
853 GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
854 RK3399_CLKGATE_CON(20), 12, GFLAGS),
855
856 GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0,
857 RK3399_CLKGATE_CON(20), 5, GFLAGS),
858 GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0,
859 RK3399_CLKGATE_CON(20), 6, GFLAGS),
860 GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", 0,
861 RK3399_CLKGATE_CON(20), 7, GFLAGS),
862 GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", 0,
863 RK3399_CLKGATE_CON(20), 8, GFLAGS),
864 GATE(HCLK_HSIC, "hclk_hsic", "hclk_perihp", 0,
865 RK3399_CLKGATE_CON(20), 9, GFLAGS),
866 GATE(0, "hclk_perihp_noc", "hclk_perihp", CLK_IGNORE_UNUSED,
867 RK3399_CLKGATE_CON(20), 13, GFLAGS),
868 GATE(0, "hclk_ahb1tom", "hclk_perihp", CLK_IGNORE_UNUSED,
869 RK3399_CLKGATE_CON(20), 15, GFLAGS),
870
871 GATE(PCLK_PERIHP_GRF, "pclk_perihp_grf", "pclk_perihp", CLK_IGNORE_UNUSED,
872 RK3399_CLKGATE_CON(20), 4, GFLAGS),
873 GATE(PCLK_PCIE, "pclk_pcie", "pclk_perihp", 0,
874 RK3399_CLKGATE_CON(20), 11, GFLAGS),
875 GATE(0, "pclk_perihp_noc", "pclk_perihp", CLK_IGNORE_UNUSED,
876 RK3399_CLKGATE_CON(20), 14, GFLAGS),
877 GATE(PCLK_HSICPHY, "pclk_hsicphy", "pclk_perihp", 0,
878 RK3399_CLKGATE_CON(31), 8, GFLAGS),
879
880 /* sdio & sdmmc */
881 COMPOSITE(0, "hclk_sd", mux_pll_src_cpll_gpll_p, 0,
882 RK3399_CLKSEL_CON(13), 15, 1, MFLAGS, 8, 5, DFLAGS,
883 RK3399_CLKGATE_CON(12), 13, GFLAGS),
884 GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0,
885 RK3399_CLKGATE_CON(33), 8, GFLAGS),
886 GATE(0, "hclk_sdmmc_noc", "hclk_sd", CLK_IGNORE_UNUSED,
887 RK3399_CLKGATE_CON(33), 9, GFLAGS),
888
889 COMPOSITE(SCLK_SDIO, "clk_sdio", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, 0,
890 RK3399_CLKSEL_CON(15), 8, 3, MFLAGS, 0, 7, DFLAGS,
891 RK3399_CLKGATE_CON(6), 0, GFLAGS),
892
893 COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, 0,
894 RK3399_CLKSEL_CON(16), 8, 3, MFLAGS, 0, 7, DFLAGS,
895 RK3399_CLKGATE_CON(6), 1, GFLAGS),
896
897 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", RK3399_SDMMC_CON0, 1),
898 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", RK3399_SDMMC_CON1, 1),
899
900 MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RK3399_SDIO_CON0, 1),
901 MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RK3399_SDIO_CON1, 1),
902
903 /* pcie */
904 COMPOSITE(SCLK_PCIE_PM, "clk_pcie_pm", mux_pll_src_cpll_gpll_npll_24m_p, 0,
905 RK3399_CLKSEL_CON(17), 8, 3, MFLAGS, 0, 7, DFLAGS,
906 RK3399_CLKGATE_CON(6), 2, GFLAGS),
907
908 COMPOSITE_NOMUX(SCLK_PCIEPHY_REF100M, "clk_pciephy_ref100m", "npll", 0,
909 RK3399_CLKSEL_CON(18), 11, 5, DFLAGS,
910 RK3399_CLKGATE_CON(12), 6, GFLAGS),
911 MUX(SCLK_PCIEPHY_REF, "clk_pciephy_ref", mux_pll_src_24m_pciephy_p, CLK_SET_RATE_PARENT,
912 RK3399_CLKSEL_CON(18), 10, 1, MFLAGS),
913
914 COMPOSITE(0, "clk_pcie_core_cru", mux_pll_src_cpll_gpll_npll_p, 0,
915 RK3399_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 7, DFLAGS,
916 RK3399_CLKGATE_CON(6), 3, GFLAGS),
917 MUX(SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_p, CLK_SET_RATE_PARENT,
918 RK3399_CLKSEL_CON(18), 7, 1, MFLAGS),
919
920 /* emmc */
921 COMPOSITE(SCLK_EMMC, "clk_emmc", mux_pll_src_cpll_gpll_npll_upll_24m_p, 0,
922 RK3399_CLKSEL_CON(22), 8, 3, MFLAGS, 0, 7, DFLAGS,
923 RK3399_CLKGATE_CON(6), 14, GFLAGS),
924
925 GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED,
926 RK3399_CLKGATE_CON(6), 12, GFLAGS),
927 GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED,
928 RK3399_CLKGATE_CON(6), 13, GFLAGS),
929 COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED,
930 RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS),
931 GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED,
932 RK3399_CLKGATE_CON(32), 8, GFLAGS),
933 GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", CLK_IGNORE_UNUSED,
934 RK3399_CLKGATE_CON(32), 9, GFLAGS),
935 GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", CLK_IGNORE_UNUSED,
936 RK3399_CLKGATE_CON(32), 10, GFLAGS),
937
938 /* perilp0 */
939 GATE(0, "cpll_aclk_perilp0_src", "cpll", CLK_IGNORE_UNUSED,
940 RK3399_CLKGATE_CON(7), 1, GFLAGS),
941 GATE(0, "gpll_aclk_perilp0_src", "gpll", CLK_IGNORE_UNUSED,
942 RK3399_CLKGATE_CON(7), 0, GFLAGS),
943 COMPOSITE(ACLK_PERILP0, "aclk_perilp0", mux_aclk_perilp0_p, CLK_IGNORE_UNUSED,
944 RK3399_CLKSEL_CON(23), 7, 1, MFLAGS, 0, 5, DFLAGS,
945 RK3399_CLKGATE_CON(7), 2, GFLAGS),
946 COMPOSITE_NOMUX(HCLK_PERILP0, "hclk_perilp0", "aclk_perilp0", CLK_IGNORE_UNUSED,
947 RK3399_CLKSEL_CON(23), 8, 2, DFLAGS,
948 RK3399_CLKGATE_CON(7), 3, GFLAGS),
949 COMPOSITE_NOMUX(PCLK_PERILP0, "pclk_perilp0", "aclk_perilp0", 0,
950 RK3399_CLKSEL_CON(23), 12, 3, DFLAGS,
951 RK3399_CLKGATE_CON(7), 4, GFLAGS),
952
953 /* aclk_perilp0 gates */
954 GATE(ACLK_INTMEM, "aclk_intmem", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 0, GFLAGS),
955 GATE(ACLK_TZMA, "aclk_tzma", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 1, GFLAGS),
956 GATE(SCLK_INTMEM0, "clk_intmem0", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 2, GFLAGS),
957 GATE(SCLK_INTMEM1, "clk_intmem1", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 3, GFLAGS),
958 GATE(SCLK_INTMEM2, "clk_intmem2", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 4, GFLAGS),
959 GATE(SCLK_INTMEM3, "clk_intmem3", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 5, GFLAGS),
960 GATE(SCLK_INTMEM4, "clk_intmem4", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 6, GFLAGS),
961 GATE(SCLK_INTMEM5, "clk_intmem5", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 7, GFLAGS),
962 GATE(ACLK_DCF, "aclk_dcf", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 8, GFLAGS),
963 GATE(ACLK_DMAC0_PERILP, "aclk_dmac0_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 5, GFLAGS),
964 GATE(ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 6, GFLAGS),
965 GATE(ACLK_PERILP0_NOC, "aclk_perilp0_noc", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 7, GFLAGS),
966
967 /* hclk_perilp0 gates */
968 GATE(HCLK_ROM, "hclk_rom", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 4, GFLAGS),
969 GATE(HCLK_M_CRYPTO0, "hclk_m_crypto0", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 5, GFLAGS),
970 GATE(HCLK_S_CRYPTO0, "hclk_s_crypto0", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 6, GFLAGS),
971 GATE(HCLK_M_CRYPTO1, "hclk_m_crypto1", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 14, GFLAGS),
972 GATE(HCLK_S_CRYPTO1, "hclk_s_crypto1", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 15, GFLAGS),
973 GATE(HCLK_PERILP0_NOC, "hclk_perilp0_noc", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 8, GFLAGS),
974
975 /* pclk_perilp0 gates */
976 GATE(PCLK_DCF, "pclk_dcf", "pclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 9, GFLAGS),
977
978 /* crypto */
979 COMPOSITE(SCLK_CRYPTO0, "clk_crypto0", mux_pll_src_cpll_gpll_ppll_p, 0,
980 RK3399_CLKSEL_CON(24), 6, 2, MFLAGS, 0, 5, DFLAGS,
981 RK3399_CLKGATE_CON(7), 7, GFLAGS),
982
983 COMPOSITE(SCLK_CRYPTO1, "clk_crypto1", mux_pll_src_cpll_gpll_ppll_p, 0,
984 RK3399_CLKSEL_CON(26), 6, 2, MFLAGS, 0, 5, DFLAGS,
985 RK3399_CLKGATE_CON(7), 8, GFLAGS),
986
987 /* cm0s_perilp */
988 GATE(0, "cpll_fclk_cm0s_src", "cpll", 0,
989 RK3399_CLKGATE_CON(7), 6, GFLAGS),
990 GATE(0, "gpll_fclk_cm0s_src", "gpll", 0,
991 RK3399_CLKGATE_CON(7), 5, GFLAGS),
992 COMPOSITE(FCLK_CM0S, "fclk_cm0s", mux_fclk_cm0s_p, 0,
993 RK3399_CLKSEL_CON(24), 15, 1, MFLAGS, 8, 5, DFLAGS,
994 RK3399_CLKGATE_CON(7), 9, GFLAGS),
995
996 /* fclk_cm0s gates */
997 GATE(SCLK_M0_PERILP, "sclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 8, GFLAGS),
998 GATE(HCLK_M0_PERILP, "hclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 9, GFLAGS),
999 GATE(DCLK_M0_PERILP, "dclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 10, GFLAGS),
1000 GATE(SCLK_M0_PERILP_DEC, "clk_m0_perilp_dec", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 11, GFLAGS),
1001 GATE(HCLK_M0_PERILP_NOC, "hclk_m0_perilp_noc", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 11, GFLAGS),
1002
1003 /* perilp1 */
1004 GATE(0, "cpll_hclk_perilp1_src", "cpll", CLK_IGNORE_UNUSED,
1005 RK3399_CLKGATE_CON(8), 1, GFLAGS),
1006 GATE(0, "gpll_hclk_perilp1_src", "gpll", CLK_IGNORE_UNUSED,
1007 RK3399_CLKGATE_CON(8), 0, GFLAGS),
1008 COMPOSITE_NOGATE(HCLK_PERILP1, "hclk_perilp1", mux_hclk_perilp1_p, CLK_IGNORE_UNUSED,
1009 RK3399_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 5, DFLAGS),
1010 COMPOSITE_NOMUX(PCLK_PERILP1, "pclk_perilp1", "hclk_perilp1", CLK_IGNORE_UNUSED,
1011 RK3399_CLKSEL_CON(25), 8, 3, DFLAGS,
1012 RK3399_CLKGATE_CON(8), 2, GFLAGS),
1013
1014 /* hclk_perilp1 gates */
1015 GATE(0, "hclk_perilp1_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 9, GFLAGS),
1016 GATE(0, "hclk_sdio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 12, GFLAGS),
1017 GATE(HCLK_I2S0_8CH, "hclk_i2s0", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 0, GFLAGS),
1018 GATE(HCLK_I2S1_8CH, "hclk_i2s1", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 1, GFLAGS),
1019 GATE(HCLK_I2S2_8CH, "hclk_i2s2", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 2, GFLAGS),
1020 GATE(HCLK_SPDIF, "hclk_spdif", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 3, GFLAGS),
1021 GATE(HCLK_SDIO, "hclk_sdio", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 4, GFLAGS),
1022 GATE(PCLK_SPI5, "pclk_spi5", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 5, GFLAGS),
1023 GATE(0, "hclk_sdioaudio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 6, GFLAGS),
1024
1025 /* pclk_perilp1 gates */
1026 GATE(PCLK_UART0, "pclk_uart0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 0, GFLAGS),
1027 GATE(PCLK_UART1, "pclk_uart1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 1, GFLAGS),
1028 GATE(PCLK_UART2, "pclk_uart2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 2, GFLAGS),
1029 GATE(PCLK_UART3, "pclk_uart3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 3, GFLAGS),
1030 GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 5, GFLAGS),
1031 GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 6, GFLAGS),
1032 GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 7, GFLAGS),
1033 GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 8, GFLAGS),
1034 GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 9, GFLAGS),
1035 GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 10, GFLAGS),
1036 GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 11, GFLAGS),
1037 GATE(PCLK_SARADC, "pclk_saradc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 12, GFLAGS),
1038 GATE(PCLK_TSADC, "pclk_tsadc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 13, GFLAGS),
1039 GATE(PCLK_EFUSE1024NS, "pclk_efuse1024ns", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 14, GFLAGS),
1040 GATE(PCLK_EFUSE1024S, "pclk_efuse1024s", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 15, GFLAGS),
1041 GATE(PCLK_SPI0, "pclk_spi0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 10, GFLAGS),
1042 GATE(PCLK_SPI1, "pclk_spi1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 11, GFLAGS),
1043 GATE(PCLK_SPI2, "pclk_spi2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 12, GFLAGS),
1044 GATE(PCLK_SPI4, "pclk_spi4", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 13, GFLAGS),
1045 GATE(PCLK_PERIHP_GRF, "pclk_perilp_sgrf", "pclk_perilp1", 0, RK3399_CLKGATE_CON(24), 13, GFLAGS),
1046 GATE(0, "pclk_perilp1_noc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(25), 10, GFLAGS),
1047
1048 /* saradc */
1049 COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0,
1050 RK3399_CLKSEL_CON(26), 8, 8, DFLAGS,
1051 RK3399_CLKGATE_CON(9), 11, GFLAGS),
1052
1053 /* tsadc */
1054 COMPOSITE(SCLK_TSADC, "clk_tsadc", mux_pll_p, 0,
1055 RK3399_CLKSEL_CON(27), 15, 1, MFLAGS, 0, 10, DFLAGS,
1056 RK3399_CLKGATE_CON(9), 10, GFLAGS),
1057
1058 /* cif_testout */
1059 MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0,
1060 RK3399_CLKSEL_CON(38), 6, 2, MFLAGS),
1061 COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0,
1062 RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS,
1063 RK3399_CLKGATE_CON(13), 14, GFLAGS),
1064
1065 MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0,
1066 RK3399_CLKSEL_CON(38), 14, 2, MFLAGS),
1067 COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0,
1068 RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS,
1069 RK3399_CLKGATE_CON(13), 15, GFLAGS),
1070
1071 /* vio */
1072 COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED,
1073 RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS,
1074 RK3399_CLKGATE_CON(11), 10, GFLAGS),
1075 COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0,
1076 RK3399_CLKSEL_CON(43), 0, 5, DFLAGS,
1077 RK3399_CLKGATE_CON(11), 1, GFLAGS),
1078
1079 GATE(ACLK_VIO_NOC, "aclk_vio_noc", "aclk_vio", CLK_IGNORE_UNUSED,
1080 RK3399_CLKGATE_CON(29), 0, GFLAGS),
1081
1082 GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "pclk_vio", 0,
1083 RK3399_CLKGATE_CON(29), 1, GFLAGS),
1084 GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "pclk_vio", 0,
1085 RK3399_CLKGATE_CON(29), 2, GFLAGS),
1086 GATE(PCLK_VIO_GRF, "pclk_vio_grf", "pclk_vio", CLK_IGNORE_UNUSED,
1087 RK3399_CLKGATE_CON(29), 12, GFLAGS),
1088
1089 /* hdcp */
1090 COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0,
1091 RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS,
1092 RK3399_CLKGATE_CON(11), 12, GFLAGS),
1093 COMPOSITE_NOMUX(HCLK_HDCP, "hclk_hdcp", "aclk_hdcp", 0,
1094 RK3399_CLKSEL_CON(43), 5, 5, DFLAGS,
1095 RK3399_CLKGATE_CON(11), 3, GFLAGS),
1096 COMPOSITE_NOMUX(PCLK_HDCP, "pclk_hdcp", "aclk_hdcp", 0,
1097 RK3399_CLKSEL_CON(43), 10, 5, DFLAGS,
1098 RK3399_CLKGATE_CON(11), 10, GFLAGS),
1099
1100 GATE(ACLK_HDCP_NOC, "aclk_hdcp_noc", "aclk_hdcp", CLK_IGNORE_UNUSED,
1101 RK3399_CLKGATE_CON(29), 4, GFLAGS),
1102 GATE(ACLK_HDCP22, "aclk_hdcp22", "aclk_hdcp", 0,
1103 RK3399_CLKGATE_CON(29), 10, GFLAGS),
1104
1105 GATE(HCLK_HDCP_NOC, "hclk_hdcp_noc", "hclk_hdcp", CLK_IGNORE_UNUSED,
1106 RK3399_CLKGATE_CON(29), 5, GFLAGS),
1107 GATE(HCLK_HDCP22, "hclk_hdcp22", "hclk_hdcp", 0,
1108 RK3399_CLKGATE_CON(29), 9, GFLAGS),
1109
1110 GATE(PCLK_HDCP_NOC, "pclk_hdcp_noc", "pclk_hdcp", CLK_IGNORE_UNUSED,
1111 RK3399_CLKGATE_CON(29), 3, GFLAGS),
1112 GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_hdcp", 0,
1113 RK3399_CLKGATE_CON(29), 6, GFLAGS),
1114 GATE(PCLK_DP_CTRL, "pclk_dp_ctrl", "pclk_hdcp", 0,
1115 RK3399_CLKGATE_CON(29), 7, GFLAGS),
1116 GATE(PCLK_HDCP22, "pclk_hdcp22", "pclk_hdcp", 0,
1117 RK3399_CLKGATE_CON(29), 8, GFLAGS),
1118 GATE(PCLK_GASKET, "pclk_gasket", "pclk_hdcp", 0,
1119 RK3399_CLKGATE_CON(29), 11, GFLAGS),
1120
1121 /* edp */
1122 COMPOSITE(SCLK_DP_CORE, "clk_dp_core", mux_pll_src_npll_cpll_gpll_p, 0,
1123 RK3399_CLKSEL_CON(46), 6, 2, MFLAGS, 0, 5, DFLAGS,
1124 RK3399_CLKGATE_CON(11), 8, GFLAGS),
1125
1126 COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0,
1127 RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS,
1128 RK3399_CLKGATE_CON(11), 11, GFLAGS),
1129 GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
1130 RK3399_CLKGATE_CON(32), 12, GFLAGS),
1131 GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_edp", 0,
1132 RK3399_CLKGATE_CON(32), 13, GFLAGS),
1133
1134 /* hdmi */
1135 GATE(SCLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0,
1136 RK3399_CLKGATE_CON(11), 6, GFLAGS),
1137
1138 COMPOSITE(SCLK_HDMI_CEC, "clk_hdmi_cec", mux_pll_p, 0,
1139 RK3399_CLKSEL_CON(45), 15, 1, MFLAGS, 0, 10, DFLAGS,
1140 RK3399_CLKGATE_CON(11), 7, GFLAGS),
1141
1142 /* vop0 */
1143 COMPOSITE(ACLK_VOP0_PRE, "aclk_vop0_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
1144 RK3399_CLKSEL_CON(47), 6, 2, MFLAGS, 0, 5, DFLAGS,
1145 RK3399_CLKGATE_CON(10), 8, GFLAGS),
1146 COMPOSITE_NOMUX(0, "hclk_vop0_pre", "aclk_vop0_pre", 0,
1147 RK3399_CLKSEL_CON(47), 8, 5, DFLAGS,
1148 RK3399_CLKGATE_CON(10), 9, GFLAGS),
1149
1150 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vop0_pre", 0,
1151 RK3399_CLKGATE_CON(28), 3, GFLAGS),
1152 GATE(ACLK_VOP0_NOC, "aclk_vop0_noc", "aclk_vop0_pre", CLK_IGNORE_UNUSED,
1153 RK3399_CLKGATE_CON(28), 1, GFLAGS),
1154
1155 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vop0_pre", 0,
1156 RK3399_CLKGATE_CON(28), 2, GFLAGS),
1157 GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED,
1158 RK3399_CLKGATE_CON(28), 0, GFLAGS),
1159
1160 COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, 0,
1161 RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS,
1162 RK3399_CLKGATE_CON(10), 12, GFLAGS),
1163
1164 COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT,
1165 RK3399_CLKSEL_CON(106), 0,
1166 &rk3399_dclk_vop0_fracmux),
1167
1168 COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, 0,
1169 RK3399_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS,
1170 RK3399_CLKGATE_CON(10), 14, GFLAGS),
1171
1172 /* vop1 */
1173 COMPOSITE(ACLK_VOP1_PRE, "aclk_vop1_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0,
1174 RK3399_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
1175 RK3399_CLKGATE_CON(10), 10, GFLAGS),
1176 COMPOSITE_NOMUX(0, "hclk_vop1_pre", "aclk_vop1_pre", 0,
1177 RK3399_CLKSEL_CON(48), 8, 5, DFLAGS,
1178 RK3399_CLKGATE_CON(10), 11, GFLAGS),
1179
1180 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vop1_pre", 0,
1181 RK3399_CLKGATE_CON(28), 7, GFLAGS),
1182 GATE(ACLK_VOP1_NOC, "aclk_vop1_noc", "aclk_vop1_pre", CLK_IGNORE_UNUSED,
1183 RK3399_CLKGATE_CON(28), 5, GFLAGS),
1184
1185 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vop1_pre", 0,
1186 RK3399_CLKGATE_CON(28), 6, GFLAGS),
1187 GATE(HCLK_VOP1_NOC, "hclk_vop1_noc", "hclk_vop1_pre", CLK_IGNORE_UNUSED,
1188 RK3399_CLKGATE_CON(28), 4, GFLAGS),
1189
1190 COMPOSITE(DCLK_VOP1_DIV, "dclk_vop1_div", mux_pll_src_vpll_cpll_gpll_p, 0,
1191 RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS,
1192 RK3399_CLKGATE_CON(10), 13, GFLAGS),
1193
1194 COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT,
1195 RK3399_CLKSEL_CON(107), 0,
1196 &rk3399_dclk_vop1_fracmux),
1197
1198 COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED,
1199 RK3399_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 5, DFLAGS,
1200 RK3399_CLKGATE_CON(10), 15, GFLAGS),
1201
1202 /* isp */
1203 COMPOSITE(ACLK_ISP0, "aclk_isp0", mux_pll_src_cpll_gpll_ppll_p, 0,
1204 RK3399_CLKSEL_CON(53), 6, 2, MFLAGS, 0, 5, DFLAGS,
1205 RK3399_CLKGATE_CON(12), 8, GFLAGS),
1206 COMPOSITE_NOMUX(HCLK_ISP0, "hclk_isp0", "aclk_isp0", 0,
1207 RK3399_CLKSEL_CON(53), 8, 5, DFLAGS,
1208 RK3399_CLKGATE_CON(12), 9, GFLAGS),
1209
1210 GATE(ACLK_ISP0_NOC, "aclk_isp0_noc", "aclk_isp0", CLK_IGNORE_UNUSED,
1211 RK3399_CLKGATE_CON(27), 1, GFLAGS),
1212 GATE(ACLK_ISP0_WRAPPER, "aclk_isp0_wrapper", "aclk_isp0", 0,
1213 RK3399_CLKGATE_CON(27), 5, GFLAGS),
1214 GATE(HCLK_ISP1_WRAPPER, "hclk_isp1_wrapper", "aclk_isp0", 0,
1215 RK3399_CLKGATE_CON(27), 7, GFLAGS),
1216
1217 GATE(HCLK_ISP0_NOC, "hclk_isp0_noc", "hclk_isp0", CLK_IGNORE_UNUSED,
1218 RK3399_CLKGATE_CON(27), 0, GFLAGS),
1219 GATE(HCLK_ISP0_WRAPPER, "hclk_isp0_wrapper", "hclk_isp0", 0,
1220 RK3399_CLKGATE_CON(27), 4, GFLAGS),
1221
1222 COMPOSITE(SCLK_ISP0, "clk_isp0", mux_pll_src_cpll_gpll_npll_p, 0,
1223 RK3399_CLKSEL_CON(55), 6, 2, MFLAGS, 0, 5, DFLAGS,
1224 RK3399_CLKGATE_CON(11), 4, GFLAGS),
1225
1226 COMPOSITE(ACLK_ISP1, "aclk_isp1", mux_pll_src_cpll_gpll_ppll_p, 0,
1227 RK3399_CLKSEL_CON(54), 6, 2, MFLAGS, 0, 5, DFLAGS,
1228 RK3399_CLKGATE_CON(12), 10, GFLAGS),
1229 COMPOSITE_NOMUX(HCLK_ISP1, "hclk_isp1", "aclk_isp1", 0,
1230 RK3399_CLKSEL_CON(54), 8, 5, DFLAGS,
1231 RK3399_CLKGATE_CON(12), 11, GFLAGS),
1232
1233 GATE(ACLK_ISP1_NOC, "aclk_isp1_noc", "aclk_isp1", CLK_IGNORE_UNUSED,
1234 RK3399_CLKGATE_CON(27), 3, GFLAGS),
1235
1236 GATE(HCLK_ISP1_NOC, "hclk_isp1_noc", "hclk_isp1", CLK_IGNORE_UNUSED,
1237 RK3399_CLKGATE_CON(27), 2, GFLAGS),
1238 GATE(ACLK_ISP1_WRAPPER, "aclk_isp1_wrapper", "hclk_isp1", 0,
1239 RK3399_CLKGATE_CON(27), 8, GFLAGS),
1240
1241 COMPOSITE(SCLK_ISP1, "clk_isp1", mux_pll_src_cpll_gpll_npll_p, 0,
1242 RK3399_CLKSEL_CON(55), 14, 2, MFLAGS, 8, 5, DFLAGS,
1243 RK3399_CLKGATE_CON(11), 5, GFLAGS),
1244
1245 /*
1246 * We use pclkin_cifinv by default GRF_SOC_CON20[9] (GSC20_9) setting in system,
1247 * so we ignore the mux and make clocks nodes as following,
1248 *
1249 * pclkin_cifinv --|-------\
1250 * |GSC20_9|-- pclkin_cifmux -- |G27_6| -- pclkin_isp1_wrapper
1251 * pclkin_cif --|-------/
1252 */
1253 GATE(PCLK_ISP1_WRAPPER, "pclkin_isp1_wrapper", "pclkin_cif", 0,
1254 RK3399_CLKGATE_CON(27), 6, GFLAGS),
1255
1256 /* cif */
1257 COMPOSITE_NODIV(0, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0,
1258 RK3399_CLKSEL_CON(56), 6, 2, MFLAGS,
1259 RK3399_CLKGATE_CON(10), 7, GFLAGS),
1260
1261 COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0,
1262 RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS),
1263
1264 /* gic */
1265 COMPOSITE(ACLK_GIC_PRE, "aclk_gic_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
1266 RK3399_CLKSEL_CON(56), 15, 1, MFLAGS, 8, 5, DFLAGS,
1267 RK3399_CLKGATE_CON(12), 12, GFLAGS),
1268
1269 GATE(ACLK_GIC, "aclk_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 0, GFLAGS),
1270 GATE(ACLK_GIC_NOC, "aclk_gic_noc", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 1, GFLAGS),
1271 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),
1272 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),
1273 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),
1274 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),
1275
1276 /* alive */
1277 /* pclk_alive_gpll_src is controlled by PMUGRF_SOC_CON0[6] */
1278 DIV(PCLK_ALIVE, "pclk_alive", "gpll", 0,
1279 RK3399_CLKSEL_CON(57), 0, 5, DFLAGS),
1280
1281 GATE(PCLK_USBPHY_MUX_G, "pclk_usbphy_mux_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 4, GFLAGS),
1282 GATE(PCLK_UPHY0_TCPHY_G, "pclk_uphy0_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 5, GFLAGS),
1283 GATE(PCLK_UPHY0_TCPD_G, "pclk_uphy0_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 6, GFLAGS),
1284 GATE(PCLK_UPHY1_TCPHY_G, "pclk_uphy1_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 8, GFLAGS),
1285 GATE(PCLK_UPHY1_TCPD_G, "pclk_uphy1_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 9, GFLAGS),
1286
1287 GATE(PCLK_GRF, "pclk_grf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 1, GFLAGS),
1288 GATE(PCLK_INTR_ARB, "pclk_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 2, GFLAGS),
1289 GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 3, GFLAGS),
1290 GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 4, GFLAGS),
1291 GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 5, GFLAGS),
1292 GATE(PCLK_TIMER0, "pclk_timer0", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 6, GFLAGS),
1293 GATE(PCLK_TIMER1, "pclk_timer1", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 7, GFLAGS),
1294 GATE(PCLK_PMU_INTR_ARB, "pclk_pmu_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 9, GFLAGS),
1295 GATE(PCLK_SGRF, "pclk_sgrf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 10, GFLAGS),
1296
1297 GATE(SCLK_MIPIDPHY_REF, "clk_mipidphy_ref", "xin24m", 0, RK3399_CLKGATE_CON(11), 14, GFLAGS),
1298 GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 0, GFLAGS),
1299
1300 GATE(SCLK_MIPIDPHY_CFG, "clk_mipidphy_cfg", "xin24m", 0, RK3399_CLKGATE_CON(11), 15, GFLAGS),
1301 GATE(SCLK_DPHY_TX0_CFG, "clk_dphy_tx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 1, GFLAGS),
1302 GATE(SCLK_DPHY_TX1RX1_CFG, "clk_dphy_tx1rx1_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 2, GFLAGS),
1303 GATE(SCLK_DPHY_RX0_CFG, "clk_dphy_rx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 3, GFLAGS),
1304
1305 /* testout */
1306 MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT,
1307 RK3399_CLKSEL_CON(58), 7, 1, MFLAGS),
1308 COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT,
1309 RK3399_CLKSEL_CON(105), 0,
1310 RK3399_CLKGATE_CON(13), 9, GFLAGS),
1311
1312 DIV(0, "clk_test_24m", "xin24m", 0,
1313 RK3399_CLKSEL_CON(57), 6, 10, DFLAGS),
1314
1315 /* spi */
1316 COMPOSITE(SCLK_SPI0, "clk_spi0", mux_pll_src_cpll_gpll_p, 0,
1317 RK3399_CLKSEL_CON(59), 7, 1, MFLAGS, 0, 7, DFLAGS,
1318 RK3399_CLKGATE_CON(9), 12, GFLAGS),
1319
1320 COMPOSITE(SCLK_SPI1, "clk_spi1", mux_pll_src_cpll_gpll_p, 0,
1321 RK3399_CLKSEL_CON(59), 15, 1, MFLAGS, 8, 7, DFLAGS,
1322 RK3399_CLKGATE_CON(9), 13, GFLAGS),
1323
1324 COMPOSITE(SCLK_SPI2, "clk_spi2", mux_pll_src_cpll_gpll_p, 0,
1325 RK3399_CLKSEL_CON(60), 7, 1, MFLAGS, 0, 7, DFLAGS,
1326 RK3399_CLKGATE_CON(9), 14, GFLAGS),
1327
1328 COMPOSITE(SCLK_SPI4, "clk_spi4", mux_pll_src_cpll_gpll_p, 0,
1329 RK3399_CLKSEL_CON(60), 15, 1, MFLAGS, 8, 7, DFLAGS,
1330 RK3399_CLKGATE_CON(9), 15, GFLAGS),
1331
1332 COMPOSITE(SCLK_SPI5, "clk_spi5", mux_pll_src_cpll_gpll_p, 0,
1333 RK3399_CLKSEL_CON(58), 15, 1, MFLAGS, 8, 7, DFLAGS,
1334 RK3399_CLKGATE_CON(13), 13, GFLAGS),
1335
1336 /* i2c */
1337 COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_cpll_gpll_p, 0,
1338 RK3399_CLKSEL_CON(61), 7, 1, MFLAGS, 0, 7, DFLAGS,
1339 RK3399_CLKGATE_CON(10), 0, GFLAGS),
1340
1341 COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_cpll_gpll_p, 0,
1342 RK3399_CLKSEL_CON(62), 7, 1, MFLAGS, 0, 7, DFLAGS,
1343 RK3399_CLKGATE_CON(10), 2, GFLAGS),
1344
1345 COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_cpll_gpll_p, 0,
1346 RK3399_CLKSEL_CON(63), 7, 1, MFLAGS, 0, 7, DFLAGS,
1347 RK3399_CLKGATE_CON(10), 4, GFLAGS),
1348
1349 COMPOSITE(SCLK_I2C5, "clk_i2c5", mux_pll_src_cpll_gpll_p, 0,
1350 RK3399_CLKSEL_CON(61), 15, 1, MFLAGS, 8, 7, DFLAGS,
1351 RK3399_CLKGATE_CON(10), 1, GFLAGS),
1352
1353 COMPOSITE(SCLK_I2C6, "clk_i2c6", mux_pll_src_cpll_gpll_p, 0,
1354 RK3399_CLKSEL_CON(62), 15, 1, MFLAGS, 8, 7, DFLAGS,
1355 RK3399_CLKGATE_CON(10), 3, GFLAGS),
1356
1357 COMPOSITE(SCLK_I2C7, "clk_i2c7", mux_pll_src_cpll_gpll_p, 0,
1358 RK3399_CLKSEL_CON(63), 15, 1, MFLAGS, 8, 7, DFLAGS,
1359 RK3399_CLKGATE_CON(10), 5, GFLAGS),
1360
1361 /* timer */
1362 GATE(SCLK_TIMER00, "clk_timer00", "xin24m", 0, RK3399_CLKGATE_CON(26), 0, GFLAGS),
1363 GATE(SCLK_TIMER01, "clk_timer01", "xin24m", 0, RK3399_CLKGATE_CON(26), 1, GFLAGS),
1364 GATE(SCLK_TIMER02, "clk_timer02", "xin24m", 0, RK3399_CLKGATE_CON(26), 2, GFLAGS),
1365 GATE(SCLK_TIMER03, "clk_timer03", "xin24m", 0, RK3399_CLKGATE_CON(26), 3, GFLAGS),
1366 GATE(SCLK_TIMER04, "clk_timer04", "xin24m", 0, RK3399_CLKGATE_CON(26), 4, GFLAGS),
1367 GATE(SCLK_TIMER05, "clk_timer05", "xin24m", 0, RK3399_CLKGATE_CON(26), 5, GFLAGS),
1368 GATE(SCLK_TIMER06, "clk_timer06", "xin24m", 0, RK3399_CLKGATE_CON(26), 6, GFLAGS),
1369 GATE(SCLK_TIMER07, "clk_timer07", "xin24m", 0, RK3399_CLKGATE_CON(26), 7, GFLAGS),
1370 GATE(SCLK_TIMER08, "clk_timer08", "xin24m", 0, RK3399_CLKGATE_CON(26), 8, GFLAGS),
1371 GATE(SCLK_TIMER09, "clk_timer09", "xin24m", 0, RK3399_CLKGATE_CON(26), 9, GFLAGS),
1372 GATE(SCLK_TIMER10, "clk_timer10", "xin24m", 0, RK3399_CLKGATE_CON(26), 10, GFLAGS),
1373 GATE(SCLK_TIMER11, "clk_timer11", "xin24m", 0, RK3399_CLKGATE_CON(26), 11, GFLAGS),
1374
1375 /* clk_test */
1376 /* clk_test_pre is controlled by CRU_MISC_CON[3] */
1377 COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
1378 RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
1379 RK3368_CLKGATE_CON(13), 11, GFLAGS),
1380};
1381
1382static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
1383 /*
1384 * PMU CRU Clock-Architecture
1385 */
1386
1387 GATE(0, "fclk_cm0s_pmu_ppll_src", "ppll", 0,
1388 RK3399_PMU_CLKGATE_CON(0), 1, GFLAGS),
1389
1390 COMPOSITE_NOGATE(FCLK_CM0S_SRC_PMU, "fclk_cm0s_src_pmu", mux_fclk_cm0s_pmu_ppll_p, 0,
1391 RK3399_PMU_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS),
1392
1393 COMPOSITE(SCLK_SPI3_PMU, "clk_spi3_pmu", mux_24m_ppll_p, 0,
1394 RK3399_PMU_CLKSEL_CON(1), 7, 1, MFLAGS, 0, 7, DFLAGS,
1395 RK3399_PMU_CLKGATE_CON(0), 2, GFLAGS),
1396
1397 COMPOSITE(0, "clk_wifi_div", mux_ppll_24m_p, CLK_IGNORE_UNUSED,
1398 RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
1399 RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS),
1400
1401 COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT,
1402 RK3399_PMU_CLKSEL_CON(7), 0,
1403 &rk3399_pmuclk_wifi_fracmux),
1404
1405 MUX(0, "clk_timer_src_pmu", mux_pll_p, CLK_IGNORE_UNUSED,
1406 RK3399_PMU_CLKSEL_CON(1), 15, 1, MFLAGS),
1407
1408 COMPOSITE_NOMUX(SCLK_I2C0_PMU, "clk_i2c0_pmu", "ppll", 0,
1409 RK3399_PMU_CLKSEL_CON(2), 0, 7, DFLAGS,
1410 RK3399_PMU_CLKGATE_CON(0), 9, GFLAGS),
1411
1412 COMPOSITE_NOMUX(SCLK_I2C4_PMU, "clk_i2c4_pmu", "ppll", 0,
1413 RK3399_PMU_CLKSEL_CON(3), 0, 7, DFLAGS,
1414 RK3399_PMU_CLKGATE_CON(0), 10, GFLAGS),
1415
1416 COMPOSITE_NOMUX(SCLK_I2C8_PMU, "clk_i2c8_pmu", "ppll", 0,
1417 RK3399_PMU_CLKSEL_CON(2), 8, 7, DFLAGS,
1418 RK3399_PMU_CLKGATE_CON(0), 11, GFLAGS),
1419
1420 DIV(0, "clk_32k_suspend_pmu", "xin24m", CLK_IGNORE_UNUSED,
1421 RK3399_PMU_CLKSEL_CON(4), 0, 10, DFLAGS),
1422 MUX(0, "clk_testout_2io", mux_clk_testout2_2io_p, CLK_IGNORE_UNUSED,
1423 RK3399_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
1424
1425 COMPOSITE(0, "clk_uart4_div", mux_24m_ppll_p, 0,
1426 RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
1427 RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS),
1428
1429 COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT,
1430 RK3399_PMU_CLKSEL_CON(6), 0,
1431 RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS,
1432 &rk3399_uart4_pmu_fracmux),
1433
1434 DIV(PCLK_SRC_PMU, "pclk_pmu_src", "ppll", CLK_IGNORE_UNUSED,
1435 RK3399_PMU_CLKSEL_CON(0), 0, 5, DFLAGS),
1436
1437 /* pmu clock gates */
1438 GATE(SCLK_TIMER12_PMU, "clk_timer0_pmu", "clk_timer_src_pmu", 0, RK3399_PMU_CLKGATE_CON(0), 3, GFLAGS),
1439 GATE(SCLK_TIMER13_PMU, "clk_timer1_pmu", "clk_timer_src_pmu", 0, RK3399_PMU_CLKGATE_CON(0), 4, GFLAGS),
1440
1441 GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 7, GFLAGS),
1442
1443 GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 0, GFLAGS),
1444 GATE(PCLK_PMUGRF_PMU, "pclk_pmugrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 1, GFLAGS),
1445 GATE(PCLK_INTMEM1_PMU, "pclk_intmem1_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 2, GFLAGS),
1446 GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 3, GFLAGS),
1447 GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 4, GFLAGS),
1448 GATE(PCLK_SGRF_PMU, "pclk_sgrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 5, GFLAGS),
1449 GATE(PCLK_NOC_PMU, "pclk_noc_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 6, GFLAGS),
1450 GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 7, GFLAGS),
1451 GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 8, GFLAGS),
1452 GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 9, GFLAGS),
1453 GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 10, GFLAGS),
1454 GATE(PCLK_SPI3_PMU, "pclk_spi3_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 11, GFLAGS),
1455 GATE(PCLK_TIMER_PMU, "pclk_timer_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 12, GFLAGS),
1456 GATE(PCLK_MAILBOX_PMU, "pclk_mailbox_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 13, GFLAGS),
1457 GATE(PCLK_UART4_PMU, "pclk_uart4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 14, GFLAGS),
1458 GATE(PCLK_WDT_M0_PMU, "pclk_wdt_m0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 15, GFLAGS),
1459
1460 GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 0, GFLAGS),
1461 GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 1, GFLAGS),
1462 GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 2, GFLAGS),
1463 GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 3, GFLAGS),
1464 GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 5, GFLAGS),
1465};
1466
1467static const char *const rk3399_cru_critical_clocks[] __initconst = {
1468 "aclk_cci_pre",
1469 "pclk_perilp0",
1470 "pclk_perilp0",
1471 "hclk_perilp0",
1472 "hclk_perilp0_noc",
1473 "pclk_perilp1",
1474 "pclk_perilp1_noc",
1475 "pclk_perihp",
1476 "pclk_perihp_noc",
1477 "hclk_perihp",
1478 "aclk_perihp",
1479 "aclk_perihp_noc",
1480 "aclk_perilp0",
1481 "aclk_perilp0_noc",
1482 "hclk_perilp1",
1483 "hclk_perilp1_noc",
1484 "aclk_dmac0_perilp",
1485 "gpll_hclk_perilp1_src",
1486 "gpll_aclk_perilp0_src",
1487 "gpll_aclk_perihp_src",
1488};
1489
1490static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
1491 "ppll",
1492 "pclk_pmu_src",
1493 "fclk_cm0s_src_pmu",
1494 "clk_timer_src_pmu",
1495};
1496
1497static void __init rk3399_clk_init(struct device_node *np)
1498{
1499 struct rockchip_clk_provider *ctx;
1500 void __iomem *reg_base;
1501
1502 reg_base = of_iomap(np, 0);
1503 if (!reg_base) {
1504 pr_err("%s: could not map cru region\n", __func__);
1505 return;
1506 }
1507
1508 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
1509 if (IS_ERR(ctx)) {
1510 pr_err("%s: rockchip clk init failed\n", __func__);
1511 return;
1512 }
1513
1514 rockchip_clk_register_plls(ctx, rk3399_pll_clks,
1515 ARRAY_SIZE(rk3399_pll_clks), -1);
1516
1517 rockchip_clk_register_branches(ctx, rk3399_clk_branches,
1518 ARRAY_SIZE(rk3399_clk_branches));
1519
1520 rockchip_clk_protect_critical(rk3399_cru_critical_clocks,
1521 ARRAY_SIZE(rk3399_cru_critical_clocks));
1522
1523 rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl",
1524 mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p),
1525 &rk3399_cpuclkl_data, rk3399_cpuclkl_rates,
1526 ARRAY_SIZE(rk3399_cpuclkl_rates));
1527
1528 rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb",
1529 mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p),
1530 &rk3399_cpuclkb_data, rk3399_cpuclkb_rates,
1531 ARRAY_SIZE(rk3399_cpuclkb_rates));
1532
1533 rockchip_register_softrst(np, 21, reg_base + RK3399_SOFTRST_CON(0),
1534 ROCKCHIP_SOFTRST_HIWORD_MASK);
1535
1536 rockchip_register_restart_notifier(ctx, RK3399_GLB_SRST_FST, NULL);
1537
1538 rockchip_clk_of_add_provider(np, ctx);
1539}
1540CLK_OF_DECLARE(rk3399_cru, "rockchip,rk3399-cru", rk3399_clk_init);
1541
1542static void __init rk3399_pmu_clk_init(struct device_node *np)
1543{
1544 struct rockchip_clk_provider *ctx;
1545 void __iomem *reg_base;
1546
1547 reg_base = of_iomap(np, 0);
1548 if (!reg_base) {
1549 pr_err("%s: could not map cru pmu region\n", __func__);
1550 return;
1551 }
1552
1553 ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS);
1554 if (IS_ERR(ctx)) {
1555 pr_err("%s: rockchip pmu clk init failed\n", __func__);
1556 return;
1557 }
1558
1559 rockchip_clk_register_plls(ctx, rk3399_pmu_pll_clks,
1560 ARRAY_SIZE(rk3399_pmu_pll_clks), -1);
1561
1562 rockchip_clk_register_branches(ctx, rk3399_clk_pmu_branches,
1563 ARRAY_SIZE(rk3399_clk_pmu_branches));
1564
1565 rockchip_clk_protect_critical(rk3399_pmucru_critical_clocks,
1566 ARRAY_SIZE(rk3399_pmucru_critical_clocks));
1567
1568 rockchip_register_softrst(np, 2, reg_base + RK3399_PMU_SOFTRST_CON(0),
1569 ROCKCHIP_SOFTRST_HIWORD_MASK);
1570
1571 rockchip_clk_of_add_provider(np, ctx);
1572}
1573CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index ec06350c78c4..7ffd134995f2 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -2,6 +2,9 @@
2 * Copyright (c) 2014 MundoReader S.L. 2 * Copyright (c) 2014 MundoReader S.L.
3 * Author: Heiko Stuebner <heiko@sntech.de> 3 * Author: Heiko Stuebner <heiko@sntech.de>
4 * 4 *
5 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
6 * Author: Xing Zheng <zhengxing@rock-chips.com>
7 *
5 * based on 8 * based on
6 * 9 *
7 * samsung/clk.c 10 * samsung/clk.c
@@ -39,7 +42,8 @@
39 * sometimes without one of those components. 42 * sometimes without one of those components.
40 */ 43 */
41static struct clk *rockchip_clk_register_branch(const char *name, 44static struct clk *rockchip_clk_register_branch(const char *name,
42 const char *const *parent_names, u8 num_parents, void __iomem *base, 45 const char *const *parent_names, u8 num_parents,
46 void __iomem *base,
43 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 47 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
44 u8 div_shift, u8 div_width, u8 div_flags, 48 u8 div_shift, u8 div_width, u8 div_flags,
45 struct clk_div_table *div_table, int gate_offset, 49 struct clk_div_table *div_table, int gate_offset,
@@ -136,9 +140,11 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
136 pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n", 140 pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
137 __func__, event, ndata->old_rate, ndata->new_rate); 141 __func__, event, ndata->old_rate, ndata->new_rate);
138 if (event == PRE_RATE_CHANGE) { 142 if (event == PRE_RATE_CHANGE) {
139 frac->rate_change_idx = frac->mux_ops->get_parent(&frac_mux->hw); 143 frac->rate_change_idx =
144 frac->mux_ops->get_parent(&frac_mux->hw);
140 if (frac->rate_change_idx != frac->mux_frac_idx) { 145 if (frac->rate_change_idx != frac->mux_frac_idx) {
141 frac->mux_ops->set_parent(&frac_mux->hw, frac->mux_frac_idx); 146 frac->mux_ops->set_parent(&frac_mux->hw,
147 frac->mux_frac_idx);
142 frac->rate_change_remuxed = 1; 148 frac->rate_change_remuxed = 1;
143 } 149 }
144 } else if (event == POST_RATE_CHANGE) { 150 } else if (event == POST_RATE_CHANGE) {
@@ -149,7 +155,8 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
149 * reaches the mux itself. 155 * reaches the mux itself.
150 */ 156 */
151 if (frac->rate_change_remuxed) { 157 if (frac->rate_change_remuxed) {
152 frac->mux_ops->set_parent(&frac_mux->hw, frac->rate_change_idx); 158 frac->mux_ops->set_parent(&frac_mux->hw,
159 frac->rate_change_idx);
153 frac->rate_change_remuxed = 0; 160 frac->rate_change_remuxed = 0;
154 } 161 }
155 } 162 }
@@ -157,7 +164,8 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
157 return notifier_from_errno(ret); 164 return notifier_from_errno(ret);
158} 165}
159 166
160static struct clk *rockchip_clk_register_frac_branch(const char *name, 167static struct clk *rockchip_clk_register_frac_branch(
168 struct rockchip_clk_provider *ctx, const char *name,
161 const char *const *parent_names, u8 num_parents, 169 const char *const *parent_names, u8 num_parents,
162 void __iomem *base, int muxdiv_offset, u8 div_flags, 170 void __iomem *base, int muxdiv_offset, u8 div_flags,
163 int gate_offset, u8 gate_shift, u8 gate_flags, 171 int gate_offset, u8 gate_shift, u8 gate_flags,
@@ -250,7 +258,7 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
250 if (IS_ERR(mux_clk)) 258 if (IS_ERR(mux_clk))
251 return clk; 259 return clk;
252 260
253 rockchip_clk_add_lookup(mux_clk, child->id); 261 rockchip_clk_add_lookup(ctx, mux_clk, child->id);
254 262
255 /* notifier on the fraction divider to catch rate changes */ 263 /* notifier on the fraction divider to catch rate changes */
256 if (frac->mux_frac_idx >= 0) { 264 if (frac->mux_frac_idx >= 0) {
@@ -314,66 +322,82 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name,
314 return clk; 322 return clk;
315} 323}
316 324
317static DEFINE_SPINLOCK(clk_lock); 325struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np,
318static struct clk **clk_table; 326 void __iomem *base, unsigned long nr_clks)
319static void __iomem *reg_base;
320static struct clk_onecell_data clk_data;
321static struct device_node *cru_node;
322static struct regmap *grf;
323
324void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
325 unsigned long nr_clks)
326{ 327{
327 reg_base = base; 328 struct rockchip_clk_provider *ctx;
328 cru_node = np; 329 struct clk **clk_table;
329 grf = ERR_PTR(-EPROBE_DEFER); 330 int i;
331
332 ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL);
333 if (!ctx)
334 return ERR_PTR(-ENOMEM);
330 335
331 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 336 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
332 if (!clk_table) 337 if (!clk_table)
333 pr_err("%s: could not allocate clock lookup table\n", __func__); 338 goto err_free;
334 339
335 clk_data.clks = clk_table; 340 for (i = 0; i < nr_clks; ++i)
336 clk_data.clk_num = nr_clks; 341 clk_table[i] = ERR_PTR(-ENOENT);
337 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 342
343 ctx->reg_base = base;
344 ctx->clk_data.clks = clk_table;
345 ctx->clk_data.clk_num = nr_clks;
346 ctx->cru_node = np;
347 ctx->grf = ERR_PTR(-EPROBE_DEFER);
348 spin_lock_init(&ctx->lock);
349
350 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
351 "rockchip,grf");
352
353 return ctx;
354
355err_free:
356 kfree(ctx);
357 return ERR_PTR(-ENOMEM);
338} 358}
339 359
340struct regmap *rockchip_clk_get_grf(void) 360void __init rockchip_clk_of_add_provider(struct device_node *np,
361 struct rockchip_clk_provider *ctx)
341{ 362{
342 if (IS_ERR(grf)) 363 if (of_clk_add_provider(np, of_clk_src_onecell_get,
343 grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf"); 364 &ctx->clk_data))
344 return grf; 365 pr_err("%s: could not register clk provider\n", __func__);
345} 366}
346 367
347void rockchip_clk_add_lookup(struct clk *clk, unsigned int id) 368void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
369 struct clk *clk, unsigned int id)
348{ 370{
349 if (clk_table && id) 371 if (ctx->clk_data.clks && id)
350 clk_table[id] = clk; 372 ctx->clk_data.clks[id] = clk;
351} 373}
352 374
353void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, 375void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
376 struct rockchip_pll_clock *list,
354 unsigned int nr_pll, int grf_lock_offset) 377 unsigned int nr_pll, int grf_lock_offset)
355{ 378{
356 struct clk *clk; 379 struct clk *clk;
357 int idx; 380 int idx;
358 381
359 for (idx = 0; idx < nr_pll; idx++, list++) { 382 for (idx = 0; idx < nr_pll; idx++, list++) {
360 clk = rockchip_clk_register_pll(list->type, list->name, 383 clk = rockchip_clk_register_pll(ctx, list->type, list->name,
361 list->parent_names, list->num_parents, 384 list->parent_names, list->num_parents,
362 reg_base, list->con_offset, grf_lock_offset, 385 list->con_offset, grf_lock_offset,
363 list->lock_shift, list->mode_offset, 386 list->lock_shift, list->mode_offset,
364 list->mode_shift, list->rate_table, 387 list->mode_shift, list->rate_table,
365 list->pll_flags, &clk_lock); 388 list->pll_flags);
366 if (IS_ERR(clk)) { 389 if (IS_ERR(clk)) {
367 pr_err("%s: failed to register clock %s\n", __func__, 390 pr_err("%s: failed to register clock %s\n", __func__,
368 list->name); 391 list->name);
369 continue; 392 continue;
370 } 393 }
371 394
372 rockchip_clk_add_lookup(clk, list->id); 395 rockchip_clk_add_lookup(ctx, clk, list->id);
373 } 396 }
374} 397}
375 398
376void __init rockchip_clk_register_branches( 399void __init rockchip_clk_register_branches(
400 struct rockchip_clk_provider *ctx,
377 struct rockchip_clk_branch *list, 401 struct rockchip_clk_branch *list,
378 unsigned int nr_clk) 402 unsigned int nr_clk)
379{ 403{
@@ -389,56 +413,59 @@ void __init rockchip_clk_register_branches(
389 case branch_mux: 413 case branch_mux:
390 clk = clk_register_mux(NULL, list->name, 414 clk = clk_register_mux(NULL, list->name,
391 list->parent_names, list->num_parents, 415 list->parent_names, list->num_parents,
392 flags, reg_base + list->muxdiv_offset, 416 flags, ctx->reg_base + list->muxdiv_offset,
393 list->mux_shift, list->mux_width, 417 list->mux_shift, list->mux_width,
394 list->mux_flags, &clk_lock); 418 list->mux_flags, &ctx->lock);
395 break; 419 break;
396 case branch_divider: 420 case branch_divider:
397 if (list->div_table) 421 if (list->div_table)
398 clk = clk_register_divider_table(NULL, 422 clk = clk_register_divider_table(NULL,
399 list->name, list->parent_names[0], 423 list->name, list->parent_names[0],
400 flags, reg_base + list->muxdiv_offset, 424 flags,
425 ctx->reg_base + list->muxdiv_offset,
401 list->div_shift, list->div_width, 426 list->div_shift, list->div_width,
402 list->div_flags, list->div_table, 427 list->div_flags, list->div_table,
403 &clk_lock); 428 &ctx->lock);
404 else 429 else
405 clk = clk_register_divider(NULL, list->name, 430 clk = clk_register_divider(NULL, list->name,
406 list->parent_names[0], flags, 431 list->parent_names[0], flags,
407 reg_base + list->muxdiv_offset, 432 ctx->reg_base + list->muxdiv_offset,
408 list->div_shift, list->div_width, 433 list->div_shift, list->div_width,
409 list->div_flags, &clk_lock); 434 list->div_flags, &ctx->lock);
410 break; 435 break;
411 case branch_fraction_divider: 436 case branch_fraction_divider:
412 clk = rockchip_clk_register_frac_branch(list->name, 437 clk = rockchip_clk_register_frac_branch(ctx, list->name,
413 list->parent_names, list->num_parents, 438 list->parent_names, list->num_parents,
414 reg_base, list->muxdiv_offset, list->div_flags, 439 ctx->reg_base, list->muxdiv_offset,
440 list->div_flags,
415 list->gate_offset, list->gate_shift, 441 list->gate_offset, list->gate_shift,
416 list->gate_flags, flags, list->child, 442 list->gate_flags, flags, list->child,
417 &clk_lock); 443 &ctx->lock);
418 break; 444 break;
419 case branch_gate: 445 case branch_gate:
420 flags |= CLK_SET_RATE_PARENT; 446 flags |= CLK_SET_RATE_PARENT;
421 447
422 clk = clk_register_gate(NULL, list->name, 448 clk = clk_register_gate(NULL, list->name,
423 list->parent_names[0], flags, 449 list->parent_names[0], flags,
424 reg_base + list->gate_offset, 450 ctx->reg_base + list->gate_offset,
425 list->gate_shift, list->gate_flags, &clk_lock); 451 list->gate_shift, list->gate_flags, &ctx->lock);
426 break; 452 break;
427 case branch_composite: 453 case branch_composite:
428 clk = rockchip_clk_register_branch(list->name, 454 clk = rockchip_clk_register_branch(list->name,
429 list->parent_names, list->num_parents, 455 list->parent_names, list->num_parents,
430 reg_base, list->muxdiv_offset, list->mux_shift, 456 ctx->reg_base, list->muxdiv_offset,
457 list->mux_shift,
431 list->mux_width, list->mux_flags, 458 list->mux_width, list->mux_flags,
432 list->div_shift, list->div_width, 459 list->div_shift, list->div_width,
433 list->div_flags, list->div_table, 460 list->div_flags, list->div_table,
434 list->gate_offset, list->gate_shift, 461 list->gate_offset, list->gate_shift,
435 list->gate_flags, flags, &clk_lock); 462 list->gate_flags, flags, &ctx->lock);
436 break; 463 break;
437 case branch_mmc: 464 case branch_mmc:
438 clk = rockchip_clk_register_mmc( 465 clk = rockchip_clk_register_mmc(
439 list->name, 466 list->name,
440 list->parent_names, list->num_parents, 467 list->parent_names, list->num_parents,
441 reg_base + list->muxdiv_offset, 468 ctx->reg_base + list->muxdiv_offset,
442 list->div_shift 469 list->div_shift
443 ); 470 );
444 break; 471 break;
@@ -446,16 +473,16 @@ void __init rockchip_clk_register_branches(
446 clk = rockchip_clk_register_inverter( 473 clk = rockchip_clk_register_inverter(
447 list->name, list->parent_names, 474 list->name, list->parent_names,
448 list->num_parents, 475 list->num_parents,
449 reg_base + list->muxdiv_offset, 476 ctx->reg_base + list->muxdiv_offset,
450 list->div_shift, list->div_flags, &clk_lock); 477 list->div_shift, list->div_flags, &ctx->lock);
451 break; 478 break;
452 case branch_factor: 479 case branch_factor:
453 clk = rockchip_clk_register_factor_branch( 480 clk = rockchip_clk_register_factor_branch(
454 list->name, list->parent_names, 481 list->name, list->parent_names,
455 list->num_parents, reg_base, 482 list->num_parents, ctx->reg_base,
456 list->div_shift, list->div_width, 483 list->div_shift, list->div_width,
457 list->gate_offset, list->gate_shift, 484 list->gate_offset, list->gate_shift,
458 list->gate_flags, flags, &clk_lock); 485 list->gate_flags, flags, &ctx->lock);
459 break; 486 break;
460 } 487 }
461 488
@@ -472,11 +499,12 @@ void __init rockchip_clk_register_branches(
472 continue; 499 continue;
473 } 500 }
474 501
475 rockchip_clk_add_lookup(clk, list->id); 502 rockchip_clk_add_lookup(ctx, clk, list->id);
476 } 503 }
477} 504}
478 505
479void __init rockchip_clk_register_armclk(unsigned int lookup_id, 506void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
507 unsigned int lookup_id,
480 const char *name, const char *const *parent_names, 508 const char *name, const char *const *parent_names,
481 u8 num_parents, 509 u8 num_parents,
482 const struct rockchip_cpuclk_reg_data *reg_data, 510 const struct rockchip_cpuclk_reg_data *reg_data,
@@ -486,15 +514,15 @@ void __init rockchip_clk_register_armclk(unsigned int lookup_id,
486 struct clk *clk; 514 struct clk *clk;
487 515
488 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, 516 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
489 reg_data, rates, nrates, reg_base, 517 reg_data, rates, nrates,
490 &clk_lock); 518 ctx->reg_base, &ctx->lock);
491 if (IS_ERR(clk)) { 519 if (IS_ERR(clk)) {
492 pr_err("%s: failed to register clock %s: %ld\n", 520 pr_err("%s: failed to register clock %s: %ld\n",
493 __func__, name, PTR_ERR(clk)); 521 __func__, name, PTR_ERR(clk));
494 return; 522 return;
495 } 523 }
496 524
497 rockchip_clk_add_lookup(clk, lookup_id); 525 rockchip_clk_add_lookup(ctx, clk, lookup_id);
498} 526}
499 527
500void __init rockchip_clk_protect_critical(const char *const clocks[], 528void __init rockchip_clk_protect_critical(const char *const clocks[],
@@ -511,6 +539,7 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
511 } 539 }
512} 540}
513 541
542static void __iomem *rst_base;
514static unsigned int reg_restart; 543static unsigned int reg_restart;
515static void (*cb_restart)(void); 544static void (*cb_restart)(void);
516static int rockchip_restart_notify(struct notifier_block *this, 545static int rockchip_restart_notify(struct notifier_block *this,
@@ -519,7 +548,7 @@ static int rockchip_restart_notify(struct notifier_block *this,
519 if (cb_restart) 548 if (cb_restart)
520 cb_restart(); 549 cb_restart();
521 550
522 writel(0xfdb9, reg_base + reg_restart); 551 writel(0xfdb9, rst_base + reg_restart);
523 return NOTIFY_DONE; 552 return NOTIFY_DONE;
524} 553}
525 554
@@ -528,10 +557,14 @@ static struct notifier_block rockchip_restart_handler = {
528 .priority = 128, 557 .priority = 128,
529}; 558};
530 559
531void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)) 560void __init
561rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
562 unsigned int reg,
563 void (*cb)(void))
532{ 564{
533 int ret; 565 int ret;
534 566
567 rst_base = ctx->reg_base;
535 reg_restart = reg; 568 reg_restart = reg;
536 cb_restart = cb; 569 cb_restart = cb;
537 ret = register_restart_handler(&rockchip_restart_handler); 570 ret = register_restart_handler(&rockchip_restart_handler);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 39c198bbcbee..2194ffa8c9fd 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -27,13 +27,13 @@
27#define CLK_ROCKCHIP_CLK_H 27#define CLK_ROCKCHIP_CLK_H
28 28
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/clk-provider.h>
30 31
31struct clk; 32struct clk;
32 33
33#define HIWORD_UPDATE(val, mask, shift) \ 34#define HIWORD_UPDATE(val, mask, shift) \
34 ((val) << (shift) | (mask) << ((shift) + 16)) 35 ((val) << (shift) | (mask) << ((shift) + 16))
35 36
36/* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */
37#define RK2928_PLL_CON(x) ((x) * 0x4) 37#define RK2928_PLL_CON(x) ((x) * 0x4)
38#define RK2928_MODE_CON 0x40 38#define RK2928_MODE_CON 0x40
39#define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44) 39#define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44)
@@ -92,9 +92,30 @@ struct clk;
92#define RK3368_EMMC_CON0 0x418 92#define RK3368_EMMC_CON0 0x418
93#define RK3368_EMMC_CON1 0x41c 93#define RK3368_EMMC_CON1 0x41c
94 94
95#define RK3399_PLL_CON(x) RK2928_PLL_CON(x)
96#define RK3399_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
97#define RK3399_CLKGATE_CON(x) ((x) * 0x4 + 0x300)
98#define RK3399_SOFTRST_CON(x) ((x) * 0x4 + 0x400)
99#define RK3399_GLB_SRST_FST 0x500
100#define RK3399_GLB_SRST_SND 0x504
101#define RK3399_GLB_CNT_TH 0x508
102#define RK3399_MISC_CON 0x50c
103#define RK3399_RST_CON 0x510
104#define RK3399_RST_ST 0x514
105#define RK3399_SDMMC_CON0 0x580
106#define RK3399_SDMMC_CON1 0x584
107#define RK3399_SDIO_CON0 0x588
108#define RK3399_SDIO_CON1 0x58c
109
110#define RK3399_PMU_PLL_CON(x) RK2928_PLL_CON(x)
111#define RK3399_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x80)
112#define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100)
113#define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110)
114
95enum rockchip_pll_type { 115enum rockchip_pll_type {
96 pll_rk3036, 116 pll_rk3036,
97 pll_rk3066, 117 pll_rk3066,
118 pll_rk3399,
98}; 119};
99 120
100#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 121#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \
@@ -127,13 +148,29 @@ enum rockchip_pll_type {
127 .nb = _nb, \ 148 .nb = _nb, \
128} 149}
129 150
151/**
152 * struct rockchip_clk_provider - information about clock provider
153 * @reg_base: virtual address for the register base.
154 * @clk_data: holds clock related data like clk* and number of clocks.
155 * @cru_node: device-node of the clock-provider
156 * @grf: regmap of the general-register-files syscon
157 * @lock: maintains exclusion between callbacks for a given clock-provider.
158 */
159struct rockchip_clk_provider {
160 void __iomem *reg_base;
161 struct clk_onecell_data clk_data;
162 struct device_node *cru_node;
163 struct regmap *grf;
164 spinlock_t lock;
165};
166
130struct rockchip_pll_rate_table { 167struct rockchip_pll_rate_table {
131 unsigned long rate; 168 unsigned long rate;
132 unsigned int nr; 169 unsigned int nr;
133 unsigned int nf; 170 unsigned int nf;
134 unsigned int no; 171 unsigned int no;
135 unsigned int nb; 172 unsigned int nb;
136 /* for RK3036 */ 173 /* for RK3036/RK3399 */
137 unsigned int fbdiv; 174 unsigned int fbdiv;
138 unsigned int postdiv1; 175 unsigned int postdiv1;
139 unsigned int refdiv; 176 unsigned int refdiv;
@@ -143,10 +180,11 @@ struct rockchip_pll_rate_table {
143}; 180};
144 181
145/** 182/**
146 * struct rockchip_pll_clock: information about pll clock 183 * struct rockchip_pll_clock - information about pll clock
147 * @id: platform specific id of the clock. 184 * @id: platform specific id of the clock.
148 * @name: name of this pll clock. 185 * @name: name of this pll clock.
149 * @parent_name: name of the parent clock. 186 * @parent_names: name of the parent clock.
187 * @num_parents: number of parents
150 * @flags: optional flags for basic clock. 188 * @flags: optional flags for basic clock.
151 * @con_offset: offset of the register for configuring the PLL. 189 * @con_offset: offset of the register for configuring the PLL.
152 * @mode_offset: offset of the register for configuring the PLL-mode. 190 * @mode_offset: offset of the register for configuring the PLL-mode.
@@ -194,12 +232,13 @@ struct rockchip_pll_clock {
194 .rate_table = _rtable, \ 232 .rate_table = _rtable, \
195 } 233 }
196 234
197struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 235struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
236 enum rockchip_pll_type pll_type,
198 const char *name, const char *const *parent_names, 237 const char *name, const char *const *parent_names,
199 u8 num_parents, void __iomem *base, int con_offset, 238 u8 num_parents, int con_offset, int grf_lock_offset,
200 int grf_lock_offset, int lock_shift, int reg_mode, 239 int lock_shift, int mode_offset, int mode_shift,
201 int mode_shift, struct rockchip_pll_rate_table *rate_table, 240 struct rockchip_pll_rate_table *rate_table,
202 u8 clk_pll_flags, spinlock_t *lock); 241 u8 clk_pll_flags);
203 242
204struct rockchip_cpuclk_clksel { 243struct rockchip_cpuclk_clksel {
205 int reg; 244 int reg;
@@ -213,18 +252,23 @@ struct rockchip_cpuclk_rate_table {
213}; 252};
214 253
215/** 254/**
216 * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock 255 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
217 * @core_reg: register offset of the core settings register 256 * @core_reg: register offset of the core settings register
218 * @div_core_shift: core divider offset used to divide the pll value 257 * @div_core_shift: core divider offset used to divide the pll value
219 * @div_core_mask: core divider mask 258 * @div_core_mask: core divider mask
259 * @mux_core_alt: mux value to select alternate parent
260 * @mux_core_main: mux value to select main parent of core
220 * @mux_core_shift: offset of the core multiplexer 261 * @mux_core_shift: offset of the core multiplexer
262 * @mux_core_mask: core multiplexer mask
221 */ 263 */
222struct rockchip_cpuclk_reg_data { 264struct rockchip_cpuclk_reg_data {
223 int core_reg; 265 int core_reg;
224 u8 div_core_shift; 266 u8 div_core_shift;
225 u32 div_core_mask; 267 u32 div_core_mask;
226 int mux_core_reg; 268 u8 mux_core_alt;
269 u8 mux_core_main;
227 u8 mux_core_shift; 270 u8 mux_core_shift;
271 u32 mux_core_mask;
228}; 272};
229 273
230struct clk *rockchip_clk_register_cpuclk(const char *name, 274struct clk *rockchip_clk_register_cpuclk(const char *name,
@@ -428,6 +472,22 @@ struct rockchip_clk_branch {
428 .child = ch, \ 472 .child = ch, \
429 } 473 }
430 474
475#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
476 { \
477 .id = _id, \
478 .branch_type = branch_fraction_divider, \
479 .name = cname, \
480 .parent_names = (const char *[]){ pname }, \
481 .num_parents = 1, \
482 .flags = f, \
483 .muxdiv_offset = mo, \
484 .div_shift = 16, \
485 .div_width = 16, \
486 .div_flags = df, \
487 .gate_offset = -1, \
488 .child = ch, \
489 }
490
431#define MUX(_id, cname, pnames, f, o, s, w, mf) \ 491#define MUX(_id, cname, pnames, f, o, s, w, mf) \
432 { \ 492 { \
433 .id = _id, \ 493 .id = _id, \
@@ -536,21 +596,27 @@ struct rockchip_clk_branch {
536 .gate_flags = gf, \ 596 .gate_flags = gf, \
537 } 597 }
538 598
539void rockchip_clk_init(struct device_node *np, void __iomem *base, 599struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
540 unsigned long nr_clks); 600 void __iomem *base, unsigned long nr_clks);
541struct regmap *rockchip_clk_get_grf(void); 601void rockchip_clk_of_add_provider(struct device_node *np,
542void rockchip_clk_add_lookup(struct clk *clk, unsigned int id); 602 struct rockchip_clk_provider *ctx);
543void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list, 603void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
604 struct clk *clk, unsigned int id);
605void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
606 struct rockchip_clk_branch *list,
544 unsigned int nr_clk); 607 unsigned int nr_clk);
545void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, 608void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
609 struct rockchip_pll_clock *pll_list,
546 unsigned int nr_pll, int grf_lock_offset); 610 unsigned int nr_pll, int grf_lock_offset);
547void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, 611void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
612 unsigned int lookup_id, const char *name,
548 const char *const *parent_names, u8 num_parents, 613 const char *const *parent_names, u8 num_parents,
549 const struct rockchip_cpuclk_reg_data *reg_data, 614 const struct rockchip_cpuclk_reg_data *reg_data,
550 const struct rockchip_cpuclk_rate_table *rates, 615 const struct rockchip_cpuclk_rate_table *rates,
551 int nrates); 616 int nrates);
552void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 617void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
553void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)); 618void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
619 unsigned int reg, void (*cb)(void));
554 620
555#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 621#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
556 622
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index be03ed0fcb6b..92382cef9f90 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -554,8 +554,8 @@ static struct samsung_mux_clock exynos5800_mux_clks[] __initdata = {
554}; 554};
555 555
556static struct samsung_div_clock exynos5800_div_clks[] __initdata = { 556static struct samsung_div_clock exynos5800_div_clks[] __initdata = {
557 DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore", DIV_TOP0, 16, 3), 557 DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore",
558 558 "mout_aclk400_wcore", DIV_TOP0, 16, 3),
559 DIV(0, "dout_aclk550_cam", "mout_aclk550_cam", 559 DIV(0, "dout_aclk550_cam", "mout_aclk550_cam",
560 DIV_TOP8, 16, 3), 560 DIV_TOP8, 16, 3),
561 DIV(0, "dout_aclkfl1_550_cam", "mout_aclkfl1_550_cam", 561 DIV(0, "dout_aclkfl1_550_cam", "mout_aclkfl1_550_cam",
@@ -607,8 +607,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
607}; 607};
608 608
609static struct samsung_div_clock exynos5420_div_clks[] __initdata = { 609static struct samsung_div_clock exynos5420_div_clks[] __initdata = {
610 DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll", 610 DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore",
611 DIV_TOP0, 16, 3), 611 "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3),
612}; 612};
613 613
614static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = { 614static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
@@ -785,31 +785,47 @@ static struct samsung_div_clock exynos5x_div_clks[] __initdata = {
785 DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3), 785 DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3),
786 DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), 786 DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3),
787 787
788 DIV(0, "dout_aclk400_isp", "mout_aclk400_isp", DIV_TOP0, 0, 3), 788 DIV(CLK_DOUT_ACLK400_ISP, "dout_aclk400_isp", "mout_aclk400_isp",
789 DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), 789 DIV_TOP0, 0, 3),
790 DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), 790 DIV(CLK_DOUT_ACLK400_MSCL, "dout_aclk400_mscl", "mout_aclk400_mscl",
791 DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), 791 DIV_TOP0, 4, 3),
792 DIV(0, "dout_aclk100_noc", "mout_aclk100_noc", DIV_TOP0, 20, 3), 792 DIV(CLK_DOUT_ACLK200, "dout_aclk200", "mout_aclk200",
793 DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), 793 DIV_TOP0, 8, 3),
794 DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), 794 DIV(CLK_DOUT_ACLK200_FSYS2, "dout_aclk200_fsys2", "mout_aclk200_fsys2",
795 795 DIV_TOP0, 12, 3),
796 DIV(0, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl", 796 DIV(CLK_DOUT_ACLK100_NOC, "dout_aclk100_noc", "mout_aclk100_noc",
797 DIV_TOP1, 0, 3), 797 DIV_TOP0, 20, 3),
798 DIV(0, "dout_aclk333_432_isp", "mout_aclk333_432_isp", 798 DIV(CLK_DOUT_PCLK200_FSYS, "dout_pclk200_fsys", "mout_pclk200_fsys",
799 DIV_TOP1, 4, 3), 799 DIV_TOP0, 24, 3),
800 DIV(0, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6), 800 DIV(CLK_DOUT_ACLK200_FSYS, "dout_aclk200_fsys", "mout_aclk200_fsys",
801 DIV(0, "dout_aclk333_432_isp0", "mout_aclk333_432_isp0", 801 DIV_TOP0, 28, 3),
802 DIV_TOP1, 16, 3), 802 DIV(CLK_DOUT_ACLK333_432_GSCL, "dout_aclk333_432_gscl",
803 DIV(0, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3), 803 "mout_aclk333_432_gscl", DIV_TOP1, 0, 3),
804 DIV(0, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3), 804 DIV(CLK_DOUT_ACLK333_432_ISP, "dout_aclk333_432_isp",
805 DIV(0, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3), 805 "mout_aclk333_432_isp", DIV_TOP1, 4, 3),
806 806 DIV(CLK_DOUT_ACLK66, "dout_aclk66", "mout_aclk66",
807 DIV(0, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3), 807 DIV_TOP1, 8, 6),
808 DIV(0, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), 808 DIV(CLK_DOUT_ACLK333_432_ISP0, "dout_aclk333_432_isp0",
809 DIV(0, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3), 809 "mout_aclk333_432_isp0", DIV_TOP1, 16, 3),
810 DIV(0, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), 810 DIV(CLK_DOUT_ACLK266, "dout_aclk266", "mout_aclk266",
811 DIV(0, "dout_aclk300_disp1", "mout_aclk300_disp1", DIV_TOP2, 24, 3), 811 DIV_TOP1, 20, 3),
812 DIV(0, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3), 812 DIV(CLK_DOUT_ACLK166, "dout_aclk166", "mout_aclk166",
813 DIV_TOP1, 24, 3),
814 DIV(CLK_DOUT_ACLK333, "dout_aclk333", "mout_aclk333",
815 DIV_TOP1, 28, 3),
816
817 DIV(CLK_DOUT_ACLK333_G2D, "dout_aclk333_g2d", "mout_aclk333_g2d",
818 DIV_TOP2, 8, 3),
819 DIV(CLK_DOUT_ACLK266_G2D, "dout_aclk266_g2d", "mout_aclk266_g2d",
820 DIV_TOP2, 12, 3),
821 DIV(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2,
822 16, 3),
823 DIV(CLK_DOUT_ACLK300_JPEG, "dout_aclk300_jpeg", "mout_aclk300_jpeg",
824 DIV_TOP2, 20, 3),
825 DIV(CLK_DOUT_ACLK300_DISP1, "dout_aclk300_disp1",
826 "mout_aclk300_disp1", DIV_TOP2, 24, 3),
827 DIV(CLK_DOUT_ACLK300_GSCL, "dout_aclk300_gscl", "mout_aclk300_gscl",
828 DIV_TOP2, 28, 3),
813 829
814 /* DISP1 Block */ 830 /* DISP1 Block */
815 DIV(0, "dout_fimd1", "mout_fimd1_final", DIV_DISP10, 0, 4), 831 DIV(0, "dout_fimd1", "mout_fimd1_final", DIV_DISP10, 0, 4),
@@ -817,7 +833,8 @@ static struct samsung_div_clock exynos5x_div_clks[] __initdata = {
817 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), 833 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
818 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), 834 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
819 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2), 835 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2),
820 DIV(0, "dout_aclk400_disp1", "mout_aclk400_disp1", DIV_TOP2, 4, 3), 836 DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1",
837 "mout_aclk400_disp1", DIV_TOP2, 4, 3),
821 838
822 /* Audio Block */ 839 /* Audio Block */
823 DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), 840 DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
diff --git a/drivers/clk/sirf/clk-atlas6.c b/drivers/clk/sirf/clk-atlas6.c
index c5eaa9d16247..665fa681b2e1 100644
--- a/drivers/clk/sirf/clk-atlas6.c
+++ b/drivers/clk/sirf/clk-atlas6.c
@@ -130,10 +130,9 @@ static void __init atlas6_clk_init(struct device_node *np)
130 panic("unable to map clkc registers\n"); 130 panic("unable to map clkc registers\n");
131 131
132 /* These are always available (RTC and 26MHz OSC)*/ 132 /* These are always available (RTC and 26MHz OSC)*/
133 atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 133 atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
134 CLK_IS_ROOT, 32768); 134 atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0,
135 atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 135 26000000);
136 CLK_IS_ROOT, 26000000);
137 136
138 for (i = pll1; i < maxclk; i++) { 137 for (i = pll1; i < maxclk; i++) {
139 atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]); 138 atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
diff --git a/drivers/clk/sirf/clk-prima2.c b/drivers/clk/sirf/clk-prima2.c
index f92c40264342..aac1c8ec151a 100644
--- a/drivers/clk/sirf/clk-prima2.c
+++ b/drivers/clk/sirf/clk-prima2.c
@@ -129,10 +129,9 @@ static void __init prima2_clk_init(struct device_node *np)
129 panic("unable to map clkc registers\n"); 129 panic("unable to map clkc registers\n");
130 130
131 /* These are always available (RTC and 26MHz OSC)*/ 131 /* These are always available (RTC and 26MHz OSC)*/
132 prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 132 prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
133 CLK_IS_ROOT, 32768); 133 prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0,
134 prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 134 26000000);
135 CLK_IS_ROOT, 26000000);
136 135
137 for (i = pll1; i < maxclk; i++) { 136 for (i = pll1; i < maxclk; i++) {
138 prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]); 137 prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 3fd7901d48e4..39d2044a1f49 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -11,6 +11,9 @@ obj-y += clk-a10-ve.o
11obj-y += clk-a20-gmac.o 11obj-y += clk-a20-gmac.o
12obj-y += clk-mod0.o 12obj-y += clk-mod0.o
13obj-y += clk-simple-gates.o 13obj-y += clk-simple-gates.o
14obj-y += clk-sun4i-display.o
15obj-y += clk-sun4i-pll3.o
16obj-y += clk-sun4i-tcon-ch1.o
14obj-y += clk-sun8i-bus-gates.o 17obj-y += clk-sun8i-bus-gates.o
15obj-y += clk-sun8i-mbus.o 18obj-y += clk-sun8i-mbus.o
16obj-y += clk-sun9i-core.o 19obj-y += clk-sun9i-core.o
diff --git a/drivers/clk/sunxi/clk-a10-hosc.c b/drivers/clk/sunxi/clk-a10-hosc.c
index 6b598c6a0213..dca532431394 100644
--- a/drivers/clk/sunxi/clk-a10-hosc.c
+++ b/drivers/clk/sunxi/clk-a10-hosc.c
@@ -54,8 +54,7 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
54 NULL, 0, 54 NULL, 0,
55 NULL, NULL, 55 NULL, NULL,
56 &fixed->hw, &clk_fixed_rate_ops, 56 &fixed->hw, &clk_fixed_rate_ops,
57 &gate->hw, &clk_gate_ops, 57 &gate->hw, &clk_gate_ops, 0);
58 CLK_IS_ROOT);
59 58
60 if (IS_ERR(clk)) 59 if (IS_ERR(clk))
61 goto err_free_gate; 60 goto err_free_gate;
diff --git a/drivers/clk/sunxi/clk-a10-mod1.c b/drivers/clk/sunxi/clk-a10-mod1.c
index e9d870de165c..e2819fa09637 100644
--- a/drivers/clk/sunxi/clk-a10-mod1.c
+++ b/drivers/clk/sunxi/clk-a10-mod1.c
@@ -62,7 +62,7 @@ static void __init sun4i_mod1_clk_setup(struct device_node *node)
62 clk = clk_register_composite(NULL, clk_name, parents, i, 62 clk = clk_register_composite(NULL, clk_name, parents, i,
63 &mux->hw, &clk_mux_ops, 63 &mux->hw, &clk_mux_ops,
64 NULL, NULL, 64 NULL, NULL,
65 &gate->hw, &clk_gate_ops, 0); 65 &gate->hw, &clk_gate_ops, CLK_SET_RATE_PARENT);
66 if (IS_ERR(clk)) 66 if (IS_ERR(clk))
67 goto err_free_gate; 67 goto err_free_gate;
68 68
diff --git a/drivers/clk/sunxi/clk-sun4i-display.c b/drivers/clk/sunxi/clk-sun4i-display.c
new file mode 100644
index 000000000000..445a7498d6df
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun4i-display.c
@@ -0,0 +1,261 @@
1/*
2 * Copyright 2015 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/kernel.h>
19#include <linux/of_address.h>
20#include <linux/reset-controller.h>
21#include <linux/slab.h>
22#include <linux/spinlock.h>
23
24struct sun4i_a10_display_clk_data {
25 bool has_div;
26 u8 num_rst;
27 u8 parents;
28
29 u8 offset_en;
30 u8 offset_div;
31 u8 offset_mux;
32 u8 offset_rst;
33
34 u8 width_div;
35 u8 width_mux;
36};
37
38struct reset_data {
39 void __iomem *reg;
40 spinlock_t *lock;
41 struct reset_controller_dev rcdev;
42 u8 offset;
43};
44
45static DEFINE_SPINLOCK(sun4i_a10_display_lock);
46
47static inline struct reset_data *rcdev_to_reset_data(struct reset_controller_dev *rcdev)
48{
49 return container_of(rcdev, struct reset_data, rcdev);
50};
51
52static int sun4i_a10_display_assert(struct reset_controller_dev *rcdev,
53 unsigned long id)
54{
55 struct reset_data *data = rcdev_to_reset_data(rcdev);
56 unsigned long flags;
57 u32 reg;
58
59 spin_lock_irqsave(data->lock, flags);
60
61 reg = readl(data->reg);
62 writel(reg & ~BIT(data->offset + id), data->reg);
63
64 spin_unlock_irqrestore(data->lock, flags);
65
66 return 0;
67}
68
69static int sun4i_a10_display_deassert(struct reset_controller_dev *rcdev,
70 unsigned long id)
71{
72 struct reset_data *data = rcdev_to_reset_data(rcdev);
73 unsigned long flags;
74 u32 reg;
75
76 spin_lock_irqsave(data->lock, flags);
77
78 reg = readl(data->reg);
79 writel(reg | BIT(data->offset + id), data->reg);
80
81 spin_unlock_irqrestore(data->lock, flags);
82
83 return 0;
84}
85
86static int sun4i_a10_display_status(struct reset_controller_dev *rcdev,
87 unsigned long id)
88{
89 struct reset_data *data = rcdev_to_reset_data(rcdev);
90
91 return !(readl(data->reg) & BIT(data->offset + id));
92}
93
94static const struct reset_control_ops sun4i_a10_display_reset_ops = {
95 .assert = sun4i_a10_display_assert,
96 .deassert = sun4i_a10_display_deassert,
97 .status = sun4i_a10_display_status,
98};
99
100static int sun4i_a10_display_reset_xlate(struct reset_controller_dev *rcdev,
101 const struct of_phandle_args *spec)
102{
103 /* We only have a single reset signal */
104 return 0;
105}
106
107static void __init sun4i_a10_display_init(struct device_node *node,
108 const struct sun4i_a10_display_clk_data *data)
109{
110 const char *parents[4];
111 const char *clk_name = node->name;
112 struct reset_data *reset_data;
113 struct clk_divider *div = NULL;
114 struct clk_gate *gate;
115 struct resource res;
116 struct clk_mux *mux;
117 void __iomem *reg;
118 struct clk *clk;
119 int ret;
120
121 of_property_read_string(node, "clock-output-names", &clk_name);
122
123 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
124 if (IS_ERR(reg)) {
125 pr_err("%s: Could not map the clock registers\n", clk_name);
126 return;
127 }
128
129 ret = of_clk_parent_fill(node, parents, data->parents);
130 if (ret != data->parents) {
131 pr_err("%s: Could not retrieve the parents\n", clk_name);
132 goto unmap;
133 }
134
135 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
136 if (!mux)
137 goto unmap;
138
139 mux->reg = reg;
140 mux->shift = data->offset_mux;
141 mux->mask = (1 << data->width_mux) - 1;
142 mux->lock = &sun4i_a10_display_lock;
143
144 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
145 if (!gate)
146 goto free_mux;
147
148 gate->reg = reg;
149 gate->bit_idx = data->offset_en;
150 gate->lock = &sun4i_a10_display_lock;
151
152 if (data->has_div) {
153 div = kzalloc(sizeof(*div), GFP_KERNEL);
154 if (!div)
155 goto free_gate;
156
157 div->reg = reg;
158 div->shift = data->offset_div;
159 div->width = data->width_div;
160 div->lock = &sun4i_a10_display_lock;
161 }
162
163 clk = clk_register_composite(NULL, clk_name,
164 parents, data->parents,
165 &mux->hw, &clk_mux_ops,
166 data->has_div ? &div->hw : NULL,
167 data->has_div ? &clk_divider_ops : NULL,
168 &gate->hw, &clk_gate_ops,
169 0);
170 if (IS_ERR(clk)) {
171 pr_err("%s: Couldn't register the clock\n", clk_name);
172 goto free_div;
173 }
174
175 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
176 if (ret) {
177 pr_err("%s: Couldn't register DT provider\n", clk_name);
178 goto free_clk;
179 }
180
181 if (!data->num_rst)
182 return;
183
184 reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
185 if (!reset_data)
186 goto free_of_clk;
187
188 reset_data->reg = reg;
189 reset_data->offset = data->offset_rst;
190 reset_data->lock = &sun4i_a10_display_lock;
191 reset_data->rcdev.nr_resets = data->num_rst;
192 reset_data->rcdev.ops = &sun4i_a10_display_reset_ops;
193 reset_data->rcdev.of_node = node;
194
195 if (data->num_rst == 1) {
196 reset_data->rcdev.of_reset_n_cells = 0;
197 reset_data->rcdev.of_xlate = &sun4i_a10_display_reset_xlate;
198 } else {
199 reset_data->rcdev.of_reset_n_cells = 1;
200 }
201
202 if (reset_controller_register(&reset_data->rcdev)) {
203 pr_err("%s: Couldn't register the reset controller\n",
204 clk_name);
205 goto free_reset;
206 }
207
208 return;
209
210free_reset:
211 kfree(reset_data);
212free_of_clk:
213 of_clk_del_provider(node);
214free_clk:
215 clk_unregister_composite(clk);
216free_div:
217 kfree(div);
218free_gate:
219 kfree(gate);
220free_mux:
221 kfree(mux);
222unmap:
223 iounmap(reg);
224 of_address_to_resource(node, 0, &res);
225 release_mem_region(res.start, resource_size(&res));
226}
227
228static const struct sun4i_a10_display_clk_data sun4i_a10_tcon_ch0_data __initconst = {
229 .num_rst = 2,
230 .parents = 4,
231 .offset_en = 31,
232 .offset_rst = 29,
233 .offset_mux = 24,
234 .width_mux = 2,
235};
236
237static void __init sun4i_a10_tcon_ch0_setup(struct device_node *node)
238{
239 sun4i_a10_display_init(node, &sun4i_a10_tcon_ch0_data);
240}
241CLK_OF_DECLARE(sun4i_a10_tcon_ch0, "allwinner,sun4i-a10-tcon-ch0-clk",
242 sun4i_a10_tcon_ch0_setup);
243
244static const struct sun4i_a10_display_clk_data sun4i_a10_display_data __initconst = {
245 .has_div = true,
246 .num_rst = 1,
247 .parents = 3,
248 .offset_en = 31,
249 .offset_rst = 30,
250 .offset_mux = 24,
251 .offset_div = 0,
252 .width_mux = 2,
253 .width_div = 4,
254};
255
256static void __init sun4i_a10_display_setup(struct device_node *node)
257{
258 sun4i_a10_display_init(node, &sun4i_a10_display_data);
259}
260CLK_OF_DECLARE(sun4i_a10_display, "allwinner,sun4i-a10-display-clk",
261 sun4i_a10_display_setup);
diff --git a/drivers/clk/sunxi/clk-sun4i-pll3.c b/drivers/clk/sunxi/clk-sun4i-pll3.c
new file mode 100644
index 000000000000..f66267e77d9c
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun4i-pll3.c
@@ -0,0 +1,98 @@
1/*
2 * Copyright 2015 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/slab.h>
21#include <linux/spinlock.h>
22
23#define SUN4I_A10_PLL3_GATE_BIT 31
24#define SUN4I_A10_PLL3_DIV_WIDTH 7
25#define SUN4I_A10_PLL3_DIV_SHIFT 0
26
27static DEFINE_SPINLOCK(sun4i_a10_pll3_lock);
28
29static void __init sun4i_a10_pll3_setup(struct device_node *node)
30{
31 const char *clk_name = node->name, *parent;
32 struct clk_multiplier *mult;
33 struct clk_gate *gate;
34 struct resource res;
35 void __iomem *reg;
36 struct clk *clk;
37 int ret;
38
39 of_property_read_string(node, "clock-output-names", &clk_name);
40 parent = of_clk_get_parent_name(node, 0);
41
42 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
43 if (IS_ERR(reg)) {
44 pr_err("%s: Could not map the clock registers\n", clk_name);
45 return;
46 }
47
48 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
49 if (!gate)
50 goto err_unmap;
51
52 gate->reg = reg;
53 gate->bit_idx = SUN4I_A10_PLL3_GATE_BIT;
54 gate->lock = &sun4i_a10_pll3_lock;
55
56 mult = kzalloc(sizeof(*mult), GFP_KERNEL);
57 if (!mult)
58 goto err_free_gate;
59
60 mult->reg = reg;
61 mult->shift = SUN4I_A10_PLL3_DIV_SHIFT;
62 mult->width = SUN4I_A10_PLL3_DIV_WIDTH;
63 mult->lock = &sun4i_a10_pll3_lock;
64
65 clk = clk_register_composite(NULL, clk_name,
66 &parent, 1,
67 NULL, NULL,
68 &mult->hw, &clk_multiplier_ops,
69 &gate->hw, &clk_gate_ops,
70 0);
71 if (IS_ERR(clk)) {
72 pr_err("%s: Couldn't register the clock\n", clk_name);
73 goto err_free_mult;
74 }
75
76 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
77 if (ret) {
78 pr_err("%s: Couldn't register DT provider\n",
79 clk_name);
80 goto err_clk_unregister;
81 }
82
83 return;
84
85err_clk_unregister:
86 clk_unregister_composite(clk);
87err_free_mult:
88 kfree(mult);
89err_free_gate:
90 kfree(gate);
91err_unmap:
92 iounmap(reg);
93 of_address_to_resource(node, 0, &res);
94 release_mem_region(res.start, resource_size(&res));
95}
96
97CLK_OF_DECLARE(sun4i_a10_pll3, "allwinner,sun4i-a10-pll3-clk",
98 sun4i_a10_pll3_setup);
diff --git a/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c b/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c
new file mode 100644
index 000000000000..98a4582de56a
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c
@@ -0,0 +1,300 @@
1/*
2 * Copyright 2015 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/slab.h>
21#include <linux/spinlock.h>
22
23#define TCON_CH1_SCLK2_PARENTS 4
24
25#define TCON_CH1_SCLK2_GATE_BIT BIT(31)
26#define TCON_CH1_SCLK2_MUX_MASK 3
27#define TCON_CH1_SCLK2_MUX_SHIFT 24
28#define TCON_CH1_SCLK2_DIV_MASK 0xf
29#define TCON_CH1_SCLK2_DIV_SHIFT 0
30
31#define TCON_CH1_SCLK1_GATE_BIT BIT(15)
32#define TCON_CH1_SCLK1_HALF_BIT BIT(11)
33
34struct tcon_ch1_clk {
35 struct clk_hw hw;
36 spinlock_t lock;
37 void __iomem *reg;
38};
39
40#define hw_to_tclk(hw) container_of(hw, struct tcon_ch1_clk, hw)
41
42static void tcon_ch1_disable(struct clk_hw *hw)
43{
44 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
45 unsigned long flags;
46 u32 reg;
47
48 spin_lock_irqsave(&tclk->lock, flags);
49 reg = readl(tclk->reg);
50 reg &= ~(TCON_CH1_SCLK2_GATE_BIT | TCON_CH1_SCLK1_GATE_BIT);
51 writel(reg, tclk->reg);
52 spin_unlock_irqrestore(&tclk->lock, flags);
53}
54
55static int tcon_ch1_enable(struct clk_hw *hw)
56{
57 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
58 unsigned long flags;
59 u32 reg;
60
61 spin_lock_irqsave(&tclk->lock, flags);
62 reg = readl(tclk->reg);
63 reg |= TCON_CH1_SCLK2_GATE_BIT | TCON_CH1_SCLK1_GATE_BIT;
64 writel(reg, tclk->reg);
65 spin_unlock_irqrestore(&tclk->lock, flags);
66
67 return 0;
68}
69
70static int tcon_ch1_is_enabled(struct clk_hw *hw)
71{
72 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
73 u32 reg;
74
75 reg = readl(tclk->reg);
76 return reg & (TCON_CH1_SCLK2_GATE_BIT | TCON_CH1_SCLK1_GATE_BIT);
77}
78
79static u8 tcon_ch1_get_parent(struct clk_hw *hw)
80{
81 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
82 int num_parents = clk_hw_get_num_parents(hw);
83 u32 reg;
84
85 reg = readl(tclk->reg) >> TCON_CH1_SCLK2_MUX_SHIFT;
86 reg &= reg >> TCON_CH1_SCLK2_MUX_MASK;
87
88 if (reg >= num_parents)
89 return -EINVAL;
90
91 return reg;
92}
93
94static int tcon_ch1_set_parent(struct clk_hw *hw, u8 index)
95{
96 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
97 unsigned long flags;
98 u32 reg;
99
100 spin_lock_irqsave(&tclk->lock, flags);
101 reg = readl(tclk->reg);
102 reg &= ~(TCON_CH1_SCLK2_MUX_MASK << TCON_CH1_SCLK2_MUX_SHIFT);
103 reg |= index << TCON_CH1_SCLK2_MUX_SHIFT;
104 writel(reg, tclk->reg);
105 spin_unlock_irqrestore(&tclk->lock, flags);
106
107 return 0;
108};
109
110static unsigned long tcon_ch1_calc_divider(unsigned long rate,
111 unsigned long parent_rate,
112 u8 *div,
113 bool *half)
114{
115 unsigned long best_rate = 0;
116 u8 best_m = 0, m;
117 bool is_double;
118
119 for (m = 1; m < 16; m++) {
120 u8 d;
121
122 for (d = 1; d < 3; d++) {
123 unsigned long tmp_rate;
124
125 tmp_rate = parent_rate / m / d;
126
127 if (tmp_rate > rate)
128 continue;
129
130 if (!best_rate ||
131 (rate - tmp_rate) < (rate - best_rate)) {
132 best_rate = tmp_rate;
133 best_m = m;
134 is_double = d;
135 }
136 }
137 }
138
139 if (div && half) {
140 *div = best_m;
141 *half = is_double;
142 }
143
144 return best_rate;
145}
146
147static int tcon_ch1_determine_rate(struct clk_hw *hw,
148 struct clk_rate_request *req)
149{
150 long best_rate = -EINVAL;
151 int i;
152
153 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
154 unsigned long parent_rate;
155 unsigned long tmp_rate;
156 struct clk_hw *parent;
157
158 parent = clk_hw_get_parent_by_index(hw, i);
159 if (!parent)
160 continue;
161
162 parent_rate = clk_hw_get_rate(parent);
163
164 tmp_rate = tcon_ch1_calc_divider(req->rate, parent_rate,
165 NULL, NULL);
166
167 if (best_rate < 0 ||
168 (req->rate - tmp_rate) < (req->rate - best_rate)) {
169 best_rate = tmp_rate;
170 req->best_parent_rate = parent_rate;
171 req->best_parent_hw = parent;
172 }
173 }
174
175 if (best_rate < 0)
176 return best_rate;
177
178 req->rate = best_rate;
179 return 0;
180}
181
182static unsigned long tcon_ch1_recalc_rate(struct clk_hw *hw,
183 unsigned long parent_rate)
184{
185 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
186 u32 reg;
187
188 reg = readl(tclk->reg);
189
190 parent_rate /= (reg & TCON_CH1_SCLK2_DIV_MASK) + 1;
191
192 if (reg & TCON_CH1_SCLK1_HALF_BIT)
193 parent_rate /= 2;
194
195 return parent_rate;
196}
197
198static int tcon_ch1_set_rate(struct clk_hw *hw, unsigned long rate,
199 unsigned long parent_rate)
200{
201 struct tcon_ch1_clk *tclk = hw_to_tclk(hw);
202 unsigned long flags;
203 bool half;
204 u8 div_m;
205 u32 reg;
206
207 tcon_ch1_calc_divider(rate, parent_rate, &div_m, &half);
208
209 spin_lock_irqsave(&tclk->lock, flags);
210 reg = readl(tclk->reg);
211 reg &= ~(TCON_CH1_SCLK2_DIV_MASK | TCON_CH1_SCLK1_HALF_BIT);
212 reg |= (div_m - 1) & TCON_CH1_SCLK2_DIV_MASK;
213
214 if (half)
215 reg |= TCON_CH1_SCLK1_HALF_BIT;
216
217 writel(reg, tclk->reg);
218 spin_unlock_irqrestore(&tclk->lock, flags);
219
220 return 0;
221}
222
223static const struct clk_ops tcon_ch1_ops = {
224 .disable = tcon_ch1_disable,
225 .enable = tcon_ch1_enable,
226 .is_enabled = tcon_ch1_is_enabled,
227
228 .get_parent = tcon_ch1_get_parent,
229 .set_parent = tcon_ch1_set_parent,
230
231 .determine_rate = tcon_ch1_determine_rate,
232 .recalc_rate = tcon_ch1_recalc_rate,
233 .set_rate = tcon_ch1_set_rate,
234};
235
236static void __init tcon_ch1_setup(struct device_node *node)
237{
238 const char *parents[TCON_CH1_SCLK2_PARENTS];
239 const char *clk_name = node->name;
240 struct clk_init_data init;
241 struct tcon_ch1_clk *tclk;
242 struct resource res;
243 struct clk *clk;
244 void __iomem *reg;
245 int ret;
246
247 of_property_read_string(node, "clock-output-names", &clk_name);
248
249 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
250 if (IS_ERR(reg)) {
251 pr_err("%s: Could not map the clock registers\n", clk_name);
252 return;
253 }
254
255 ret = of_clk_parent_fill(node, parents, TCON_CH1_SCLK2_PARENTS);
256 if (ret != TCON_CH1_SCLK2_PARENTS) {
257 pr_err("%s Could not retrieve the parents\n", clk_name);
258 goto err_unmap;
259 }
260
261 tclk = kzalloc(sizeof(*tclk), GFP_KERNEL);
262 if (!tclk)
263 goto err_unmap;
264
265 init.name = clk_name;
266 init.ops = &tcon_ch1_ops;
267 init.parent_names = parents;
268 init.num_parents = TCON_CH1_SCLK2_PARENTS;
269 init.flags = CLK_SET_RATE_PARENT;
270
271 tclk->reg = reg;
272 tclk->hw.init = &init;
273 spin_lock_init(&tclk->lock);
274
275 clk = clk_register(NULL, &tclk->hw);
276 if (IS_ERR(clk)) {
277 pr_err("%s: Couldn't register the clock\n", clk_name);
278 goto err_free_data;
279 }
280
281 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
282 if (ret) {
283 pr_err("%s: Couldn't register our clock provider\n", clk_name);
284 goto err_unregister_clk;
285 }
286
287 return;
288
289err_unregister_clk:
290 clk_unregister(clk);
291err_free_data:
292 kfree(tclk);
293err_unmap:
294 iounmap(reg);
295 of_address_to_resource(node, 0, &res);
296 release_mem_region(res.start, resource_size(&res));
297}
298
299CLK_OF_DECLARE(tcon_ch1, "allwinner,sun4i-a10-tcon-ch1-clk",
300 tcon_ch1_setup);
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
index 028dd832a39f..716737388b7d 100644
--- a/drivers/clk/sunxi/clk-sun9i-mmc.c
+++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
@@ -106,7 +106,7 @@ static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev)
106 106
107 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 107 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
108 /* one clock/reset pair per word */ 108 /* one clock/reset pair per word */
109 count = DIV_ROUND_UP((r->end - r->start + 1), SUN9I_MMC_WIDTH); 109 count = DIV_ROUND_UP((resource_size(r)), SUN9I_MMC_WIDTH);
110 data->membase = devm_ioremap_resource(&pdev->dev, r); 110 data->membase = devm_ioremap_resource(&pdev->dev, r);
111 if (IS_ERR(data->membase)) 111 if (IS_ERR(data->membase))
112 return PTR_ERR(data->membase); 112 return PTR_ERR(data->membase);
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 91de0a006773..838b22aa8b67 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -523,21 +523,12 @@ static const struct factors_data sun4i_pll5_data __initconst = {
523 .enable = 31, 523 .enable = 31,
524 .table = &sun4i_pll5_config, 524 .table = &sun4i_pll5_config,
525 .getter = sun4i_get_pll5_factors, 525 .getter = sun4i_get_pll5_factors,
526 .name = "pll5",
527};
528
529static const struct factors_data sun4i_pll6_data __initconst = {
530 .enable = 31,
531 .table = &sun4i_pll5_config,
532 .getter = sun4i_get_pll5_factors,
533 .name = "pll6",
534}; 526};
535 527
536static const struct factors_data sun6i_a31_pll6_data __initconst = { 528static const struct factors_data sun6i_a31_pll6_data __initconst = {
537 .enable = 31, 529 .enable = 31,
538 .table = &sun6i_a31_pll6_config, 530 .table = &sun6i_a31_pll6_config,
539 .getter = sun6i_a31_get_pll6_factors, 531 .getter = sun6i_a31_get_pll6_factors,
540 .name = "pll6x2",
541}; 532};
542 533
543static const struct factors_data sun5i_a13_ahb_data __initconst = { 534static const struct factors_data sun5i_a13_ahb_data __initconst = {
@@ -933,7 +924,7 @@ static const struct divs_data pll5_divs_data __initconst = {
933}; 924};
934 925
935static const struct divs_data pll6_divs_data __initconst = { 926static const struct divs_data pll6_divs_data __initconst = {
936 .factors = &sun4i_pll6_data, 927 .factors = &sun4i_pll5_data,
937 .ndivs = 4, 928 .ndivs = 4,
938 .div = { 929 .div = {
939 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ 930 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
@@ -975,6 +966,8 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node,
975 struct clk_gate *gate = NULL; 966 struct clk_gate *gate = NULL;
976 struct clk_fixed_factor *fix_factor; 967 struct clk_fixed_factor *fix_factor;
977 struct clk_divider *divider; 968 struct clk_divider *divider;
969 struct factors_data factors = *data->factors;
970 char *derived_name = NULL;
978 void __iomem *reg; 971 void __iomem *reg;
979 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; 972 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
980 int flags, clkflags; 973 int flags, clkflags;
@@ -983,11 +976,37 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node,
983 if (data->ndivs) 976 if (data->ndivs)
984 ndivs = data->ndivs; 977 ndivs = data->ndivs;
985 978
979 /* Try to find a name for base factor clock */
980 for (i = 0; i < ndivs; i++) {
981 if (data->div[i].self) {
982 of_property_read_string_index(node, "clock-output-names",
983 i, &factors.name);
984 break;
985 }
986 }
987 /* If we don't have a .self clk use the first output-name up to '_' */
988 if (factors.name == NULL) {
989 char *endp;
990
991 of_property_read_string_index(node, "clock-output-names",
992 0, &clk_name);
993 endp = strchr(clk_name, '_');
994 if (endp) {
995 derived_name = kstrndup(clk_name, endp - clk_name,
996 GFP_KERNEL);
997 factors.name = derived_name;
998 } else {
999 factors.name = clk_name;
1000 }
1001 }
1002
986 /* Set up factor clock that we will be dividing */ 1003 /* Set up factor clock that we will be dividing */
987 pclk = sunxi_factors_clk_setup(node, data->factors); 1004 pclk = sunxi_factors_clk_setup(node, &factors);
988 if (!pclk) 1005 if (!pclk)
989 return NULL; 1006 return NULL;
1007
990 parent = __clk_get_name(pclk); 1008 parent = __clk_get_name(pclk);
1009 kfree(derived_name);
991 1010
992 reg = of_iomap(node, 0); 1011 reg = of_iomap(node, 0);
993 if (!reg) { 1012 if (!reg) {
@@ -1127,3 +1146,41 @@ static void __init sun6i_pll6_clk_setup(struct device_node *node)
1127} 1146}
1128CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk", 1147CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk",
1129 sun6i_pll6_clk_setup); 1148 sun6i_pll6_clk_setup);
1149
1150/*
1151 * sun6i display
1152 *
1153 * rate = parent_rate / (m + 1);
1154 */
1155static void sun6i_display_factors(struct factors_request *req)
1156{
1157 u8 m;
1158
1159 if (req->rate > req->parent_rate)
1160 req->rate = req->parent_rate;
1161
1162 m = DIV_ROUND_UP(req->parent_rate, req->rate);
1163
1164 req->rate = req->parent_rate / m;
1165 req->m = m - 1;
1166}
1167
1168static const struct clk_factors_config sun6i_display_config = {
1169 .mshift = 0,
1170 .mwidth = 4,
1171};
1172
1173static const struct factors_data sun6i_display_data __initconst = {
1174 .enable = 31,
1175 .mux = 24,
1176 .muxmask = BIT(2) | BIT(1) | BIT(0),
1177 .table = &sun6i_display_config,
1178 .getter = sun6i_display_factors,
1179};
1180
1181static void __init sun6i_display_setup(struct device_node *node)
1182{
1183 sunxi_factors_clk_setup(node, &sun6i_display_data);
1184}
1185CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-a31-display-clk",
1186 sun6i_display_setup);
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index 97984c503bbb..33fd0938d79e 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -3,6 +3,7 @@ obj-y += clk-audio-sync.o
3obj-y += clk-dfll.o 3obj-y += clk-dfll.o
4obj-y += clk-divider.o 4obj-y += clk-divider.o
5obj-y += clk-periph.o 5obj-y += clk-periph.o
6obj-y += clk-periph-fixed.o
6obj-y += clk-periph-gate.o 7obj-y += clk-periph-gate.o
7obj-y += clk-pll.o 8obj-y += clk-pll.o
8obj-y += clk-pll-out.o 9obj-y += clk-pll-out.o
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index 19bfa07e24b1..f010562534eb 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -55,6 +55,7 @@
55#include <linux/seq_file.h> 55#include <linux/seq_file.h>
56 56
57#include "clk-dfll.h" 57#include "clk-dfll.h"
58#include "cvb.h"
58 59
59/* 60/*
60 * DFLL control registers - access via dfll_{readl,writel} 61 * DFLL control registers - access via dfll_{readl,writel}
@@ -442,8 +443,8 @@ static void dfll_tune_low(struct tegra_dfll *td)
442{ 443{
443 td->tune_range = DFLL_TUNE_LOW; 444 td->tune_range = DFLL_TUNE_LOW;
444 445
445 dfll_writel(td, td->soc->tune0_low, DFLL_TUNE0); 446 dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune0_low, DFLL_TUNE0);
446 dfll_writel(td, td->soc->tune1, DFLL_TUNE1); 447 dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune1, DFLL_TUNE1);
447 dfll_wmb(td); 448 dfll_wmb(td);
448 449
449 if (td->soc->set_clock_trimmers_low) 450 if (td->soc->set_clock_trimmers_low)
@@ -1449,7 +1450,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
1449 } 1450 }
1450 v_max = dev_pm_opp_get_voltage(opp); 1451 v_max = dev_pm_opp_get_voltage(opp);
1451 1452
1452 v = td->soc->min_millivolts * 1000; 1453 v = td->soc->cvb->min_millivolts * 1000;
1453 lut = find_vdd_map_entry_exact(td, v); 1454 lut = find_vdd_map_entry_exact(td, v);
1454 if (lut < 0) 1455 if (lut < 0)
1455 goto out; 1456 goto out;
@@ -1461,7 +1462,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
1461 break; 1462 break;
1462 v_opp = dev_pm_opp_get_voltage(opp); 1463 v_opp = dev_pm_opp_get_voltage(opp);
1463 1464
1464 if (v_opp <= td->soc->min_millivolts * 1000) 1465 if (v_opp <= td->soc->cvb->min_millivolts * 1000)
1465 td->dvco_rate_min = dev_pm_opp_get_freq(opp); 1466 td->dvco_rate_min = dev_pm_opp_get_freq(opp);
1466 1467
1467 for (;;) { 1468 for (;;) {
@@ -1490,7 +1491,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
1490 1491
1491 if (!td->dvco_rate_min) 1492 if (!td->dvco_rate_min)
1492 dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n", 1493 dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n",
1493 td->soc->min_millivolts); 1494 td->soc->cvb->min_millivolts);
1494 else 1495 else
1495 ret = 0; 1496 ret = 0;
1496 1497
diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h
index 2e4c0772a5dc..ed2ad888268f 100644
--- a/drivers/clk/tegra/clk-dfll.h
+++ b/drivers/clk/tegra/clk-dfll.h
@@ -24,22 +24,18 @@
24 24
25/** 25/**
26 * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver 26 * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver
27 * @opp_dev: struct device * that holds the OPP table for the DFLL 27 * @dev: struct device * that holds the OPP table for the DFLL
28 * @min_millivolts: minimum voltage (in mV) that the DFLL can operate 28 * @max_freq: maximum frequency supported on this SoC
29 * @tune0_low: DFLL tuning register 0 (low voltage range) 29 * @cvb: CPU frequency table for this SoC
30 * @tune0_high: DFLL tuning register 0 (high voltage range) 30 * @init_clock_trimmers: callback to initialize clock trimmers
31 * @tune1: DFLL tuning register 1 31 * @set_clock_trimmers_high: callback to tune clock trimmers for high voltage
32 * @assert_dvco_reset: fn ptr to place the DVCO in reset 32 * @set_clock_trimmers_low: callback to tune clock trimmers for low voltage
33 * @deassert_dvco_reset: fn ptr to release the DVCO reset
34 * @set_clock_trimmers_high: fn ptr to tune clock trimmers for high voltage
35 * @set_clock_trimmers_low: fn ptr to tune clock trimmers for low voltage
36 */ 33 */
37struct tegra_dfll_soc_data { 34struct tegra_dfll_soc_data {
38 struct device *dev; 35 struct device *dev;
39 unsigned int min_millivolts; 36 unsigned long max_freq;
40 u32 tune0_low; 37 const struct cvb_table *cvb;
41 u32 tune0_high; 38
42 u32 tune1;
43 void (*init_clock_trimmers)(void); 39 void (*init_clock_trimmers)(void);
44 void (*set_clock_trimmers_high)(void); 40 void (*set_clock_trimmers_high)(void);
45 void (*set_clock_trimmers_low)(void); 41 void (*set_clock_trimmers_low)(void);
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
index 62ea38187b71..36c974916d4f 100644
--- a/drivers/clk/tegra/clk-id.h
+++ b/drivers/clk/tegra/clk-id.h
@@ -71,6 +71,7 @@ enum clk_id {
71 tegra_clk_disp2_8, 71 tegra_clk_disp2_8,
72 tegra_clk_dp2, 72 tegra_clk_dp2,
73 tegra_clk_dpaux, 73 tegra_clk_dpaux,
74 tegra_clk_dpaux1,
74 tegra_clk_dsialp, 75 tegra_clk_dsialp,
75 tegra_clk_dsia_mux, 76 tegra_clk_dsia_mux,
76 tegra_clk_dsiblp, 77 tegra_clk_dsiblp,
@@ -306,6 +307,7 @@ enum clk_id {
306 tegra_clk_xusb_ss_div2, 307 tegra_clk_xusb_ss_div2,
307 tegra_clk_xusb_ssp_src, 308 tegra_clk_xusb_ssp_src,
308 tegra_clk_sclk_mux, 309 tegra_clk_sclk_mux,
310 tegra_clk_sor_safe,
309 tegra_clk_max, 311 tegra_clk_max,
310}; 312};
311 313
diff --git a/drivers/clk/tegra/clk-periph-fixed.c b/drivers/clk/tegra/clk-periph-fixed.c
new file mode 100644
index 000000000000..c57dfb037b10
--- /dev/null
+++ b/drivers/clk/tegra/clk-periph-fixed.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/clk-provider.h>
18
19#include "clk.h"
20
21static inline struct tegra_clk_periph_fixed *
22to_tegra_clk_periph_fixed(struct clk_hw *hw)
23{
24 return container_of(hw, struct tegra_clk_periph_fixed, hw);
25}
26
27static int tegra_clk_periph_fixed_is_enabled(struct clk_hw *hw)
28{
29 struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
30 u32 mask = 1 << (fixed->num % 32), value;
31
32 value = readl(fixed->base + fixed->regs->enb_reg);
33 if (value & mask) {
34 value = readl(fixed->base + fixed->regs->rst_reg);
35 if ((value & mask) == 0)
36 return 1;
37 }
38
39 return 0;
40}
41
42static int tegra_clk_periph_fixed_enable(struct clk_hw *hw)
43{
44 struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
45 u32 mask = 1 << (fixed->num % 32);
46
47 writel(mask, fixed->base + fixed->regs->enb_set_reg);
48
49 return 0;
50}
51
52static void tegra_clk_periph_fixed_disable(struct clk_hw *hw)
53{
54 struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
55 u32 mask = 1 << (fixed->num % 32);
56
57 writel(mask, fixed->base + fixed->regs->enb_clr_reg);
58}
59
60static unsigned long
61tegra_clk_periph_fixed_recalc_rate(struct clk_hw *hw,
62 unsigned long parent_rate)
63{
64 struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
65 unsigned long long rate;
66
67 rate = (unsigned long long)parent_rate * fixed->mul;
68 do_div(rate, fixed->div);
69
70 return (unsigned long)rate;
71}
72
73static const struct clk_ops tegra_clk_periph_fixed_ops = {
74 .is_enabled = tegra_clk_periph_fixed_is_enabled,
75 .enable = tegra_clk_periph_fixed_enable,
76 .disable = tegra_clk_periph_fixed_disable,
77 .recalc_rate = tegra_clk_periph_fixed_recalc_rate,
78};
79
80struct clk *tegra_clk_register_periph_fixed(const char *name,
81 const char *parent,
82 unsigned long flags,
83 void __iomem *base,
84 unsigned int mul,
85 unsigned int div,
86 unsigned int num)
87{
88 const struct tegra_clk_periph_regs *regs;
89 struct tegra_clk_periph_fixed *fixed;
90 struct clk_init_data init;
91 struct clk *clk;
92
93 regs = get_reg_bank(num);
94 if (!regs)
95 return ERR_PTR(-EINVAL);
96
97 fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
98 if (!fixed)
99 return ERR_PTR(-ENOMEM);
100
101 init.name = name;
102 init.flags = flags;
103 init.parent_names = parent ? &parent : NULL;
104 init.num_parents = parent ? 1 : 0;
105 init.ops = &tegra_clk_periph_fixed_ops;
106
107 fixed->base = base;
108 fixed->regs = regs;
109 fixed->mul = mul;
110 fixed->div = div;
111 fixed->num = num;
112
113 fixed->hw.init = &init;
114
115 clk = clk_register(NULL, &fixed->hw);
116 if (IS_ERR(clk))
117 kfree(fixed);
118
119 return clk;
120}
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
index d28d6e95020f..88127828befe 100644
--- a/drivers/clk/tegra/clk-periph-gate.c
+++ b/drivers/clk/tegra/clk-periph-gate.c
@@ -134,7 +134,7 @@ struct clk *tegra_clk_register_periph_gate(const char *name,
134 struct tegra_clk_periph_gate *gate; 134 struct tegra_clk_periph_gate *gate;
135 struct clk *clk; 135 struct clk *clk;
136 struct clk_init_data init; 136 struct clk_init_data init;
137 struct tegra_clk_periph_regs *pregs; 137 const struct tegra_clk_periph_regs *pregs;
138 138
139 pregs = get_reg_bank(clk_num); 139 pregs = get_reg_bank(clk_num);
140 if (!pregs) 140 if (!pregs)
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index ec5b6113b012..a17ca6d7f649 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -145,7 +145,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
145{ 145{
146 struct clk *clk; 146 struct clk *clk;
147 struct clk_init_data init; 147 struct clk_init_data init;
148 struct tegra_clk_periph_regs *bank; 148 const struct tegra_clk_periph_regs *bank;
149 bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); 149 bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV);
150 150
151 if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { 151 if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) {
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 6ac3f843e7ca..4e194ecc8d5e 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -2013,6 +2013,52 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
2013#endif 2013#endif
2014 2014
2015#if defined(CONFIG_ARCH_TEGRA_210_SOC) 2015#if defined(CONFIG_ARCH_TEGRA_210_SOC)
2016struct clk *tegra_clk_register_pllre_tegra210(const char *name,
2017 const char *parent_name, void __iomem *clk_base,
2018 void __iomem *pmc, unsigned long flags,
2019 struct tegra_clk_pll_params *pll_params,
2020 spinlock_t *lock, unsigned long parent_rate)
2021{
2022 u32 val;
2023 struct tegra_clk_pll *pll;
2024 struct clk *clk;
2025
2026 pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
2027
2028 if (pll_params->adjust_vco)
2029 pll_params->vco_min = pll_params->adjust_vco(pll_params,
2030 parent_rate);
2031
2032 pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
2033 if (IS_ERR(pll))
2034 return ERR_CAST(pll);
2035
2036 /* program minimum rate by default */
2037
2038 val = pll_readl_base(pll);
2039 if (val & PLL_BASE_ENABLE)
2040 WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) &
2041 BIT(pll_params->iddq_bit_idx));
2042 else {
2043 val = 0x4 << divm_shift(pll);
2044 val |= 0x41 << divn_shift(pll);
2045 pll_writel_base(val, pll);
2046 }
2047
2048 /* disable lock override */
2049
2050 val = pll_readl_misc(pll);
2051 val &= ~BIT(29);
2052 pll_writel_misc(val, pll);
2053
2054 clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
2055 &tegra_clk_pllre_ops);
2056 if (IS_ERR(clk))
2057 kfree(pll);
2058
2059 return clk;
2060}
2061
2016static int clk_plle_tegra210_enable(struct clk_hw *hw) 2062static int clk_plle_tegra210_enable(struct clk_hw *hw)
2017{ 2063{
2018 struct tegra_clk_pll *pll = to_clk_pll(hw); 2064 struct tegra_clk_pll *pll = to_clk_pll(hw);
diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c
index d64ec7a1b976..91c38f1666c1 100644
--- a/drivers/clk/tegra/clk-tegra-fixed.c
+++ b/drivers/clk/tegra/clk-tegra-fixed.c
@@ -107,4 +107,3 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks)
107 *dt_clk = clk; 107 *dt_clk = clk;
108 } 108 }
109} 109}
110
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index ea2b9cbf9e70..29d04c663abf 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -803,7 +803,7 @@ static struct tegra_periph_init_data gate_clks[] = {
803 GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), 803 GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0),
804 GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), 804 GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0),
805 GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), 805 GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0),
806 GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0), 806 GATE("mipi-cal", "clk72mhz", 56, 0, tegra_clk_mipi_cal, 0),
807 GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), 807 GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0),
808 GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), 808 GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0),
809 GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), 809 GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0),
@@ -821,7 +821,6 @@ static struct tegra_periph_init_data gate_clks[] = {
821 GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), 821 GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0),
822 GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), 822 GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0),
823 GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), 823 GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0),
824 GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0),
825 GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), 824 GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0),
826 GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0), 825 GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0),
827 GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0), 826 GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0),
@@ -877,7 +876,7 @@ static void __init periph_clk_init(void __iomem *clk_base,
877 struct clk **dt_clk; 876 struct clk **dt_clk;
878 877
879 for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { 878 for (i = 0; i < ARRAY_SIZE(periph_clks); i++) {
880 struct tegra_clk_periph_regs *bank; 879 const struct tegra_clk_periph_regs *bank;
881 struct tegra_periph_init_data *data; 880 struct tegra_periph_init_data *data;
882 881
883 data = periph_clks + i; 882 data = periph_clks + i;
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index df47ec3169c3..b78054fac0a8 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -743,7 +743,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
743 [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, 743 [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true },
744 [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, 744 [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true },
745 [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, 745 [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true },
746 [tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true },
747 [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, 746 [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true },
748 [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, 747 [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true },
749 [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, 748 [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true },
@@ -1237,6 +1236,11 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
1237 &emc_lock); 1236 &emc_lock);
1238 clks[TEGRA114_CLK_MC] = clk; 1237 clks[TEGRA114_CLK_MC] = clk;
1239 1238
1239 clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base,
1240 CLK_SET_RATE_PARENT, 56,
1241 periph_clk_enb_refcnt);
1242 clks[TEGRA114_CLK_MIPI_CAL] = clk;
1243
1240 for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { 1244 for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
1241 data = &tegra_periph_clk_list[i]; 1245 data = &tegra_periph_clk_list[i];
1242 clk = tegra_clk_register_periph(data->name, 1246 clk = tegra_clk_register_periph(data->name,
diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
index 61253330c12b..c205809ba580 100644
--- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
+++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
@@ -47,32 +47,32 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
47 }, 47 },
48 .speedo_scale = 100, 48 .speedo_scale = 100,
49 .voltage_scale = 1000, 49 .voltage_scale = 1000,
50 .cvb_table = { 50 .entries = {
51 {204000000UL, {1112619, -29295, 402} }, 51 { 204000000UL, { 1112619, -29295, 402 } },
52 {306000000UL, {1150460, -30585, 402} }, 52 { 306000000UL, { 1150460, -30585, 402 } },
53 {408000000UL, {1190122, -31865, 402} }, 53 { 408000000UL, { 1190122, -31865, 402 } },
54 {510000000UL, {1231606, -33155, 402} }, 54 { 510000000UL, { 1231606, -33155, 402 } },
55 {612000000UL, {1274912, -34435, 402} }, 55 { 612000000UL, { 1274912, -34435, 402 } },
56 {714000000UL, {1320040, -35725, 402} }, 56 { 714000000UL, { 1320040, -35725, 402 } },
57 {816000000UL, {1366990, -37005, 402} }, 57 { 816000000UL, { 1366990, -37005, 402 } },
58 {918000000UL, {1415762, -38295, 402} }, 58 { 918000000UL, { 1415762, -38295, 402 } },
59 {1020000000UL, {1466355, -39575, 402} }, 59 { 1020000000UL, { 1466355, -39575, 402 } },
60 {1122000000UL, {1518771, -40865, 402} }, 60 { 1122000000UL, { 1518771, -40865, 402 } },
61 {1224000000UL, {1573009, -42145, 402} }, 61 { 1224000000UL, { 1573009, -42145, 402 } },
62 {1326000000UL, {1629068, -43435, 402} }, 62 { 1326000000UL, { 1629068, -43435, 402 } },
63 {1428000000UL, {1686950, -44715, 402} }, 63 { 1428000000UL, { 1686950, -44715, 402 } },
64 {1530000000UL, {1746653, -46005, 402} }, 64 { 1530000000UL, { 1746653, -46005, 402 } },
65 {1632000000UL, {1808179, -47285, 402} }, 65 { 1632000000UL, { 1808179, -47285, 402 } },
66 {1734000000UL, {1871526, -48575, 402} }, 66 { 1734000000UL, { 1871526, -48575, 402 } },
67 {1836000000UL, {1936696, -49855, 402} }, 67 { 1836000000UL, { 1936696, -49855, 402 } },
68 {1938000000UL, {2003687, -51145, 402} }, 68 { 1938000000UL, { 2003687, -51145, 402 } },
69 {2014500000UL, {2054787, -52095, 402} }, 69 { 2014500000UL, { 2054787, -52095, 402 } },
70 {2116500000UL, {2124957, -53385, 402} }, 70 { 2116500000UL, { 2124957, -53385, 402 } },
71 {2218500000UL, {2196950, -54665, 402} }, 71 { 2218500000UL, { 2196950, -54665, 402 } },
72 {2320500000UL, {2270765, -55955, 402} }, 72 { 2320500000UL, { 2270765, -55955, 402 } },
73 {2422500000UL, {2346401, -57235, 402} }, 73 { 2422500000UL, { 2346401, -57235, 402 } },
74 {2524500000UL, {2437299, -58535, 402} }, 74 { 2524500000UL, { 2437299, -58535, 402 } },
75 {0, { 0, 0, 0} }, 75 { 0UL, { 0, 0, 0 } },
76 }, 76 },
77 .cpu_dfll_data = { 77 .cpu_dfll_data = {
78 .tune0_low = 0x005020ff, 78 .tune0_low = 0x005020ff,
@@ -84,9 +84,8 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
84 84
85static int tegra124_dfll_fcpu_probe(struct platform_device *pdev) 85static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
86{ 86{
87 int process_id, speedo_id, speedo_value; 87 int process_id, speedo_id, speedo_value, err;
88 struct tegra_dfll_soc_data *soc; 88 struct tegra_dfll_soc_data *soc;
89 const struct cvb_table *cvb;
90 89
91 process_id = tegra_sku_info.cpu_process_id; 90 process_id = tegra_sku_info.cpu_process_id;
92 speedo_id = tegra_sku_info.cpu_speedo_id; 91 speedo_id = tegra_sku_info.cpu_speedo_id;
@@ -108,23 +107,41 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
108 return -ENODEV; 107 return -ENODEV;
109 } 108 }
110 109
111 cvb = tegra_cvb_build_opp_table(tegra124_cpu_cvb_tables, 110 soc->max_freq = cpu_max_freq_table[speedo_id];
112 ARRAY_SIZE(tegra124_cpu_cvb_tables), 111
113 process_id, speedo_id, speedo_value, 112 soc->cvb = tegra_cvb_add_opp_table(soc->dev, tegra124_cpu_cvb_tables,
114 cpu_max_freq_table[speedo_id], 113 ARRAY_SIZE(tegra124_cpu_cvb_tables),
115 soc->dev); 114 process_id, speedo_id, speedo_value,
116 if (IS_ERR(cvb)) { 115 soc->max_freq);
117 dev_err(&pdev->dev, "couldn't build OPP table: %ld\n", 116 if (IS_ERR(soc->cvb)) {
118 PTR_ERR(cvb)); 117 dev_err(&pdev->dev, "couldn't add OPP table: %ld\n",
119 return PTR_ERR(cvb); 118 PTR_ERR(soc->cvb));
119 return PTR_ERR(soc->cvb);
120 }
121
122 err = tegra_dfll_register(pdev, soc);
123 if (err < 0) {
124 tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
125 return err;
120 } 126 }
121 127
122 soc->min_millivolts = cvb->min_millivolts; 128 platform_set_drvdata(pdev, soc);
123 soc->tune0_low = cvb->cpu_dfll_data.tune0_low; 129
124 soc->tune0_high = cvb->cpu_dfll_data.tune0_high; 130 return 0;
125 soc->tune1 = cvb->cpu_dfll_data.tune1; 131}
132
133static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
134{
135 struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev);
136 int err;
137
138 err = tegra_dfll_unregister(pdev);
139 if (err < 0)
140 dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err);
141
142 tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
126 143
127 return tegra_dfll_register(pdev, soc); 144 return 0;
128} 145}
129 146
130static const struct of_device_id tegra124_dfll_fcpu_of_match[] = { 147static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
@@ -140,7 +157,7 @@ static const struct dev_pm_ops tegra124_dfll_pm_ops = {
140 157
141static struct platform_driver tegra124_dfll_fcpu_driver = { 158static struct platform_driver tegra124_dfll_fcpu_driver = {
142 .probe = tegra124_dfll_fcpu_probe, 159 .probe = tegra124_dfll_fcpu_probe,
143 .remove = tegra_dfll_unregister, 160 .remove = tegra124_dfll_fcpu_remove,
144 .driver = { 161 .driver = {
145 .name = "tegra124-dfll", 162 .name = "tegra124-dfll",
146 .of_match_table = tegra124_dfll_fcpu_of_match, 163 .of_match_table = tegra124_dfll_fcpu_of_match,
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 1627258292d2..f4fbbf16a056 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1155,6 +1155,10 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
1155 1, 2); 1155 1, 2);
1156 clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk; 1156 clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk;
1157 1157
1158 clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base,
1159 1, 17, 181);
1160 clks[TEGRA124_CLK_DPAUX] = clk;
1161
1158 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, 1162 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
1159 clk_base + PLLD_MISC, 30, 0, &pll_d_lock); 1163 clk_base + PLLD_MISC, 30, 0, &pll_d_lock);
1160 clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk; 1164 clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk;
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 3d0edee1f9fe..b8551813ec43 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -92,6 +92,7 @@
92#define PLLE_AUX 0x48c 92#define PLLE_AUX 0x48c
93#define PLLRE_BASE 0x4c4 93#define PLLRE_BASE 0x4c4
94#define PLLRE_MISC0 0x4c8 94#define PLLRE_MISC0 0x4c8
95#define PLLRE_OUT1 0x4cc
95#define PLLDP_BASE 0x590 96#define PLLDP_BASE 0x590
96#define PLLDP_MISC 0x594 97#define PLLDP_MISC 0x594
97 98
@@ -2150,6 +2151,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
2150 [tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true }, 2151 [tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true },
2151 [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true }, 2152 [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true },
2152 [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, 2153 [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true },
2154 [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true },
2153 [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, 2155 [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true },
2154 [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, 2156 [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true },
2155 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, 2157 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true },
@@ -2461,6 +2463,18 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
2461 1, 2); 2463 1, 2);
2462 clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk; 2464 clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk;
2463 2465
2466 clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base,
2467 1, 17, 181);
2468 clks[TEGRA210_CLK_DPAUX] = clk;
2469
2470 clk = tegra_clk_register_periph_fixed("dpaux1", "pll_p", 0, clk_base,
2471 1, 17, 207);
2472 clks[TEGRA210_CLK_DPAUX1] = clk;
2473
2474 clk = tegra_clk_register_periph_fixed("sor_safe", "pll_p", 0, clk_base,
2475 1, 17, 222);
2476 clks[TEGRA210_CLK_SOR_SAFE] = clk;
2477
2464 /* pll_d_dsi_out */ 2478 /* pll_d_dsi_out */
2465 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, 2479 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
2466 clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); 2480 clk_base + PLLD_MISC0, 21, 0, &pll_d_lock);
@@ -2640,8 +2654,10 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
2640 clks[TEGRA210_CLK_PLL_D_OUT0] = clk; 2654 clks[TEGRA210_CLK_PLL_D_OUT0] = clk;
2641 2655
2642 /* PLLRE */ 2656 /* PLLRE */
2643 clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, 2657 clk = tegra_clk_register_pllre_tegra210("pll_re_vco", "pll_ref",
2644 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); 2658 clk_base, pmc, 0,
2659 &pll_re_vco_params,
2660 &pll_re_lock, pll_ref_freq);
2645 clk_register_clkdev(clk, "pll_re_vco", NULL); 2661 clk_register_clkdev(clk, "pll_re_vco", NULL);
2646 clks[TEGRA210_CLK_PLL_RE_VCO] = clk; 2662 clks[TEGRA210_CLK_PLL_RE_VCO] = clk;
2647 2663
@@ -2651,6 +2667,15 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
2651 clk_register_clkdev(clk, "pll_re_out", NULL); 2667 clk_register_clkdev(clk, "pll_re_out", NULL);
2652 clks[TEGRA210_CLK_PLL_RE_OUT] = clk; 2668 clks[TEGRA210_CLK_PLL_RE_OUT] = clk;
2653 2669
2670 clk = tegra_clk_register_divider("pll_re_out1_div", "pll_re_vco",
2671 clk_base + PLLRE_OUT1, 0,
2672 TEGRA_DIVIDER_ROUND_UP,
2673 8, 8, 1, NULL);
2674 clk = tegra_clk_register_pll_out("pll_re_out1", "pll_re_out1_div",
2675 clk_base + PLLRE_OUT1, 1, 0,
2676 CLK_SET_RATE_PARENT, 0, NULL);
2677 clks[TEGRA210_CLK_PLL_RE_OUT1] = clk;
2678
2654 /* PLLE */ 2679 /* PLLE */
2655 clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref", 2680 clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref",
2656 clk_base, 0, &pll_e_params, NULL); 2681 clk_base, 0, &pll_e_params, NULL);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 0478565cf292..9396f4930da7 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -339,11 +339,11 @@ static const struct pdiv_map pllu_p[] = {
339}; 339};
340 340
341static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { 341static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
342 { 12000000, 480000000, 960, 12, 1, 12 }, 342 { 12000000, 480000000, 960, 12, 2, 12 },
343 { 13000000, 480000000, 960, 13, 1, 12 }, 343 { 13000000, 480000000, 960, 13, 2, 12 },
344 { 16800000, 480000000, 400, 7, 1, 5 }, 344 { 16800000, 480000000, 400, 7, 2, 5 },
345 { 19200000, 480000000, 200, 4, 1, 3 }, 345 { 19200000, 480000000, 200, 4, 2, 3 },
346 { 26000000, 480000000, 960, 26, 1, 12 }, 346 { 26000000, 480000000, 960, 26, 2, 12 },
347 { 0, 0, 0, 0, 0, 0 }, 347 { 0, 0, 0, 0, 0, 0 },
348}; 348};
349 349
@@ -1372,6 +1372,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1372 { TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1372 { TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0 },
1373 { TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1373 { TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0 },
1374 { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1374 { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 },
1375 { TEGRA30_CLK_PLL_C, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
1375 { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 }, 1376 { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 },
1376 { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 }, 1377 { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 },
1377 { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 }, 1378 { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 },
@@ -1379,6 +1380,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
1379 { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1380 { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 },
1380 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1381 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
1381 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1382 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
1383 { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
1382 /* must be the last entry */ 1384 /* must be the last entry */
1383 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, 1385 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
1384}; 1386};
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index f60fe2e344ca..b2cdd9a235f4 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -84,7 +84,7 @@ static int (*special_reset_assert)(unsigned long);
84static int (*special_reset_deassert)(unsigned long); 84static int (*special_reset_deassert)(unsigned long);
85static unsigned int num_special_reset; 85static unsigned int num_special_reset;
86 86
87static struct tegra_clk_periph_regs periph_regs[] = { 87static const struct tegra_clk_periph_regs periph_regs[] = {
88 [0] = { 88 [0] = {
89 .enb_reg = CLK_OUT_ENB_L, 89 .enb_reg = CLK_OUT_ENB_L,
90 .enb_set_reg = CLK_OUT_ENB_SET_L, 90 .enb_set_reg = CLK_OUT_ENB_SET_L,
@@ -182,7 +182,7 @@ static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev,
182 return -EINVAL; 182 return -EINVAL;
183} 183}
184 184
185struct tegra_clk_periph_regs *get_reg_bank(int clkid) 185const struct tegra_clk_periph_regs *get_reg_bank(int clkid)
186{ 186{
187 int reg_bank = clkid / 32; 187 int reg_bank = clkid / 32;
188 188
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 4dbcfaec576a..9421f0310999 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -386,6 +386,12 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
386 struct tegra_clk_pll_params *pll_params, 386 struct tegra_clk_pll_params *pll_params,
387 spinlock_t *lock, unsigned long parent_rate); 387 spinlock_t *lock, unsigned long parent_rate);
388 388
389struct clk *tegra_clk_register_pllre_tegra210(const char *name,
390 const char *parent_name, void __iomem *clk_base,
391 void __iomem *pmc, unsigned long flags,
392 struct tegra_clk_pll_params *pll_params,
393 spinlock_t *lock, unsigned long parent_rate);
394
389struct clk *tegra_clk_register_plle_tegra114(const char *name, 395struct clk *tegra_clk_register_plle_tegra114(const char *name,
390 const char *parent_name, 396 const char *parent_name,
391 void __iomem *clk_base, unsigned long flags, 397 void __iomem *clk_base, unsigned long flags,
@@ -496,7 +502,7 @@ struct tegra_clk_periph_gate {
496 u8 flags; 502 u8 flags;
497 int clk_num; 503 int clk_num;
498 int *enable_refcnt; 504 int *enable_refcnt;
499 struct tegra_clk_periph_regs *regs; 505 const struct tegra_clk_periph_regs *regs;
500}; 506};
501 507
502#define to_clk_periph_gate(_hw) \ 508#define to_clk_periph_gate(_hw) \
@@ -516,6 +522,23 @@ struct clk *tegra_clk_register_periph_gate(const char *name,
516 const char *parent_name, u8 gate_flags, void __iomem *clk_base, 522 const char *parent_name, u8 gate_flags, void __iomem *clk_base,
517 unsigned long flags, int clk_num, int *enable_refcnt); 523 unsigned long flags, int clk_num, int *enable_refcnt);
518 524
525struct tegra_clk_periph_fixed {
526 struct clk_hw hw;
527 void __iomem *base;
528 const struct tegra_clk_periph_regs *regs;
529 unsigned int mul;
530 unsigned int div;
531 unsigned int num;
532};
533
534struct clk *tegra_clk_register_periph_fixed(const char *name,
535 const char *parent,
536 unsigned long flags,
537 void __iomem *base,
538 unsigned int mul,
539 unsigned int div,
540 unsigned int num);
541
519/** 542/**
520 * struct clk-periph - peripheral clock 543 * struct clk-periph - peripheral clock
521 * 544 *
@@ -716,7 +739,7 @@ void tegra_init_from_table(struct tegra_clk_init_table *tbl,
716void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, 739void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
717 struct clk *clks[], int clk_max); 740 struct clk *clks[], int clk_max);
718 741
719struct tegra_clk_periph_regs *get_reg_bank(int clkid); 742const struct tegra_clk_periph_regs *get_reg_bank(int clkid);
720struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks); 743struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
721 744
722struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); 745struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
diff --git a/drivers/clk/tegra/cvb.c b/drivers/clk/tegra/cvb.c
index 69c74eec3a4b..624115e82ff9 100644
--- a/drivers/clk/tegra/cvb.c
+++ b/drivers/clk/tegra/cvb.c
@@ -61,29 +61,28 @@ static int round_voltage(int mv, const struct rail_alignment *align, int up)
61 return mv; 61 return mv;
62} 62}
63 63
64static int build_opp_table(const struct cvb_table *d, 64static int build_opp_table(struct device *dev, const struct cvb_table *table,
65 int speedo_value, 65 int speedo_value, unsigned long max_freq)
66 unsigned long max_freq,
67 struct device *opp_dev)
68{ 66{
67 const struct rail_alignment *align = &table->alignment;
69 int i, ret, dfll_mv, min_mv, max_mv; 68 int i, ret, dfll_mv, min_mv, max_mv;
70 const struct cvb_table_freq_entry *table = NULL;
71 const struct rail_alignment *align = &d->alignment;
72 69
73 min_mv = round_voltage(d->min_millivolts, align, UP); 70 min_mv = round_voltage(table->min_millivolts, align, UP);
74 max_mv = round_voltage(d->max_millivolts, align, DOWN); 71 max_mv = round_voltage(table->max_millivolts, align, DOWN);
75 72
76 for (i = 0; i < MAX_DVFS_FREQS; i++) { 73 for (i = 0; i < MAX_DVFS_FREQS; i++) {
77 table = &d->cvb_table[i]; 74 const struct cvb_table_freq_entry *entry = &table->entries[i];
78 if (!table->freq || (table->freq > max_freq)) 75
76 if (!entry->freq || (entry->freq > max_freq))
79 break; 77 break;
80 78
81 dfll_mv = get_cvb_voltage( 79 dfll_mv = get_cvb_voltage(speedo_value, table->speedo_scale,
82 speedo_value, d->speedo_scale, &table->coefficients); 80 &entry->coefficients);
83 dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align); 81 dfll_mv = round_cvb_voltage(dfll_mv, table->voltage_scale,
82 align);
84 dfll_mv = clamp(dfll_mv, min_mv, max_mv); 83 dfll_mv = clamp(dfll_mv, min_mv, max_mv);
85 84
86 ret = dev_pm_opp_add(opp_dev, table->freq, dfll_mv * 1000); 85 ret = dev_pm_opp_add(dev, entry->freq, dfll_mv * 1000);
87 if (ret) 86 if (ret)
88 return ret; 87 return ret;
89 } 88 }
@@ -92,7 +91,7 @@ static int build_opp_table(const struct cvb_table *d,
92} 91}
93 92
94/** 93/**
95 * tegra_cvb_build_opp_table - build OPP table from Tegra CVB tables 94 * tegra_cvb_add_opp_table - build OPP table from Tegra CVB tables
96 * @cvb_tables: array of CVB tables 95 * @cvb_tables: array of CVB tables
97 * @sz: size of the previously mentioned array 96 * @sz: size of the previously mentioned array
98 * @process_id: process id of the HW module 97 * @process_id: process id of the HW module
@@ -108,26 +107,42 @@ static int build_opp_table(const struct cvb_table *d,
108 * given @opp_dev. Returns a pointer to the struct cvb_table that matched 107 * given @opp_dev. Returns a pointer to the struct cvb_table that matched
109 * or an ERR_PTR on failure. 108 * or an ERR_PTR on failure.
110 */ 109 */
111const struct cvb_table *tegra_cvb_build_opp_table( 110const struct cvb_table *
112 const struct cvb_table *cvb_tables, 111tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables,
113 size_t sz, int process_id, 112 size_t count, int process_id, int speedo_id,
114 int speedo_id, int speedo_value, 113 int speedo_value, unsigned long max_freq)
115 unsigned long max_rate,
116 struct device *opp_dev)
117{ 114{
118 int i, ret; 115 size_t i;
116 int ret;
119 117
120 for (i = 0; i < sz; i++) { 118 for (i = 0; i < count; i++) {
121 const struct cvb_table *d = &cvb_tables[i]; 119 const struct cvb_table *table = &tables[i];
122 120
123 if (d->speedo_id != -1 && d->speedo_id != speedo_id) 121 if (table->speedo_id != -1 && table->speedo_id != speedo_id)
124 continue; 122 continue;
125 if (d->process_id != -1 && d->process_id != process_id) 123
124 if (table->process_id != -1 && table->process_id != process_id)
126 continue; 125 continue;
127 126
128 ret = build_opp_table(d, speedo_value, max_rate, opp_dev); 127 ret = build_opp_table(dev, table, speedo_value, max_freq);
129 return ret ? ERR_PTR(ret) : d; 128 return ret ? ERR_PTR(ret) : table;
130 } 129 }
131 130
132 return ERR_PTR(-EINVAL); 131 return ERR_PTR(-EINVAL);
133} 132}
133
134void tegra_cvb_remove_opp_table(struct device *dev,
135 const struct cvb_table *table,
136 unsigned long max_freq)
137{
138 unsigned int i;
139
140 for (i = 0; i < MAX_DVFS_FREQS; i++) {
141 const struct cvb_table_freq_entry *entry = &table->entries[i];
142
143 if (!entry->freq || (entry->freq > max_freq))
144 break;
145
146 dev_pm_opp_remove(dev, entry->freq);
147 }
148}
diff --git a/drivers/clk/tegra/cvb.h b/drivers/clk/tegra/cvb.h
index f62cdc4f4234..c1f077993b2a 100644
--- a/drivers/clk/tegra/cvb.h
+++ b/drivers/clk/tegra/cvb.h
@@ -53,15 +53,16 @@ struct cvb_table {
53 53
54 int speedo_scale; 54 int speedo_scale;
55 int voltage_scale; 55 int voltage_scale;
56 struct cvb_table_freq_entry cvb_table[MAX_DVFS_FREQS]; 56 struct cvb_table_freq_entry entries[MAX_DVFS_FREQS];
57 struct cvb_cpu_dfll_data cpu_dfll_data; 57 struct cvb_cpu_dfll_data cpu_dfll_data;
58}; 58};
59 59
60const struct cvb_table *tegra_cvb_build_opp_table( 60const struct cvb_table *
61 const struct cvb_table *cvb_tables, 61tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *cvb_tables,
62 size_t sz, int process_id, 62 size_t count, int process_id, int speedo_id,
63 int speedo_id, int speedo_value, 63 int speedo_value, unsigned long max_freq);
64 unsigned long max_rate, 64void tegra_cvb_remove_opp_table(struct device *dev,
65 struct device *opp_dev); 65 const struct cvb_table *table,
66 unsigned long max_freq);
66 67
67#endif 68#endif
diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c
index 59ce2fa2c104..294bc03ec067 100644
--- a/drivers/clk/ti/clk-54xx.c
+++ b/drivers/clk/ti/clk-54xx.c
@@ -210,6 +210,7 @@ static struct ti_dt_clk omap54xx_clks[] = {
210 DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"), 210 DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
211 DT_CLK("omap_wdt", "ick", "dummy_ck"), 211 DT_CLK("omap_wdt", "ick", "dummy_ck"),
212 DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), 212 DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
213 DT_CLK(NULL, "sys_clkin_ck", "sys_clkin"),
213 DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin"), 214 DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin"),
214 DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin"), 215 DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin"),
215 DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin"), 216 DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin"),
diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index 6b5a309d9939..bfa17d33ef3b 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -289,6 +289,7 @@ static struct ti_dt_clk dra7xx_clks[] = {
289 DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"), 289 DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
290 DT_CLK("omap_wdt", "ick", "dummy_ck"), 290 DT_CLK("omap_wdt", "ick", "dummy_ck"),
291 DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), 291 DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
292 DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"),
292 DT_CLK("4ae18000.timer", "timer_sys_ck", "timer_sys_clk_div"), 293 DT_CLK("4ae18000.timer", "timer_sys_ck", "timer_sys_clk_div"),
293 DT_CLK("48032000.timer", "timer_sys_ck", "timer_sys_clk_div"), 294 DT_CLK("48032000.timer", "timer_sys_ck", "timer_sys_clk_div"),
294 DT_CLK("48034000.timer", "timer_sys_ck", "timer_sys_clk_div"), 295 DT_CLK("48034000.timer", "timer_sys_ck", "timer_sys_clk_div"),
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index 2e14dfb588f4..c77333230bdf 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -265,6 +265,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
265 265
266 /* Get configuration for the ATL instances */ 266 /* Get configuration for the ATL instances */
267 snprintf(prop, sizeof(prop), "atl%u", i); 267 snprintf(prop, sizeof(prop), "atl%u", i);
268 of_node_get(node);
268 cfg_node = of_find_node_by_name(node, prop); 269 cfg_node = of_find_node_by_name(node, prop);
269 if (cfg_node) { 270 if (cfg_node) {
270 ret = of_property_read_u32(cfg_node, "bws", 271 ret = of_property_read_u32(cfg_node, "bws",
@@ -278,6 +279,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
278 atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i), 279 atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i),
279 cdesc->aws); 280 cdesc->aws);
280 } 281 }
282 of_node_put(cfg_node);
281 } 283 }
282 284
283 cdesc->probed = true; 285 cdesc->probed = true;
diff --git a/drivers/clk/ti/clkt_dflt.c b/drivers/clk/ti/clkt_dflt.c
index 1ddc288fce4e..c6ae563801d7 100644
--- a/drivers/clk/ti/clkt_dflt.c
+++ b/drivers/clk/ti/clkt_dflt.c
@@ -222,7 +222,7 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
222 } 222 }
223 } 223 }
224 224
225 if (unlikely(IS_ERR(clk->enable_reg))) { 225 if (IS_ERR(clk->enable_reg)) {
226 pr_err("%s: %s missing enable_reg\n", __func__, 226 pr_err("%s: %s missing enable_reg\n", __func__,
227 clk_hw_get_name(hw)); 227 clk_hw_get_name(hw));
228 ret = -EINVAL; 228 ret = -EINVAL;
diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c
index 032c658a5f5e..b919fdfe8256 100644
--- a/drivers/clk/ti/clkt_dpll.c
+++ b/drivers/clk/ti/clkt_dpll.c
@@ -301,6 +301,9 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
301 301
302 dd = clk->dpll_data; 302 dd = clk->dpll_data;
303 303
304 if (dd->max_rate && target_rate > dd->max_rate)
305 target_rate = dd->max_rate;
306
304 ref_rate = clk_hw_get_rate(dd->clk_ref); 307 ref_rate = clk_hw_get_rate(dd->clk_ref);
305 clk_name = clk_hw_get_name(hw); 308 clk_name = clk_hw_get_name(hw);
306 pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n", 309 pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 3bc9959f71c3..9fc8754a6e61 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -655,6 +655,7 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
655 .max_multiplier = 2047, 655 .max_multiplier = 2047,
656 .max_divider = 128, 656 .max_divider = 128,
657 .min_divider = 1, 657 .min_divider = 1,
658 .max_rate = 1000000000,
658 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 659 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
659 }; 660 };
660 661
@@ -674,6 +675,7 @@ static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
674 .max_divider = 256, 675 .max_divider = 256,
675 .min_divider = 2, 676 .min_divider = 2,
676 .flags = DPLL_J_TYPE, 677 .flags = DPLL_J_TYPE,
678 .max_rate = 2000000000,
677 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 679 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
678 }; 680 };
679 681
@@ -692,6 +694,7 @@ static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
692 .max_multiplier = 2047, 694 .max_multiplier = 2047,
693 .max_divider = 128, 695 .max_divider = 128,
694 .min_divider = 1, 696 .min_divider = 1,
697 .max_rate = 2000000000,
695 .flags = DPLL_J_TYPE, 698 .flags = DPLL_J_TYPE,
696 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 699 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
697 }; 700 };
@@ -712,6 +715,7 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node)
712 .max_multiplier = 2047, 715 .max_multiplier = 2047,
713 .max_divider = 128, 716 .max_divider = 128,
714 .min_divider = 1, 717 .min_divider = 1,
718 .max_rate = 1000000000,
715 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 719 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
716 }; 720 };
717 721
@@ -729,6 +733,7 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
729 .max_multiplier = 2047, 733 .max_multiplier = 2047,
730 .max_divider = 128, 734 .max_divider = 128,
731 .min_divider = 1, 735 .min_divider = 1,
736 .max_rate = 1000000000,
732 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 737 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
733 }; 738 };
734 739
diff --git a/drivers/clk/zte/clk-zx296702.c b/drivers/clk/zte/clk-zx296702.c
index ebd20d852e73..76e967c19775 100644
--- a/drivers/clk/zte/clk-zx296702.c
+++ b/drivers/clk/zte/clk-zx296702.c
@@ -234,8 +234,7 @@ static void __init zx296702_top_clocks_init(struct device_node *np)
234 WARN_ON(!topcrm_base); 234 WARN_ON(!topcrm_base);
235 235
236 clk[ZX296702_OSC] = 236 clk[ZX296702_OSC] =
237 clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, 237 clk_register_fixed_rate(NULL, "osc", NULL, 0, 30000000);
238 30000000);
239 clk[ZX296702_PLL_A9] = 238 clk[ZX296702_PLL_A9] =
240 clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base 239 clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base
241 + 0x01c, pll_a9_config, 240 + 0x01c, pll_a9_config,