Skip to content

Commit 440d7a6

Browse files
XBurstbebarino
authored andcommitted
clk: X1000: Add FIXDIV for SSI clock of X1000.
1.The SSI clock of X1000 not like JZ4770 and JZ4780, they are not directly derived from the output of SSIPLL, but from the clock obtained by dividing the frequency by 2. "X1000_CLK_SSIPLL_DIV2" is added for this purpose, and ensure that it initialized before "X1000_CLK_SSIMUX" when initializing the clocks. 2.Clocks of LCD, OTG, EMC, EFUSE, OST, TCU, and gates of CPU, PCLK are also added. 3.Use "CLK_OF_DECLARE_DRIVER" like the other CGU drivers. Signed-off-by: 周琰杰 (Zhou Yanjie) <[email protected]> Reviewed-by: Paul Cercueil <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 424c85e commit 440d7a6

File tree

1 file changed

+111
-6
lines changed

1 file changed

+111
-6
lines changed

drivers/clk/ingenic/x1000-cgu.c

Lines changed: 111 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/*
33
* X1000 SoC CGU driver
4-
* Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
4+
* Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
55
*/
66

77
#include <linux/clk-provider.h>
88
#include <linux/delay.h>
9+
#include <linux/io.h>
910
#include <linux/of.h>
1011

1112
#include <dt-bindings/clock/x1000-cgu.h>
@@ -20,6 +21,9 @@
2021
#define CGU_REG_CLKGR 0x20
2122
#define CGU_REG_OPCR 0x24
2223
#define CGU_REG_DDRCDR 0x2c
24+
#define CGU_REG_USBPCR 0x3c
25+
#define CGU_REG_USBPCR1 0x48
26+
#define CGU_REG_USBCDR 0x50
2327
#define CGU_REG_MACCDR 0x54
2428
#define CGU_REG_I2SCDR 0x60
2529
#define CGU_REG_LPCDR 0x64
@@ -40,8 +44,47 @@
4044
#define OPCR_SPENDN0 BIT(7)
4145
#define OPCR_SPENDN1 BIT(6)
4246

47+
/* bits within the USBPCR register */
48+
#define USBPCR_SIDDQ BIT(21)
49+
#define USBPCR_OTG_DISABLE BIT(20)
50+
4351
static struct ingenic_cgu *cgu;
4452

53+
static int x1000_usb_phy_enable(struct clk_hw *hw)
54+
{
55+
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
56+
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
57+
58+
writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
59+
writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
60+
return 0;
61+
}
62+
63+
static void x1000_usb_phy_disable(struct clk_hw *hw)
64+
{
65+
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
66+
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
67+
68+
writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
69+
writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
70+
}
71+
72+
static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
73+
{
74+
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
75+
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
76+
77+
return (readl(reg_opcr) & OPCR_SPENDN0) &&
78+
!(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
79+
!(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
80+
}
81+
82+
static const struct clk_ops x1000_otg_phy_ops = {
83+
.enable = x1000_usb_phy_enable,
84+
.disable = x1000_usb_phy_disable,
85+
.is_enabled = x1000_usb_phy_is_enabled,
86+
};
87+
4588
static const s8 pll_od_encoding[8] = {
4689
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
4790
};
@@ -101,6 +144,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
101144
},
102145
},
103146

147+
148+
/* Custom (SoC-specific) OTG PHY */
149+
150+
[X1000_CLK_OTGPHY] = {
151+
"otg_phy", CGU_CLK_CUSTOM,
152+
.parents = { -1, -1, X1000_CLK_EXCLK, -1 },
153+
.custom = { &x1000_otg_phy_ops },
154+
},
155+
104156
/* Muxes & dividers */
105157

106158
[X1000_CLK_SCLKA] = {
@@ -116,9 +168,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
116168
},
117169

118170
[X1000_CLK_CPU] = {
119-
"cpu", CGU_CLK_DIV,
171+
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
120172
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
121173
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
174+
.gate = { CGU_REG_CLKGR, 30 },
122175
},
123176

124177
[X1000_CLK_L2CACHE] = {
@@ -147,9 +200,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
147200
},
148201

149202
[X1000_CLK_PCLK] = {
150-
"pclk", CGU_CLK_DIV,
203+
"pclk", CGU_CLK_DIV | CGU_CLK_GATE,
151204
.parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 },
152205
.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
206+
.gate = { CGU_REG_CLKGR, 28 },
153207
},
154208

155209
[X1000_CLK_DDR] = {
@@ -162,12 +216,20 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
162216

163217
[X1000_CLK_MAC] = {
164218
"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
165-
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
219+
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
166220
.mux = { CGU_REG_MACCDR, 31, 1 },
167221
.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
168222
.gate = { CGU_REG_CLKGR, 25 },
169223
},
170224

225+
[X1000_CLK_LCD] = {
226+
"lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
227+
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
228+
.mux = { CGU_REG_LPCDR, 31, 1 },
229+
.div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
230+
.gate = { CGU_REG_CLKGR, 23 },
231+
},
232+
171233
[X1000_CLK_MSCMUX] = {
172234
"msc_mux", CGU_CLK_MUX,
173235
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
@@ -188,21 +250,48 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
188250
.gate = { CGU_REG_CLKGR, 5 },
189251
},
190252

253+
[X1000_CLK_OTG] = {
254+
"otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
255+
.parents = { X1000_CLK_EXCLK, -1,
256+
X1000_CLK_APLL, X1000_CLK_MPLL },
257+
.mux = { CGU_REG_USBCDR, 30, 2 },
258+
.div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 },
259+
.gate = { CGU_REG_CLKGR, 3 },
260+
},
261+
191262
[X1000_CLK_SSIPLL] = {
192263
"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
193264
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 },
194265
.mux = { CGU_REG_SSICDR, 31, 1 },
195266
.div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
196267
},
197268

269+
[X1000_CLK_SSIPLL_DIV2] = {
270+
"ssi_pll_div2", CGU_CLK_FIXDIV,
271+
.parents = { X1000_CLK_SSIPLL },
272+
.fixdiv = { 2 },
273+
},
274+
198275
[X1000_CLK_SSIMUX] = {
199276
"ssi_mux", CGU_CLK_MUX,
200-
.parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 },
277+
.parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 },
201278
.mux = { CGU_REG_SSICDR, 30, 1 },
202279
},
203280

204281
/* Gate-only clocks */
205282

283+
[X1000_CLK_EMC] = {
284+
"emc", CGU_CLK_GATE,
285+
.parents = { X1000_CLK_AHB2, -1, -1, -1 },
286+
.gate = { CGU_REG_CLKGR, 0 },
287+
},
288+
289+
[X1000_CLK_EFUSE] = {
290+
"efuse", CGU_CLK_GATE,
291+
.parents = { X1000_CLK_AHB2, -1, -1, -1 },
292+
.gate = { CGU_REG_CLKGR, 1 },
293+
},
294+
206295
[X1000_CLK_SFC] = {
207296
"sfc", CGU_CLK_GATE,
208297
.parents = { X1000_CLK_SSIPLL, -1, -1, -1 },
@@ -245,12 +334,24 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
245334
.gate = { CGU_REG_CLKGR, 16 },
246335
},
247336

337+
[X1000_CLK_TCU] = {
338+
"tcu", CGU_CLK_GATE,
339+
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
340+
.gate = { CGU_REG_CLKGR, 18 },
341+
},
342+
248343
[X1000_CLK_SSI] = {
249344
"ssi", CGU_CLK_GATE,
250345
.parents = { X1000_CLK_SSIMUX, -1, -1, -1 },
251346
.gate = { CGU_REG_CLKGR, 19 },
252347
},
253348

349+
[X1000_CLK_OST] = {
350+
"ost", CGU_CLK_GATE,
351+
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
352+
.gate = { CGU_REG_CLKGR, 20 },
353+
},
354+
254355
[X1000_CLK_PDMA] = {
255356
"pdma", CGU_CLK_GATE,
256357
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
@@ -277,4 +378,8 @@ static void __init x1000_cgu_init(struct device_node *np)
277378

278379
ingenic_cgu_register_syscore_ops(cgu);
279380
}
280-
CLK_OF_DECLARE(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
381+
/*
382+
* CGU has some children devices, this is useful for probing children devices
383+
* in the case where the device node is compatible with "simple-mfd".
384+
*/
385+
CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);

0 commit comments

Comments
 (0)