aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/Kconfig8
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-lochnagar.c336
-rw-r--r--drivers/clk/clk-qoriq.c77
-rw-r--r--drivers/clk/hisilicon/clk-hi3660.c6
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c36
-rw-r--r--drivers/clk/rockchip/clk-rk3328.c18
-rw-r--r--drivers/clk/rockchip/clk.c9
-rw-r--r--drivers/clk/rockchip/clk.h23
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun50i-a64.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun50i-h6.c19
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.h4
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a83t.c5
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-v3s.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c2
-rw-r--r--drivers/clk/sunxi/Kconfig43
-rw-r--r--drivers/clk/sunxi/Makefile49
17 files changed, 576 insertions, 66 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e705aab9e38b..03854a9d6f5e 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -219,6 +219,13 @@ config COMMON_CLK_XGENE
219 ---help--- 219 ---help---
220 Sypport for the APM X-Gene SoC reference, PLL, and device clocks. 220 Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
221 221
222config COMMON_CLK_LOCHNAGAR
223 tristate "Cirrus Logic Lochnagar clock driver"
224 depends on MFD_LOCHNAGAR
225 help
226 This driver supports the clocking features of the Cirrus Logic
227 Lochnagar audio development board.
228
222config COMMON_CLK_NXP 229config COMMON_CLK_NXP
223 def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX) 230 def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
224 select REGMAP_MMIO if ARCH_LPC32XX 231 select REGMAP_MMIO if ARCH_LPC32XX
@@ -310,6 +317,7 @@ source "drivers/clk/qcom/Kconfig"
310source "drivers/clk/renesas/Kconfig" 317source "drivers/clk/renesas/Kconfig"
311source "drivers/clk/samsung/Kconfig" 318source "drivers/clk/samsung/Kconfig"
312source "drivers/clk/sprd/Kconfig" 319source "drivers/clk/sprd/Kconfig"
320source "drivers/clk/sunxi/Kconfig"
313source "drivers/clk/sunxi-ng/Kconfig" 321source "drivers/clk/sunxi-ng/Kconfig"
314source "drivers/clk/tegra/Kconfig" 322source "drivers/clk/tegra/Kconfig"
315source "drivers/clk/ti/Kconfig" 323source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 6415e37548e8..020ff8d635f2 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
32obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o 32obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
33obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 33obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
34obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o 34obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o
35obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o
35obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 36obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
36obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o 37obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o
37obj-$(CONFIG_ARCH_MILBEAUT_M10V) += clk-milbeaut.o 38obj-$(CONFIG_ARCH_MILBEAUT_M10V) += clk-milbeaut.o
diff --git a/drivers/clk/clk-lochnagar.c b/drivers/clk/clk-lochnagar.c
new file mode 100644
index 000000000000..a2f31e58ee48
--- /dev/null
+++ b/drivers/clk/clk-lochnagar.c
@@ -0,0 +1,336 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Lochnagar clock control
4 *
5 * Copyright (c) 2017-2018 Cirrus Logic, Inc. and
6 * Cirrus Logic International Semiconductor Ltd.
7 *
8 * Author: Charles Keepax <ckeepax@opensource.cirrus.com>
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/device.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/platform_device.h>
17#include <linux/regmap.h>
18
19#include <linux/mfd/lochnagar.h>
20#include <linux/mfd/lochnagar1_regs.h>
21#include <linux/mfd/lochnagar2_regs.h>
22
23#include <dt-bindings/clk/lochnagar.h>
24
25#define LOCHNAGAR_NUM_CLOCKS (LOCHNAGAR_SPDIF_CLKOUT + 1)
26
27struct lochnagar_clk {
28 const char * const name;
29 struct clk_hw hw;
30
31 struct lochnagar_clk_priv *priv;
32
33 u16 cfg_reg;
34 u16 ena_mask;
35
36 u16 src_reg;
37 u16 src_mask;
38};
39
40struct lochnagar_clk_priv {
41 struct device *dev;
42 struct regmap *regmap;
43 enum lochnagar_type type;
44
45 const char **parents;
46 unsigned int nparents;
47
48 struct lochnagar_clk lclks[LOCHNAGAR_NUM_CLOCKS];
49};
50
51static const char * const lochnagar1_clk_parents[] = {
52 "ln-none",
53 "ln-spdif-mclk",
54 "ln-psia1-mclk",
55 "ln-psia2-mclk",
56 "ln-cdc-clkout",
57 "ln-dsp-clkout",
58 "ln-pmic-32k",
59 "ln-gf-mclk1",
60 "ln-gf-mclk3",
61 "ln-gf-mclk2",
62 "ln-gf-mclk4",
63};
64
65static const char * const lochnagar2_clk_parents[] = {
66 "ln-none",
67 "ln-cdc-clkout",
68 "ln-dsp-clkout",
69 "ln-pmic-32k",
70 "ln-spdif-mclk",
71 "ln-clk-12m",
72 "ln-clk-11m",
73 "ln-clk-24m",
74 "ln-clk-22m",
75 "ln-clk-8m",
76 "ln-usb-clk-24m",
77 "ln-gf-mclk1",
78 "ln-gf-mclk3",
79 "ln-gf-mclk2",
80 "ln-psia1-mclk",
81 "ln-psia2-mclk",
82 "ln-spdif-clkout",
83 "ln-adat-mclk",
84 "ln-usb-clk-12m",
85};
86
87#define LN1_CLK(ID, NAME, REG) \
88 [LOCHNAGAR_##ID] = { \
89 .name = NAME, \
90 .cfg_reg = LOCHNAGAR1_##REG, \
91 .ena_mask = LOCHNAGAR1_##ID##_ENA_MASK, \
92 .src_reg = LOCHNAGAR1_##ID##_SEL, \
93 .src_mask = LOCHNAGAR1_SRC_MASK, \
94 }
95
96#define LN2_CLK(ID, NAME) \
97 [LOCHNAGAR_##ID] = { \
98 .name = NAME, \
99 .cfg_reg = LOCHNAGAR2_##ID##_CTRL, \
100 .src_reg = LOCHNAGAR2_##ID##_CTRL, \
101 .ena_mask = LOCHNAGAR2_CLK_ENA_MASK, \
102 .src_mask = LOCHNAGAR2_CLK_SRC_MASK, \
103 }
104
105static const struct lochnagar_clk lochnagar1_clks[LOCHNAGAR_NUM_CLOCKS] = {
106 LN1_CLK(CDC_MCLK1, "ln-cdc-mclk1", CDC_AIF_CTRL2),
107 LN1_CLK(CDC_MCLK2, "ln-cdc-mclk2", CDC_AIF_CTRL2),
108 LN1_CLK(DSP_CLKIN, "ln-dsp-clkin", DSP_AIF),
109 LN1_CLK(GF_CLKOUT1, "ln-gf-clkout1", GF_AIF1),
110};
111
112static const struct lochnagar_clk lochnagar2_clks[LOCHNAGAR_NUM_CLOCKS] = {
113 LN2_CLK(CDC_MCLK1, "ln-cdc-mclk1"),
114 LN2_CLK(CDC_MCLK2, "ln-cdc-mclk2"),
115 LN2_CLK(DSP_CLKIN, "ln-dsp-clkin"),
116 LN2_CLK(GF_CLKOUT1, "ln-gf-clkout1"),
117 LN2_CLK(GF_CLKOUT2, "ln-gf-clkout2"),
118 LN2_CLK(PSIA1_MCLK, "ln-psia1-mclk"),
119 LN2_CLK(PSIA2_MCLK, "ln-psia2-mclk"),
120 LN2_CLK(SPDIF_MCLK, "ln-spdif-mclk"),
121 LN2_CLK(ADAT_MCLK, "ln-adat-mclk"),
122 LN2_CLK(SOUNDCARD_MCLK, "ln-soundcard-mclk"),
123};
124
125static inline struct lochnagar_clk *lochnagar_hw_to_lclk(struct clk_hw *hw)
126{
127 return container_of(hw, struct lochnagar_clk, hw);
128}
129
130static int lochnagar_clk_prepare(struct clk_hw *hw)
131{
132 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
133 struct lochnagar_clk_priv *priv = lclk->priv;
134 struct regmap *regmap = priv->regmap;
135 int ret;
136
137 ret = regmap_update_bits(regmap, lclk->cfg_reg,
138 lclk->ena_mask, lclk->ena_mask);
139 if (ret < 0)
140 dev_dbg(priv->dev, "Failed to prepare %s: %d\n",
141 lclk->name, ret);
142
143 return ret;
144}
145
146static void lochnagar_clk_unprepare(struct clk_hw *hw)
147{
148 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
149 struct lochnagar_clk_priv *priv = lclk->priv;
150 struct regmap *regmap = priv->regmap;
151 int ret;
152
153 ret = regmap_update_bits(regmap, lclk->cfg_reg, lclk->ena_mask, 0);
154 if (ret < 0)
155 dev_dbg(priv->dev, "Failed to unprepare %s: %d\n",
156 lclk->name, ret);
157}
158
159static int lochnagar_clk_set_parent(struct clk_hw *hw, u8 index)
160{
161 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
162 struct lochnagar_clk_priv *priv = lclk->priv;
163 struct regmap *regmap = priv->regmap;
164 int ret;
165
166 ret = regmap_update_bits(regmap, lclk->src_reg, lclk->src_mask, index);
167 if (ret < 0)
168 dev_dbg(priv->dev, "Failed to reparent %s: %d\n",
169 lclk->name, ret);
170
171 return ret;
172}
173
174static u8 lochnagar_clk_get_parent(struct clk_hw *hw)
175{
176 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
177 struct lochnagar_clk_priv *priv = lclk->priv;
178 struct regmap *regmap = priv->regmap;
179 unsigned int val;
180 int ret;
181
182 ret = regmap_read(regmap, lclk->src_reg, &val);
183 if (ret < 0) {
184 dev_dbg(priv->dev, "Failed to read parent of %s: %d\n",
185 lclk->name, ret);
186 return priv->nparents;
187 }
188
189 val &= lclk->src_mask;
190
191 return val;
192}
193
194static const struct clk_ops lochnagar_clk_ops = {
195 .prepare = lochnagar_clk_prepare,
196 .unprepare = lochnagar_clk_unprepare,
197 .set_parent = lochnagar_clk_set_parent,
198 .get_parent = lochnagar_clk_get_parent,
199};
200
201static int lochnagar_init_parents(struct lochnagar_clk_priv *priv)
202{
203 struct device_node *np = priv->dev->of_node;
204 int i, j;
205
206 switch (priv->type) {
207 case LOCHNAGAR1:
208 memcpy(priv->lclks, lochnagar1_clks, sizeof(lochnagar1_clks));
209
210 priv->nparents = ARRAY_SIZE(lochnagar1_clk_parents);
211 priv->parents = devm_kmemdup(priv->dev, lochnagar1_clk_parents,
212 sizeof(lochnagar1_clk_parents),
213 GFP_KERNEL);
214 break;
215 case LOCHNAGAR2:
216 memcpy(priv->lclks, lochnagar2_clks, sizeof(lochnagar2_clks));
217
218 priv->nparents = ARRAY_SIZE(lochnagar2_clk_parents);
219 priv->parents = devm_kmemdup(priv->dev, lochnagar2_clk_parents,
220 sizeof(lochnagar2_clk_parents),
221 GFP_KERNEL);
222 break;
223 default:
224 dev_err(priv->dev, "Unknown Lochnagar type: %d\n", priv->type);
225 return -EINVAL;
226 }
227
228 if (!priv->parents)
229 return -ENOMEM;
230
231 for (i = 0; i < priv->nparents; i++) {
232 j = of_property_match_string(np, "clock-names",
233 priv->parents[i]);
234 if (j >= 0)
235 priv->parents[i] = of_clk_get_parent_name(np, j);
236 }
237
238 return 0;
239}
240
241static struct clk_hw *
242lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data)
243{
244 struct lochnagar_clk_priv *priv = data;
245 unsigned int idx = clkspec->args[0];
246
247 if (idx >= ARRAY_SIZE(priv->lclks)) {
248 dev_err(priv->dev, "Invalid index %u\n", idx);
249 return ERR_PTR(-EINVAL);
250 }
251
252 return &priv->lclks[idx].hw;
253}
254
255static int lochnagar_init_clks(struct lochnagar_clk_priv *priv)
256{
257 struct clk_init_data clk_init = {
258 .ops = &lochnagar_clk_ops,
259 .parent_names = priv->parents,
260 .num_parents = priv->nparents,
261 };
262 struct lochnagar_clk *lclk;
263 int ret, i;
264
265 for (i = 0; i < ARRAY_SIZE(priv->lclks); i++) {
266 lclk = &priv->lclks[i];
267
268 if (!lclk->name)
269 continue;
270
271 clk_init.name = lclk->name;
272
273 lclk->priv = priv;
274 lclk->hw.init = &clk_init;
275
276 ret = devm_clk_hw_register(priv->dev, &lclk->hw);
277 if (ret) {
278 dev_err(priv->dev, "Failed to register %s: %d\n",
279 lclk->name, ret);
280 return ret;
281 }
282 }
283
284 ret = devm_of_clk_add_hw_provider(priv->dev, lochnagar_of_clk_hw_get,
285 priv);
286 if (ret < 0)
287 dev_err(priv->dev, "Failed to register provider: %d\n", ret);
288
289 return ret;
290}
291
292static const struct of_device_id lochnagar_of_match[] = {
293 { .compatible = "cirrus,lochnagar1-clk", .data = (void *)LOCHNAGAR1 },
294 { .compatible = "cirrus,lochnagar2-clk", .data = (void *)LOCHNAGAR2 },
295 {}
296};
297MODULE_DEVICE_TABLE(of, lochnagar_of_match);
298
299static int lochnagar_clk_probe(struct platform_device *pdev)
300{
301 struct device *dev = &pdev->dev;
302 struct lochnagar_clk_priv *priv;
303 const struct of_device_id *of_id;
304 int ret;
305
306 of_id = of_match_device(lochnagar_of_match, dev);
307 if (!of_id)
308 return -EINVAL;
309
310 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
311 if (!priv)
312 return -ENOMEM;
313
314 priv->dev = dev;
315 priv->regmap = dev_get_regmap(dev->parent, NULL);
316 priv->type = (enum lochnagar_type)of_id->data;
317
318 ret = lochnagar_init_parents(priv);
319 if (ret)
320 return ret;
321
322 return lochnagar_init_clks(priv);
323}
324
325static struct platform_driver lochnagar_clk_driver = {
326 .driver = {
327 .name = "lochnagar-clk",
328 .of_match_table = lochnagar_of_match,
329 },
330 .probe = lochnagar_clk_probe,
331};
332module_platform_driver(lochnagar_clk_driver);
333
334MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
335MODULE_DESCRIPTION("Clock driver for Cirrus Logic Lochnagar Board");
336MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 1212a9be7e80..4739a47ec8bd 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -34,6 +34,7 @@
34#define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */ 34#define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */
35#define CGB_PLL1 4 35#define CGB_PLL1 4
36#define CGB_PLL2 5 36#define CGB_PLL2 5
37#define MAX_PLL_DIV 16
37 38
38struct clockgen_pll_div { 39struct clockgen_pll_div {
39 struct clk *clk; 40 struct clk *clk;
@@ -41,7 +42,7 @@ struct clockgen_pll_div {
41}; 42};
42 43
43struct clockgen_pll { 44struct clockgen_pll {
44 struct clockgen_pll_div div[8]; 45 struct clockgen_pll_div div[MAX_PLL_DIV];
45}; 46};
46 47
47#define CLKSEL_VALID 1 48#define CLKSEL_VALID 1
@@ -79,7 +80,7 @@ struct clockgen_chipinfo {
79 const struct clockgen_muxinfo *cmux_groups[2]; 80 const struct clockgen_muxinfo *cmux_groups[2];
80 const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL]; 81 const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL];
81 void (*init_periph)(struct clockgen *cg); 82 void (*init_periph)(struct clockgen *cg);
82 int cmux_to_group[NUM_CMUX]; /* -1 terminates if fewer than NUM_CMUX */ 83 int cmux_to_group[NUM_CMUX + 1]; /* array should be -1 terminated */
83 u32 pll_mask; /* 1 << n bit set if PLL n is valid */ 84 u32 pll_mask; /* 1 << n bit set if PLL n is valid */
84 u32 flags; /* CG_xxx */ 85 u32 flags; /* CG_xxx */
85}; 86};
@@ -245,6 +246,58 @@ static const struct clockgen_muxinfo clockgen2_cmux_cgb = {
245 }, 246 },
246}; 247};
247 248
249static const struct clockgen_muxinfo ls1028a_hwa1 = {
250 {
251 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
252 { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
253 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
254 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
255 { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
256 {},
257 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
258 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
259 },
260};
261
262static const struct clockgen_muxinfo ls1028a_hwa2 = {
263 {
264 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
265 { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
266 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
267 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
268 { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
269 {},
270 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
271 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
272 },
273};
274
275static const struct clockgen_muxinfo ls1028a_hwa3 = {
276 {
277 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
278 { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
279 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
280 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
281 { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
282 {},
283 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
284 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
285 },
286};
287
288static const struct clockgen_muxinfo ls1028a_hwa4 = {
289 {
290 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
291 { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
292 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
293 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
294 { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
295 {},
296 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
297 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
298 },
299};
300
248static const struct clockgen_muxinfo ls1043a_hwa1 = { 301static const struct clockgen_muxinfo ls1043a_hwa1 = {
249 { 302 {
250 {}, 303 {},
@@ -508,6 +561,21 @@ static const struct clockgen_chipinfo chipinfo[] = {
508 .pll_mask = 0x03, 561 .pll_mask = 0x03,
509 }, 562 },
510 { 563 {
564 .compat = "fsl,ls1028a-clockgen",
565 .cmux_groups = {
566 &clockgen2_cmux_cga12
567 },
568 .hwaccel = {
569 &ls1028a_hwa1, &ls1028a_hwa2,
570 &ls1028a_hwa3, &ls1028a_hwa4
571 },
572 .cmux_to_group = {
573 0, 0, 0, 0, -1
574 },
575 .pll_mask = 0x07,
576 .flags = CG_VER3 | CG_LITTLE_ENDIAN,
577 },
578 {
511 .compat = "fsl,ls1043a-clockgen", 579 .compat = "fsl,ls1043a-clockgen",
512 .init_periph = t2080_init_periph, 580 .init_periph = t2080_init_periph,
513 .cmux_groups = { 581 .cmux_groups = {
@@ -601,7 +669,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
601 &p4080_cmux_grp1, &p4080_cmux_grp2 669 &p4080_cmux_grp1, &p4080_cmux_grp2
602 }, 670 },
603 .cmux_to_group = { 671 .cmux_to_group = {
604 0, 0, 0, 0, 1, 1, 1, 1 672 0, 0, 0, 0, 1, 1, 1, 1, -1
605 }, 673 },
606 .pll_mask = 0x1f, 674 .pll_mask = 0x1f,
607 }, 675 },
@@ -1128,7 +1196,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
1128 int ret; 1196 int ret;
1129 1197
1130 /* 1198 /*
1131 * For platform PLL, there are 8 divider clocks. 1199 * For platform PLL, there are MAX_PLL_DIV divider clocks.
1132 * For core PLL, there are 4 divider clocks at most. 1200 * For core PLL, there are 4 divider clocks at most.
1133 */ 1201 */
1134 if (idx != PLATFORM_PLL && i >= 4) 1202 if (idx != PLATFORM_PLL && i >= 4)
@@ -1423,6 +1491,7 @@ CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init);
1423CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen", clockgen_init); 1491CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen", clockgen_init);
1424CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); 1492CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
1425CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); 1493CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
1494CLK_OF_DECLARE(qoriq_clockgen_ls1028a, "fsl,ls1028a-clockgen", clockgen_init);
1426CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); 1495CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
1427CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); 1496CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
1428CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); 1497CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
diff --git a/drivers/clk/hisilicon/clk-hi3660.c b/drivers/clk/hisilicon/clk-hi3660.c
index f40419959656..794eeff0d5d2 100644
--- a/drivers/clk/hisilicon/clk-hi3660.c
+++ b/drivers/clk/hisilicon/clk-hi3660.c
@@ -163,8 +163,12 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_sep_clks[] = {
163 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 17, 0, }, 163 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 17, 0, },
164 { HI3660_CLK_GATE_ISP_SNCLK2, "clk_gate_isp_snclk2", 164 { HI3660_CLK_GATE_ISP_SNCLK2, "clk_gate_isp_snclk2",
165 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 18, 0, }, 165 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 18, 0, },
166 /*
167 * clk_gate_ufs_subsys is a system bus clock, mark it as critical
168 * clock and keep it on for system suspend and resume.
169 */
166 { HI3660_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_sysbus", 170 { HI3660_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_sysbus",
167 CLK_SET_RATE_PARENT, 0x50, 21, 0, }, 171 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0x50, 21, 0, },
168 { HI3660_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus", 172 { HI3660_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus",
169 CLK_SET_RATE_PARENT, 0x50, 28, 0, }, 173 CLK_SET_RATE_PARENT, 0x50, 28, 0, },
170 { HI3660_PCLK_GATE_DSI1, "pclk_gate_dsi1", "clk_div_cfgbus", 174 { HI3660_PCLK_GATE_DSI1, "pclk_gate_dsi1", "clk_div_cfgbus",
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 5a67b7869960..24baeb56a1b3 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -200,8 +200,8 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
200PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; 200PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
201PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; 201PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
202PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; 202PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
203PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 203PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "unstable:usbphy480m_src" };
204PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" }; 204PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "unstable:usbphy480m_src", "npll" };
205 205
206PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; 206PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
207PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; 207PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
@@ -219,7 +219,7 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
219PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; 219PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
220PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; 220PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
221 221
222PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vepu", "aclk_vdpu" }; 222PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vdpu", "aclk_vepu" };
223PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", 223PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m",
224 "sclk_otgphy0_480m" }; 224 "sclk_otgphy0_480m" };
225PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 225PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
@@ -313,13 +313,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
313 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, 313 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED,
314 RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 314 RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
315 RK3288_CLKGATE_CON(12), 6, GFLAGS), 315 RK3288_CLKGATE_CON(12), 6, GFLAGS),
316 COMPOSITE_NOMUX(0, "atclk", "armclk", CLK_IGNORE_UNUSED, 316 COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
317 RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 317 RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
318 RK3288_CLKGATE_CON(12), 7, GFLAGS), 318 RK3288_CLKGATE_CON(12), 7, GFLAGS),
319 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, 319 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED,
320 RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 320 RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
321 RK3288_CLKGATE_CON(12), 8, GFLAGS), 321 RK3288_CLKGATE_CON(12), 8, GFLAGS),
322 GATE(0, "pclk_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, 322 GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
323 RK3288_CLKGATE_CON(12), 9, GFLAGS), 323 RK3288_CLKGATE_CON(12), 9, GFLAGS),
324 GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, 324 GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
325 RK3288_CLKGATE_CON(12), 10, GFLAGS), 325 RK3288_CLKGATE_CON(12), 10, GFLAGS),
@@ -420,7 +420,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
420 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 420 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
421 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, 421 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
422 RK3288_CLKGATE_CON(3), 11, GFLAGS), 422 RK3288_CLKGATE_CON(3), 11, GFLAGS),
423 MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, 0, 423 MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT,
424 RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS), 424 RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
425 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0, 425 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
426 RK3288_CLKGATE_CON(9), 0, GFLAGS), 426 RK3288_CLKGATE_CON(9), 0, GFLAGS),
@@ -647,7 +647,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
647 INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out", 647 INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
648 RK3288_CLKSEL_CON(22), 7, IFLAGS), 648 RK3288_CLKSEL_CON(22), 7, IFLAGS),
649 649
650 GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED, 650 GATE(0, "jtag", "ext_jtag", 0,
651 RK3288_CLKGATE_CON(4), 14, GFLAGS), 651 RK3288_CLKGATE_CON(4), 14, GFLAGS),
652 652
653 COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0, 653 COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
@@ -656,7 +656,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
656 COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, 656 COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
657 RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, 657 RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
658 RK3288_CLKGATE_CON(3), 6, GFLAGS), 658 RK3288_CLKGATE_CON(3), 6, GFLAGS),
659 GATE(0, "hsicphy12m_xin12m", "xin12m", CLK_IGNORE_UNUSED, 659 GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
660 RK3288_CLKGATE_CON(13), 9, GFLAGS), 660 RK3288_CLKGATE_CON(13), 9, GFLAGS),
661 DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0, 661 DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0,
662 RK3288_CLKSEL_CON(11), 8, 6, DFLAGS), 662 RK3288_CLKSEL_CON(11), 8, 6, DFLAGS),
@@ -697,7 +697,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
697 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), 697 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
698 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), 698 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
699 GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), 699 GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
700 GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS), 700 GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
701 701
702 /* ddrctrl [DDR Controller PHY clock] gates */ 702 /* ddrctrl [DDR Controller PHY clock] gates */
703 GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), 703 GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
@@ -837,12 +837,9 @@ static const char *const rk3288_critical_clocks[] __initconst = {
837 "pclk_alive_niu", 837 "pclk_alive_niu",
838 "pclk_pd_pmu", 838 "pclk_pd_pmu",
839 "pclk_pmu_niu", 839 "pclk_pmu_niu",
840 "pclk_core_niu",
841 "pclk_ddrupctl0",
842 "pclk_publ0",
843 "pclk_ddrupctl1",
844 "pclk_publ1",
845 "pmu_hclk_otg0", 840 "pmu_hclk_otg0",
841 /* pwm-regulators on some boards, so handoff-critical later */
842 "pclk_rkpwm",
846}; 843};
847 844
848static void __iomem *rk3288_cru_base; 845static void __iomem *rk3288_cru_base;
@@ -859,6 +856,9 @@ static const int rk3288_saved_cru_reg_ids[] = {
859 RK3288_CLKSEL_CON(10), 856 RK3288_CLKSEL_CON(10),
860 RK3288_CLKSEL_CON(33), 857 RK3288_CLKSEL_CON(33),
861 RK3288_CLKSEL_CON(37), 858 RK3288_CLKSEL_CON(37),
859
860 /* We turn aclk_dmac1 on for suspend; this will restore it */
861 RK3288_CLKGATE_CON(10),
862}; 862};
863 863
864static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; 864static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
@@ -875,6 +875,14 @@ static int rk3288_clk_suspend(void)
875 } 875 }
876 876
877 /* 877 /*
878 * Going into deep sleep (specifically setting PMU_CLR_DMA in
879 * RK3288_PMU_PWRMODE_CON1) appears to fail unless
880 * "aclk_dmac1" is on.
881 */
882 writel_relaxed(1 << (12 + 16),
883 rk3288_cru_base + RK3288_CLKGATE_CON(10));
884
885 /*
878 * Switch PLLs other than DPLL (for SDRAM) to slow mode to 886 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
879 * avoid crashes on resume. The Mask ROM on the system will 887 * avoid crashes on resume. The Mask ROM on the system will
880 * put APLL, CPLL, and GPLL into slow mode at resume time 888 * put APLL, CPLL, and GPLL into slow mode at resume time
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index 65ab5c2f48b0..f12142d9cea2 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -458,7 +458,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
458 RK3328_CLKSEL_CON(35), 15, 1, MFLAGS, 8, 7, DFLAGS, 458 RK3328_CLKSEL_CON(35), 15, 1, MFLAGS, 8, 7, DFLAGS,
459 RK3328_CLKGATE_CON(2), 12, GFLAGS), 459 RK3328_CLKGATE_CON(2), 12, GFLAGS),
460 COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_2plls_p, 0, 460 COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_2plls_p, 0,
461 RK3328_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS, 461 RK3328_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 5, DFLAGS,
462 RK3328_CLKGATE_CON(2), 4, GFLAGS), 462 RK3328_CLKGATE_CON(2), 4, GFLAGS),
463 COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "clk_24m", 0, 463 COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "clk_24m", 0,
464 RK3328_CLKSEL_CON(22), 0, 10, DFLAGS, 464 RK3328_CLKSEL_CON(22), 0, 10, DFLAGS,
@@ -550,15 +550,15 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
550 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", 0, 550 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", 0,
551 RK3328_CLKGATE_CON(25), 1, GFLAGS), 551 RK3328_CLKGATE_CON(25), 1, GFLAGS),
552 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0, 552 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0,
553 RK3328_CLKGATE_CON(25), 0, GFLAGS), 553 RK3328_CLKGATE_CON(25), 2, GFLAGS),
554 GATE(PCLK_H265, "pclk_h265", "hclk_rkvenc", 0, 554 GATE(PCLK_H265, "pclk_h265", "hclk_rkvenc", 0,
555 RK3328_CLKGATE_CON(25), 1, GFLAGS), 555 RK3328_CLKGATE_CON(25), 3, GFLAGS),
556 GATE(ACLK_H264, "aclk_h264", "aclk_rkvenc", 0, 556 GATE(ACLK_H264, "aclk_h264", "aclk_rkvenc", 0,
557 RK3328_CLKGATE_CON(25), 0, GFLAGS), 557 RK3328_CLKGATE_CON(25), 4, GFLAGS),
558 GATE(HCLK_H264, "hclk_h264", "hclk_rkvenc", 0, 558 GATE(HCLK_H264, "hclk_h264", "hclk_rkvenc", 0,
559 RK3328_CLKGATE_CON(25), 1, GFLAGS), 559 RK3328_CLKGATE_CON(25), 5, GFLAGS),
560 GATE(ACLK_AXISRAM, "aclk_axisram", "aclk_rkvenc", CLK_IGNORE_UNUSED, 560 GATE(ACLK_AXISRAM, "aclk_axisram", "aclk_rkvenc", CLK_IGNORE_UNUSED,
561 RK3328_CLKGATE_CON(25), 0, GFLAGS), 561 RK3328_CLKGATE_CON(25), 6, GFLAGS),
562 562
563 COMPOSITE(SCLK_VENC_CORE, "sclk_venc_core", mux_4plls_p, 0, 563 COMPOSITE(SCLK_VENC_CORE, "sclk_venc_core", mux_4plls_p, 0,
564 RK3328_CLKSEL_CON(51), 14, 2, MFLAGS, 8, 5, DFLAGS, 564 RK3328_CLKSEL_CON(51), 14, 2, MFLAGS, 8, 5, DFLAGS,
@@ -663,7 +663,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
663 663
664 /* PD_GMAC */ 664 /* PD_GMAC */
665 COMPOSITE(ACLK_GMAC, "aclk_gmac", mux_2plls_hdmiphy_p, 0, 665 COMPOSITE(ACLK_GMAC, "aclk_gmac", mux_2plls_hdmiphy_p, 0,
666 RK3328_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, 666 RK3328_CLKSEL_CON(25), 6, 2, MFLAGS, 0, 5, DFLAGS,
667 RK3328_CLKGATE_CON(3), 2, GFLAGS), 667 RK3328_CLKGATE_CON(3), 2, GFLAGS),
668 COMPOSITE_NOMUX(PCLK_GMAC, "pclk_gmac", "aclk_gmac", 0, 668 COMPOSITE_NOMUX(PCLK_GMAC, "pclk_gmac", "aclk_gmac", 0,
669 RK3328_CLKSEL_CON(25), 8, 3, DFLAGS, 669 RK3328_CLKSEL_CON(25), 8, 3, DFLAGS,
@@ -733,7 +733,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
733 733
734 /* PD_PERI */ 734 /* PD_PERI */
735 GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 11, GFLAGS), 735 GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 11, GFLAGS),
736 GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0, RK3328_CLKGATE_CON(19), 4, GFLAGS), 736 GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0, RK3328_CLKGATE_CON(19), 14, GFLAGS),
737 737
738 GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 0, GFLAGS), 738 GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 0, GFLAGS),
739 GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 1, GFLAGS), 739 GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 1, GFLAGS),
@@ -913,7 +913,7 @@ static void __init rk3328_clk_init(struct device_node *np)
913 &rk3328_cpuclk_data, rk3328_cpuclk_rates, 913 &rk3328_cpuclk_data, rk3328_cpuclk_rates,
914 ARRAY_SIZE(rk3328_cpuclk_rates)); 914 ARRAY_SIZE(rk3328_cpuclk_rates));
915 915
916 rockchip_register_softrst(np, 11, reg_base + RK3328_SOFTRST_CON(0), 916 rockchip_register_softrst(np, 12, reg_base + RK3328_SOFTRST_CON(0),
917 ROCKCHIP_SOFTRST_HIWORD_MASK); 917 ROCKCHIP_SOFTRST_HIWORD_MASK);
918 918
919 rockchip_register_restart_notifier(ctx, RK3328_GLB_SRST_FST, NULL); 919 rockchip_register_restart_notifier(ctx, RK3328_GLB_SRST_FST, NULL);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index c3ad92965823..0ea8e8080d1a 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -46,7 +46,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
46 const char *const *parent_names, u8 num_parents, 46 const char *const *parent_names, u8 num_parents,
47 void __iomem *base, 47 void __iomem *base,
48 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 48 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
49 u8 div_shift, u8 div_width, u8 div_flags, 49 int div_offset, u8 div_shift, u8 div_width, u8 div_flags,
50 struct clk_div_table *div_table, int gate_offset, 50 struct clk_div_table *div_table, int gate_offset,
51 u8 gate_shift, u8 gate_flags, unsigned long flags, 51 u8 gate_shift, u8 gate_flags, unsigned long flags,
52 spinlock_t *lock) 52 spinlock_t *lock)
@@ -95,7 +95,10 @@ static struct clk *rockchip_clk_register_branch(const char *name,
95 } 95 }
96 96
97 div->flags = div_flags; 97 div->flags = div_flags;
98 div->reg = base + muxdiv_offset; 98 if (div_offset)
99 div->reg = base + div_offset;
100 else
101 div->reg = base + muxdiv_offset;
99 div->shift = div_shift; 102 div->shift = div_shift;
100 div->width = div_width; 103 div->width = div_width;
101 div->lock = lock; 104 div->lock = lock;
@@ -516,7 +519,7 @@ void __init rockchip_clk_register_branches(
516 ctx->reg_base, list->muxdiv_offset, 519 ctx->reg_base, list->muxdiv_offset,
517 list->mux_shift, 520 list->mux_shift,
518 list->mux_width, list->mux_flags, 521 list->mux_width, list->mux_flags,
519 list->div_shift, list->div_width, 522 list->div_offset, list->div_shift, list->div_width,
520 list->div_flags, list->div_table, 523 list->div_flags, list->div_table,
521 list->gate_offset, list->gate_shift, 524 list->gate_offset, list->gate_shift,
522 list->gate_flags, flags, &ctx->lock); 525 list->gate_flags, flags, &ctx->lock);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 6b53fff4cc96..1b5270755431 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -407,6 +407,7 @@ struct rockchip_clk_branch {
407 u8 mux_shift; 407 u8 mux_shift;
408 u8 mux_width; 408 u8 mux_width;
409 u8 mux_flags; 409 u8 mux_flags;
410 int div_offset;
410 u8 div_shift; 411 u8 div_shift;
411 u8 div_width; 412 u8 div_width;
412 u8 div_flags; 413 u8 div_flags;
@@ -438,6 +439,28 @@ struct rockchip_clk_branch {
438 .gate_flags = gf, \ 439 .gate_flags = gf, \
439 } 440 }
440 441
442#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
443 mf, do, ds, dw, df, go, gs, gf) \
444 { \
445 .id = _id, \
446 .branch_type = branch_composite, \
447 .name = cname, \
448 .parent_names = pnames, \
449 .num_parents = ARRAY_SIZE(pnames), \
450 .flags = f, \
451 .muxdiv_offset = mo, \
452 .mux_shift = ms, \
453 .mux_width = mw, \
454 .mux_flags = mf, \
455 .div_offset = do, \
456 .div_shift = ds, \
457 .div_width = dw, \
458 .div_flags = df, \
459 .gate_offset = go, \
460 .gate_shift = gs, \
461 .gate_flags = gf, \
462 }
463
441#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 464#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \
442 go, gs, gf) \ 465 go, gs, gf) \
443 { \ 466 { \
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 932836d26e2b..be0deee70182 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -531,7 +531,8 @@ static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram",
531 531
532static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; 532static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
533static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 533static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
534 0x104, 0, 4, 24, 3, BIT(31), 0); 534 0x104, 0, 4, 24, 3, BIT(31),
535 CLK_SET_RATE_PARENT);
535 536
536static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" }; 537static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
537static const u8 tcon0_table[] = { 0, 2, }; 538static const u8 tcon0_table[] = { 0, 2, };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index 139e8389615c..3c32d7798f27 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -266,7 +266,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600,
266 0, 4, /* M */ 266 0, 4, /* M */
267 24, 1, /* mux */ 267 24, 1, /* mux */
268 BIT(31), /* gate */ 268 BIT(31), /* gate */
269 0); 269 CLK_SET_RATE_PARENT);
270 270
271static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2", 271static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2",
272 0x60c, BIT(0), 0); 272 0x60c, BIT(0), 0);
@@ -311,7 +311,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
311 0, 3, /* M */ 311 0, 3, /* M */
312 24, 1, /* mux */ 312 24, 1, /* mux */
313 BIT(31), /* gate */ 313 BIT(31), /* gate */
314 0); 314 CLK_SET_RATE_PARENT);
315 315
316static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2", 316static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2",
317 0x69c, BIT(0), 0); 317 0x69c, BIT(0), 0);
@@ -656,6 +656,8 @@ static const char * const hdmi_cec_parents[] = { "osc32k", "pll-periph0-2x" };
656static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = { 656static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = {
657 { .index = 1, .div = 36621 }, 657 { .index = 1, .div = 36621 },
658}; 658};
659
660#define SUN50I_H6_HDMI_CEC_CLK_REG 0xb10
659static struct ccu_mux hdmi_cec_clk = { 661static struct ccu_mux hdmi_cec_clk = {
660 .enable = BIT(31), 662 .enable = BIT(31),
661 663
@@ -689,7 +691,7 @@ static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0",
689 tcon_lcd0_parents, 0xb60, 691 tcon_lcd0_parents, 0xb60,
690 24, 3, /* mux */ 692 24, 3, /* mux */
691 BIT(31), /* gate */ 693 BIT(31), /* gate */
692 0); 694 CLK_SET_RATE_PARENT);
693 695
694static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3", 696static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3",
695 0xb7c, BIT(0), 0); 697 0xb7c, BIT(0), 0);
@@ -704,7 +706,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0",
704 8, 2, /* P */ 706 8, 2, /* P */
705 24, 3, /* mux */ 707 24, 3, /* mux */
706 BIT(31), /* gate */ 708 BIT(31), /* gate */
707 0); 709 CLK_SET_RATE_PARENT);
708 710
709static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3", 711static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3",
710 0xb9c, BIT(0), 0); 712 0xb9c, BIT(0), 0);
@@ -1200,6 +1202,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
1200 val &= ~(GENMASK(21, 16) | BIT(0)); 1202 val &= ~(GENMASK(21, 16) | BIT(0));
1201 writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG); 1203 writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG);
1202 1204
1205 /*
1206 * First clock parent (osc32K) is unusable for CEC. But since there
1207 * is no good way to force parent switch (both run with same frequency),
1208 * just set second clock parent here.
1209 */
1210 val = readl(reg + SUN50I_H6_HDMI_CEC_CLK_REG);
1211 val |= BIT(24);
1212 writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
1213
1203 return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); 1214 return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
1204} 1215}
1205 1216
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
index 93a275fbd9a9..b66abd4fd0bf 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.h
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
@@ -60,10 +60,6 @@
60 60
61/* The rest of the module clocks are exported */ 61/* The rest of the module clocks are exported */
62 62
63#define CLK_MBUS 99
64
65/* And finally the IEP clock */
66
67#define CLK_NUMBER (CLK_IEP + 1) 63#define CLK_NUMBER (CLK_IEP + 1)
68 64
69#endif /* _CCU_SUN5I_H_ */ 65#endif /* _CCU_SUN5I_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
index 2d6555d73170..5f714b4d8ee4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
@@ -513,8 +513,9 @@ static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
513 513
514static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0); 514static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0);
515 515
516static const char * const csi_mclk_parents[] = { "pll-de", "osc24M" }; 516static const char * const csi_mclk_parents[] = { "pll-video0", "pll-de",
517static const u8 csi_mclk_table[] = { 3, 5 }; 517 "osc24M" };
518static const u8 csi_mclk_table[] = { 0, 3, 5 };
518static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", 519static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
519 csi_mclk_parents, csi_mclk_table, 520 csi_mclk_parents, csi_mclk_table,
520 0x134, 521 0x134,
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
index ac12f261f8ca..eada0e291859 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -325,7 +325,8 @@ static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram",
325 325
326static const char * const de_parents[] = { "pll-video", "pll-periph0" }; 326static const char * const de_parents[] = { "pll-video", "pll-periph0" };
327static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 327static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
328 0x104, 0, 4, 24, 2, BIT(31), 0); 328 0x104, 0, 4, 24, 2, BIT(31),
329 CLK_SET_RATE_PARENT);
329 330
330static const char * const tcon_parents[] = { "pll-video" }; 331static const char * const tcon_parents[] = { "pll-video" };
331static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents, 332static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
index a09dfbe36402..dc9f0a365664 100644
--- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
+++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
@@ -240,7 +240,7 @@ static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_spdif_parents,
240/* The BSP header file has a CIR_CFG, but no mod clock uses this definition */ 240/* The BSP header file has a CIR_CFG, but no mod clock uses this definition */
241 241
242static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 242static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
243 0x0cc, BIT(8), 0); 243 0x0cc, BIT(1), 0);
244 244
245static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr", 245static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
246 0x100, BIT(0), 0); 246 0x100, BIT(0), 0);
diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
new file mode 100644
index 000000000000..2b6207cc4eda
--- /dev/null
+++ b/drivers/clk/sunxi/Kconfig
@@ -0,0 +1,43 @@
1menuconfig CLK_SUNXI
2 bool "Legacy clock support for Allwinner SoCs"
3 depends on ARCH_SUNXI || COMPILE_TEST
4 default y
5
6if CLK_SUNXI
7
8config CLK_SUNXI_CLOCKS
9 bool "Legacy clock drivers"
10 default y
11 help
12 Legacy clock drivers being used on older (A10, A13, A20,
13 A23, A31, A80) SoCs. These drivers are kept around for
14 Device Tree backward compatibility issues, in case one would
15 still use a Device Tree with one clock provider by
16 node. Newer Device Trees and newer SoCs use the drivers
17 controlled by CONFIG_SUNXI_CCU.
18
19config CLK_SUNXI_PRCM_SUN6I
20 bool "Legacy A31 PRCM driver"
21 select MFD_SUN6I_PRCM
22 default y
23 help
24 Legacy clock driver for the A31 PRCM clocks. Those are
25 usually needed for the PMIC communication, mostly.
26
27config CLK_SUNXI_PRCM_SUN8I
28 bool "Legacy sun8i PRCM driver"
29 select MFD_SUN6I_PRCM
30 default y
31 help
32 Legacy clock driver for the sun8i family PRCM clocks.
33 Those are usually needed for the PMIC communication,
34 mostly.
35
36config CLK_SUNXI_PRCM_SUN9I
37 bool "Legacy A80 PRCM driver"
38 default y
39 help
40 Legacy clock driver for the A80 PRCM clocks. Those are
41 usually needed for the PMIC communication, mostly.
42
43endif
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index be88368b48a1..e10824c76ae9 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -3,27 +3,32 @@
3# Makefile for sunxi specific clk 3# Makefile for sunxi specific clk
4# 4#
5 5
6obj-y += clk-sunxi.o clk-factors.o 6obj-$(CONFIG_CLK_SUNXI) += clk-factors.o
7obj-y += clk-a10-codec.o
8obj-y += clk-a10-hosc.o
9obj-y += clk-a10-mod1.o
10obj-y += clk-a10-pll2.o
11obj-y += clk-a10-ve.o
12obj-y += clk-a20-gmac.o
13obj-y += clk-mod0.o
14obj-y += clk-simple-gates.o
15obj-y += clk-sun4i-display.o
16obj-y += clk-sun4i-pll3.o
17obj-y += clk-sun4i-tcon-ch1.o
18obj-y += clk-sun8i-bus-gates.o
19obj-y += clk-sun8i-mbus.o
20obj-y += clk-sun9i-core.o
21obj-y += clk-sun9i-mmc.o
22obj-y += clk-usb.o
23 7
24obj-$(CONFIG_MACH_SUN9I) += clk-sun8i-apb0.o 8obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sunxi.o
25obj-$(CONFIG_MACH_SUN9I) += clk-sun9i-cpus.o 9obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-codec.o
10obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-hosc.o
11obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-mod1.o
12obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-pll2.o
13obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-ve.o
14obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a20-gmac.o
15obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-mod0.o
16obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-simple-gates.o
17obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun4i-display.o
18obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun4i-pll3.o
19obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun4i-tcon-ch1.o
20obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun8i-bus-gates.o
21obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun8i-mbus.o
22obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun9i-core.o
23obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun9i-mmc.o
24obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-usb.o
26 25
27obj-$(CONFIG_MFD_SUN6I_PRCM) += \ 26obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun8i-apb0.o
28 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ 27obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun9i-cpus.o
29 clk-sun8i-apb0.o 28
29obj-$(CONFIG_CLK_SUNXI_PRCM_SUN6I) += clk-sun6i-apb0.o
30obj-$(CONFIG_CLK_SUNXI_PRCM_SUN6I) += clk-sun6i-apb0-gates.o
31obj-$(CONFIG_CLK_SUNXI_PRCM_SUN6I) += clk-sun6i-ar100.o
32
33obj-$(CONFIG_CLK_SUNXI_PRCM_SUN8I) += clk-sun8i-apb0.o
34obj-$(CONFIG_CLK_SUNXI_PRCM_SUN8I) += clk-sun6i-apb0-gates.o