aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhiwu Song <Zhiwu.Song@csr.com>2015-05-20 04:50:33 -0400
committerStephen Boyd <sboyd@codeaurora.org>2015-05-20 18:43:28 -0400
commit301c5d29402e590ea893fe7ddc83a00a71994cba (patch)
tree886bfeeb8ef9452ac1f04fa87bb641a7879a7f58
parent95f589814c8af85fa673320bf319ffe8d721dd74 (diff)
clk: sirf: add CSR atlas7 clk and reset support
the hardware node includes both clock and reset support, so it is named as "car". this patch implements Flexible clocks(mux, divider, gate), Selectable clock(mux, divider, gate), root clock(gate),leaf clock(gate), others. it also implements the reset controller functionality. Signed-off-by: Zhiwu Song <Zhiwu.Song@csr.com> Signed-off-by: Guo Zeng <Guo.Zeng@csr.com> Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/clock/csr,atlas7-car.txt55
-rw-r--r--drivers/clk/sirf/Makefile2
-rw-r--r--drivers/clk/sirf/clk-atlas7.c1632
3 files changed, 1688 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/clock/csr,atlas7-car.txt b/Documentation/devicetree/bindings/clock/csr,atlas7-car.txt
new file mode 100644
index 000000000000..54d6d1358339
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/csr,atlas7-car.txt
@@ -0,0 +1,55 @@
1* Clock and reset bindings for CSR atlas7
2
3Required properties:
4- compatible: Should be "sirf,atlas7-car"
5- reg: Address and length of the register set
6- #clock-cells: Should be <1>
7- #reset-cells: Should be <1>
8
9The clock consumer should specify the desired clock by having the clock
10ID in its "clocks" phandle cell.
11The ID list atlas7_clks defined in drivers/clk/sirf/clk-atlas7.c
12
13The reset consumer should specify the desired reset by having the reset
14ID in its "reset" phandle cell.
15The ID list atlas7_reset_unit defined in drivers/clk/sirf/clk-atlas7.c
16
17Examples: Clock and reset controller node:
18
19car: clock-controller@18620000 {
20 compatible = "sirf,atlas7-car";
21 reg = <0x18620000 0x1000>;
22 #clock-cells = <1>;
23 #reset-cells = <1>;
24};
25
26Examples: Consumers using clock or reset:
27
28timer@10dc0000 {
29 compatible = "sirf,macro-tick";
30 reg = <0x10dc0000 0x1000>;
31 clocks = <&car 54>;
32 interrupts = <0 0 0>,
33 <0 1 0>,
34 <0 2 0>,
35 <0 49 0>,
36 <0 50 0>,
37 <0 51 0>;
38};
39
40uart1: uart@18020000 {
41 cell-index = <1>;
42 compatible = "sirf,macro-uart";
43 reg = <0x18020000 0x1000>;
44 clocks = <&clks 95>;
45 interrupts = <0 18 0>;
46 fifosize = <32>;
47};
48
49vpp@13110000 {
50 compatible = "sirf,prima2-vpp";
51 reg = <0x13110000 0x10000>;
52 interrupts = <0 31 0>;
53 clocks = <&car 85>;
54 resets = <&car 29>;
55};
diff --git a/drivers/clk/sirf/Makefile b/drivers/clk/sirf/Makefile
index 36b8e203f6e7..09b4210d9124 100644
--- a/drivers/clk/sirf/Makefile
+++ b/drivers/clk/sirf/Makefile
@@ -2,4 +2,4 @@
2# Makefile for sirf specific clk 2# Makefile for sirf specific clk
3# 3#
4 4
5obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o 5obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o clk-atlas7.o
diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
new file mode 100644
index 000000000000..db8ab691dbf6
--- /dev/null
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -0,0 +1,1632 @@
1/*
2 * Clock tree for CSR SiRFAtlas7
3 *
4 * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/bitops.h>
10#include <linux/io.h>
11#include <linux/clk-provider.h>
12#include <linux/delay.h>
13#include <linux/of_address.h>
14#include <linux/reset-controller.h>
15#include <linux/slab.h>
16
17#define SIRFSOC_CLKC_MEMPLL_AB_FREQ 0x0000
18#define SIRFSOC_CLKC_MEMPLL_AB_SSC 0x0004
19#define SIRFSOC_CLKC_MEMPLL_AB_CTRL0 0x0008
20#define SIRFSOC_CLKC_MEMPLL_AB_CTRL1 0x000c
21#define SIRFSOC_CLKC_MEMPLL_AB_STATUS 0x0010
22#define SIRFSOC_CLKC_MEMPLL_AB_SSRAM_ADDR 0x0014
23#define SIRFSOC_CLKC_MEMPLL_AB_SSRAM_DATA 0x0018
24
25#define SIRFSOC_CLKC_CPUPLL_AB_FREQ 0x001c
26#define SIRFSOC_CLKC_CPUPLL_AB_SSC 0x0020
27#define SIRFSOC_CLKC_CPUPLL_AB_CTRL0 0x0024
28#define SIRFSOC_CLKC_CPUPLL_AB_CTRL1 0x0028
29#define SIRFSOC_CLKC_CPUPLL_AB_STATUS 0x002c
30
31#define SIRFSOC_CLKC_SYS0PLL_AB_FREQ 0x0030
32#define SIRFSOC_CLKC_SYS0PLL_AB_SSC 0x0034
33#define SIRFSOC_CLKC_SYS0PLL_AB_CTRL0 0x0038
34#define SIRFSOC_CLKC_SYS0PLL_AB_CTRL1 0x003c
35#define SIRFSOC_CLKC_SYS0PLL_AB_STATUS 0x0040
36
37#define SIRFSOC_CLKC_SYS1PLL_AB_FREQ 0x0044
38#define SIRFSOC_CLKC_SYS1PLL_AB_SSC 0x0048
39#define SIRFSOC_CLKC_SYS1PLL_AB_CTRL0 0x004c
40#define SIRFSOC_CLKC_SYS1PLL_AB_CTRL1 0x0050
41#define SIRFSOC_CLKC_SYS1PLL_AB_STATUS 0x0054
42
43#define SIRFSOC_CLKC_SYS2PLL_AB_FREQ 0x0058
44#define SIRFSOC_CLKC_SYS2PLL_AB_SSC 0x005c
45#define SIRFSOC_CLKC_SYS2PLL_AB_CTRL0 0x0060
46#define SIRFSOC_CLKC_SYS2PLL_AB_CTRL1 0x0064
47#define SIRFSOC_CLKC_SYS2PLL_AB_STATUS 0x0068
48
49#define SIRFSOC_CLKC_SYS3PLL_AB_FREQ 0x006c
50#define SIRFSOC_CLKC_SYS3PLL_AB_SSC 0x0070
51#define SIRFSOC_CLKC_SYS3PLL_AB_CTRL0 0x0074
52#define SIRFSOC_CLKC_SYS3PLL_AB_CTRL1 0x0078
53#define SIRFSOC_CLKC_SYS3PLL_AB_STATUS 0x007c
54
55#define SIRFSOC_ABPLL_CTRL0_SSEN 0x00001000
56#define SIRFSOC_ABPLL_CTRL0_BYPASS 0x00000010
57#define SIRFSOC_ABPLL_CTRL0_RESET 0x00000001
58
59#define SIRFSOC_CLKC_AUDIO_DTO_INC 0x0088
60#define SIRFSOC_CLKC_DISP0_DTO_INC 0x008c
61#define SIRFSOC_CLKC_DISP1_DTO_INC 0x0090
62
63#define SIRFSOC_CLKC_AUDIO_DTO_SRC 0x0094
64#define SIRFSOC_CLKC_AUDIO_DTO_ENA 0x0098
65#define SIRFSOC_CLKC_AUDIO_DTO_DROFF 0x009c
66
67#define SIRFSOC_CLKC_DISP0_DTO_SRC 0x00a0
68#define SIRFSOC_CLKC_DISP0_DTO_ENA 0x00a4
69#define SIRFSOC_CLKC_DISP0_DTO_DROFF 0x00a8
70
71#define SIRFSOC_CLKC_DISP1_DTO_SRC 0x00ac
72#define SIRFSOC_CLKC_DISP1_DTO_ENA 0x00b0
73#define SIRFSOC_CLKC_DISP1_DTO_DROFF 0x00b4
74
75#define SIRFSOC_CLKC_I2S_CLK_SEL 0x00b8
76#define SIRFSOC_CLKC_I2S_SEL_STAT 0x00bc
77
78#define SIRFSOC_CLKC_USBPHY_CLKDIV_CFG 0x00c0
79#define SIRFSOC_CLKC_USBPHY_CLKDIV_ENA 0x00c4
80#define SIRFSOC_CLKC_USBPHY_CLK_SEL 0x00c8
81#define SIRFSOC_CLKC_USBPHY_CLK_SEL_STAT 0x00cc
82
83#define SIRFSOC_CLKC_BTSS_CLKDIV_CFG 0x00d0
84#define SIRFSOC_CLKC_BTSS_CLKDIV_ENA 0x00d4
85#define SIRFSOC_CLKC_BTSS_CLK_SEL 0x00d8
86#define SIRFSOC_CLKC_BTSS_CLK_SEL_STAT 0x00dc
87
88#define SIRFSOC_CLKC_RGMII_CLKDIV_CFG 0x00e0
89#define SIRFSOC_CLKC_RGMII_CLKDIV_ENA 0x00e4
90#define SIRFSOC_CLKC_RGMII_CLK_SEL 0x00e8
91#define SIRFSOC_CLKC_RGMII_CLK_SEL_STAT 0x00ec
92
93#define SIRFSOC_CLKC_CPU_CLKDIV_CFG 0x00f0
94#define SIRFSOC_CLKC_CPU_CLKDIV_ENA 0x00f4
95#define SIRFSOC_CLKC_CPU_CLK_SEL 0x00f8
96#define SIRFSOC_CLKC_CPU_CLK_SEL_STAT 0x00fc
97
98#define SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG 0x0100
99#define SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA 0x0104
100#define SIRFSOC_CLKC_SDPHY01_CLK_SEL 0x0108
101#define SIRFSOC_CLKC_SDPHY01_CLK_SEL_STAT 0x010c
102
103#define SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG 0x0110
104#define SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA 0x0114
105#define SIRFSOC_CLKC_SDPHY23_CLK_SEL 0x0118
106#define SIRFSOC_CLKC_SDPHY23_CLK_SEL_STAT 0x011c
107
108#define SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG 0x0120
109#define SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA 0x0124
110#define SIRFSOC_CLKC_SDPHY45_CLK_SEL 0x0128
111#define SIRFSOC_CLKC_SDPHY45_CLK_SEL_STAT 0x012c
112
113#define SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG 0x0130
114#define SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA 0x0134
115#define SIRFSOC_CLKC_SDPHY67_CLK_SEL 0x0138
116#define SIRFSOC_CLKC_SDPHY67_CLK_SEL_STAT 0x013c
117
118#define SIRFSOC_CLKC_CAN_CLKDIV_CFG 0x0140
119#define SIRFSOC_CLKC_CAN_CLKDIV_ENA 0x0144
120#define SIRFSOC_CLKC_CAN_CLK_SEL 0x0148
121#define SIRFSOC_CLKC_CAN_CLK_SEL_STAT 0x014c
122
123#define SIRFSOC_CLKC_DEINT_CLKDIV_CFG 0x0150
124#define SIRFSOC_CLKC_DEINT_CLKDIV_ENA 0x0154
125#define SIRFSOC_CLKC_DEINT_CLK_SEL 0x0158
126#define SIRFSOC_CLKC_DEINT_CLK_SEL_STAT 0x015c
127
128#define SIRFSOC_CLKC_NAND_CLKDIV_CFG 0x0160
129#define SIRFSOC_CLKC_NAND_CLKDIV_ENA 0x0164
130#define SIRFSOC_CLKC_NAND_CLK_SEL 0x0168
131#define SIRFSOC_CLKC_NAND_CLK_SEL_STAT 0x016c
132
133#define SIRFSOC_CLKC_DISP0_CLKDIV_CFG 0x0170
134#define SIRFSOC_CLKC_DISP0_CLKDIV_ENA 0x0174
135#define SIRFSOC_CLKC_DISP0_CLK_SEL 0x0178
136#define SIRFSOC_CLKC_DISP0_CLK_SEL_STAT 0x017c
137
138#define SIRFSOC_CLKC_DISP1_CLKDIV_CFG 0x0180
139#define SIRFSOC_CLKC_DISP1_CLKDIV_ENA 0x0184
140#define SIRFSOC_CLKC_DISP1_CLK_SEL 0x0188
141#define SIRFSOC_CLKC_DISP1_CLK_SEL_STAT 0x018c
142
143#define SIRFSOC_CLKC_GPU_CLKDIV_CFG 0x0190
144#define SIRFSOC_CLKC_GPU_CLKDIV_ENA 0x0194
145#define SIRFSOC_CLKC_GPU_CLK_SEL 0x0198
146#define SIRFSOC_CLKC_GPU_CLK_SEL_STAT 0x019c
147
148#define SIRFSOC_CLKC_GNSS_CLKDIV_CFG 0x01a0
149#define SIRFSOC_CLKC_GNSS_CLKDIV_ENA 0x01a4
150#define SIRFSOC_CLKC_GNSS_CLK_SEL 0x01a8
151#define SIRFSOC_CLKC_GNSS_CLK_SEL_STAT 0x01ac
152
153#define SIRFSOC_CLKC_SHARED_DIVIDER_CFG0 0x01b0
154#define SIRFSOC_CLKC_SHARED_DIVIDER_CFG1 0x01b4
155#define SIRFSOC_CLKC_SHARED_DIVIDER_ENA 0x01b8
156
157#define SIRFSOC_CLKC_SYS_CLK_SEL 0x01bc
158#define SIRFSOC_CLKC_SYS_CLK_SEL_STAT 0x01c0
159#define SIRFSOC_CLKC_IO_CLK_SEL 0x01c4
160#define SIRFSOC_CLKC_IO_CLK_SEL_STAT 0x01c8
161#define SIRFSOC_CLKC_G2D_CLK_SEL 0x01cc
162#define SIRFSOC_CLKC_G2D_CLK_SEL_STAT 0x01d0
163#define SIRFSOC_CLKC_JPENC_CLK_SEL 0x01d4
164#define SIRFSOC_CLKC_JPENC_CLK_SEL_STAT 0x01d8
165#define SIRFSOC_CLKC_VDEC_CLK_SEL 0x01dc
166#define SIRFSOC_CLKC_VDEC_CLK_SEL_STAT 0x01e0
167#define SIRFSOC_CLKC_GMAC_CLK_SEL 0x01e4
168#define SIRFSOC_CLKC_GMAC_CLK_SEL_STAT 0x01e8
169#define SIRFSOC_CLKC_USB_CLK_SEL 0x01ec
170#define SIRFSOC_CLKC_USB_CLK_SEL_STAT 0x01f0
171#define SIRFSOC_CLKC_KAS_CLK_SEL 0x01f4
172#define SIRFSOC_CLKC_KAS_CLK_SEL_STAT 0x01f8
173#define SIRFSOC_CLKC_SEC_CLK_SEL 0x01fc
174#define SIRFSOC_CLKC_SEC_CLK_SEL_STAT 0x0200
175#define SIRFSOC_CLKC_SDR_CLK_SEL 0x0204
176#define SIRFSOC_CLKC_SDR_CLK_SEL_STAT 0x0208
177#define SIRFSOC_CLKC_VIP_CLK_SEL 0x020c
178#define SIRFSOC_CLKC_VIP_CLK_SEL_STAT 0x0210
179#define SIRFSOC_CLKC_NOCD_CLK_SEL 0x0214
180#define SIRFSOC_CLKC_NOCD_CLK_SEL_STAT 0x0218
181#define SIRFSOC_CLKC_NOCR_CLK_SEL 0x021c
182#define SIRFSOC_CLKC_NOCR_CLK_SEL_STAT 0x0220
183#define SIRFSOC_CLKC_TPIU_CLK_SEL 0x0224
184#define SIRFSOC_CLKC_TPIU_CLK_SEL_STAT 0x0228
185
186#define SIRFSOC_CLKC_ROOT_CLK_EN0_SET 0x022c
187#define SIRFSOC_CLKC_ROOT_CLK_EN0_CLR 0x0230
188#define SIRFSOC_CLKC_ROOT_CLK_EN0_STAT 0x0234
189#define SIRFSOC_CLKC_ROOT_CLK_EN1_SET 0x0238
190#define SIRFSOC_CLKC_ROOT_CLK_EN1_CLR 0x023c
191#define SIRFSOC_CLKC_ROOT_CLK_EN1_STAT 0x0240
192
193#define SIRFSOC_CLKC_LEAF_CLK_EN0_SET 0x0244
194#define SIRFSOC_CLKC_LEAF_CLK_EN0_CLR 0x0248
195#define SIRFSOC_CLKC_LEAF_CLK_EN0_STAT 0x024c
196
197#define SIRFSOC_CLKC_RSTC_A7_SW_RST 0x0308
198
199#define SIRFSOC_CLKC_LEAF_CLK_EN1_SET 0x04a0
200#define SIRFSOC_CLKC_LEAF_CLK_EN2_SET 0x04b8
201#define SIRFSOC_CLKC_LEAF_CLK_EN3_SET 0x04d0
202#define SIRFSOC_CLKC_LEAF_CLK_EN4_SET 0x04e8
203#define SIRFSOC_CLKC_LEAF_CLK_EN5_SET 0x0500
204#define SIRFSOC_CLKC_LEAF_CLK_EN6_SET 0x0518
205#define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530
206#define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548
207
208
209static void __iomem *sirfsoc_clk_vbase;
210static struct clk_onecell_data clk_data;
211
212static const struct clk_div_table pll_div_table[] = {
213 { .val = 0, .div = 1 },
214 { .val = 1, .div = 2 },
215 { .val = 2, .div = 4 },
216 { .val = 3, .div = 8 },
217 { .val = 4, .div = 16 },
218 { .val = 5, .div = 32 },
219};
220
221struct clk_pll {
222 struct clk_hw hw;
223 u16 regofs; /* register offset */
224};
225#define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
226
227struct clk_dto {
228 struct clk_hw hw;
229 u16 inc_offset; /* dto increment offset */
230 u16 src_offset; /* dto src offset */
231};
232#define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw)
233
234struct clk_unit {
235 struct clk_hw hw;
236 u16 regofs;
237 u16 bit;
238 spinlock_t *lock;
239};
240#define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw)
241
242struct atlas7_div_init_data {
243 const char *div_name;
244 const char *parent_name;
245 const char *gate_name;
246 unsigned long flags;
247 u8 divider_flags;
248 u8 gate_flags;
249 u32 div_offset;
250 u8 shift;
251 u8 width;
252 u32 gate_offset;
253 u8 gate_bit;
254 spinlock_t *lock;
255};
256
257struct atlas7_mux_init_data {
258 const char *mux_name;
259 const char * const *parent_names;
260 u8 parent_num;
261 unsigned long flags;
262 u8 mux_flags;
263 u32 mux_offset;
264 u8 shift;
265 u8 width;
266};
267
268struct atlas7_unit_init_data {
269 u32 index;
270 const char *unit_name;
271 const char *parent_name;
272 unsigned long flags;
273 u32 regofs;
274 u8 bit;
275 spinlock_t *lock;
276};
277
278struct atlas7_reset_desc {
279 const char *name;
280 u32 clk_ofs;
281 u8 clk_bit;
282 u32 rst_ofs;
283 u8 rst_bit;
284 spinlock_t *lock;
285};
286
287static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
288static DEFINE_SPINLOCK(mempll_ctrl1_lock);
289static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
290static DEFINE_SPINLOCK(sys1pll_ctrl1_lock);
291static DEFINE_SPINLOCK(sys2pll_ctrl1_lock);
292static DEFINE_SPINLOCK(sys3pll_ctrl1_lock);
293static DEFINE_SPINLOCK(usbphy_div_lock);
294static DEFINE_SPINLOCK(btss_div_lock);
295static DEFINE_SPINLOCK(rgmii_div_lock);
296static DEFINE_SPINLOCK(cpu_div_lock);
297static DEFINE_SPINLOCK(sdphy01_div_lock);
298static DEFINE_SPINLOCK(sdphy23_div_lock);
299static DEFINE_SPINLOCK(sdphy45_div_lock);
300static DEFINE_SPINLOCK(sdphy67_div_lock);
301static DEFINE_SPINLOCK(can_div_lock);
302static DEFINE_SPINLOCK(deint_div_lock);
303static DEFINE_SPINLOCK(nand_div_lock);
304static DEFINE_SPINLOCK(disp0_div_lock);
305static DEFINE_SPINLOCK(disp1_div_lock);
306static DEFINE_SPINLOCK(gpu_div_lock);
307static DEFINE_SPINLOCK(gnss_div_lock);
308/* gate register shared */
309static DEFINE_SPINLOCK(share_div_lock);
310static DEFINE_SPINLOCK(root0_gate_lock);
311static DEFINE_SPINLOCK(root1_gate_lock);
312static DEFINE_SPINLOCK(leaf0_gate_lock);
313static DEFINE_SPINLOCK(leaf1_gate_lock);
314static DEFINE_SPINLOCK(leaf2_gate_lock);
315static DEFINE_SPINLOCK(leaf3_gate_lock);
316static DEFINE_SPINLOCK(leaf4_gate_lock);
317static DEFINE_SPINLOCK(leaf5_gate_lock);
318static DEFINE_SPINLOCK(leaf6_gate_lock);
319static DEFINE_SPINLOCK(leaf7_gate_lock);
320static DEFINE_SPINLOCK(leaf8_gate_lock);
321
322static inline unsigned long clkc_readl(unsigned reg)
323{
324 return readl(sirfsoc_clk_vbase + reg);
325}
326
327static inline void clkc_writel(u32 val, unsigned reg)
328{
329 writel(val, sirfsoc_clk_vbase + reg);
330}
331
332/*
333* ABPLL
334* integer mode: Fvco = Fin * 2 * NF / NR
335* Spread Spectrum mode: Fvco = Fin * SSN / NR
336* SSN = 2^24 / (256 * ((ssdiv >> ssdepth) << ssdepth) + (ssmod << ssdepth))
337*/
338static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
339 unsigned long parent_rate)
340{
341 unsigned long fin = parent_rate;
342 struct clk_pll *clk = to_pllclk(hw);
343 u64 rate;
344 u32 regctrl0 = clkc_readl(clk->regofs + SIRFSOC_CLKC_MEMPLL_AB_CTRL0 -
345 SIRFSOC_CLKC_MEMPLL_AB_FREQ);
346 u32 regfreq = clkc_readl(clk->regofs);
347 u32 regssc = clkc_readl(clk->regofs + SIRFSOC_CLKC_MEMPLL_AB_SSC -
348 SIRFSOC_CLKC_MEMPLL_AB_FREQ);
349 u32 nr = (regfreq >> 16 & (BIT(3) - 1)) + 1;
350 u32 nf = (regfreq & (BIT(9) - 1)) + 1;
351 u32 ssdiv = regssc >> 8 & (BIT(12) - 1);
352 u32 ssdepth = regssc >> 20 & (BIT(2) - 1);
353 u32 ssmod = regssc & (BIT(8) - 1);
354
355 if (regctrl0 & SIRFSOC_ABPLL_CTRL0_BYPASS)
356 return fin;
357
358 if (regctrl0 & SIRFSOC_ABPLL_CTRL0_SSEN) {
359 rate = fin;
360 rate *= 1 << 24;
361 do_div(rate, (256 * ((ssdiv >> ssdepth) << ssdepth)
362 + (ssmod << ssdepth)));
363 } else {
364 rate = 2 * fin;
365 rate *= nf;
366 do_div(rate, nr);
367 }
368 return rate;
369}
370
371static const struct clk_ops ab_pll_ops = {
372 .recalc_rate = pll_clk_recalc_rate,
373};
374
375static const char * const pll_clk_parents[] = {
376 "xin",
377};
378
379static struct clk_init_data clk_cpupll_init = {
380 .name = "cpupll_vco",
381 .ops = &ab_pll_ops,
382 .parent_names = pll_clk_parents,
383 .num_parents = ARRAY_SIZE(pll_clk_parents),
384};
385
386static struct clk_pll clk_cpupll = {
387 .regofs = SIRFSOC_CLKC_CPUPLL_AB_FREQ,
388 .hw = {
389 .init = &clk_cpupll_init,
390 },
391};
392
393static struct clk_init_data clk_mempll_init = {
394 .name = "mempll_vco",
395 .ops = &ab_pll_ops,
396 .parent_names = pll_clk_parents,
397 .num_parents = ARRAY_SIZE(pll_clk_parents),
398};
399
400static struct clk_pll clk_mempll = {
401 .regofs = SIRFSOC_CLKC_MEMPLL_AB_FREQ,
402 .hw = {
403 .init = &clk_mempll_init,
404 },
405};
406
407static struct clk_init_data clk_sys0pll_init = {
408 .name = "sys0pll_vco",
409 .ops = &ab_pll_ops,
410 .parent_names = pll_clk_parents,
411 .num_parents = ARRAY_SIZE(pll_clk_parents),
412};
413
414static struct clk_pll clk_sys0pll = {
415 .regofs = SIRFSOC_CLKC_SYS0PLL_AB_FREQ,
416 .hw = {
417 .init = &clk_sys0pll_init,
418 },
419};
420
421static struct clk_init_data clk_sys1pll_init = {
422 .name = "sys1pll_vco",
423 .ops = &ab_pll_ops,
424 .parent_names = pll_clk_parents,
425 .num_parents = ARRAY_SIZE(pll_clk_parents),
426};
427
428static struct clk_pll clk_sys1pll = {
429 .regofs = SIRFSOC_CLKC_SYS1PLL_AB_FREQ,
430 .hw = {
431 .init = &clk_sys1pll_init,
432 },
433};
434
435static struct clk_init_data clk_sys2pll_init = {
436 .name = "sys2pll_vco",
437 .ops = &ab_pll_ops,
438 .parent_names = pll_clk_parents,
439 .num_parents = ARRAY_SIZE(pll_clk_parents),
440};
441
442static struct clk_pll clk_sys2pll = {
443 .regofs = SIRFSOC_CLKC_SYS2PLL_AB_FREQ,
444 .hw = {
445 .init = &clk_sys2pll_init,
446 },
447};
448
449static struct clk_init_data clk_sys3pll_init = {
450 .name = "sys3pll_vco",
451 .ops = &ab_pll_ops,
452 .parent_names = pll_clk_parents,
453 .num_parents = ARRAY_SIZE(pll_clk_parents),
454};
455
456static struct clk_pll clk_sys3pll = {
457 .regofs = SIRFSOC_CLKC_SYS3PLL_AB_FREQ,
458 .hw = {
459 .init = &clk_sys3pll_init,
460 },
461};
462
463/*
464 * DTO in clkc, default enable double resolution mode
465 * double resolution mode:fout = fin * finc / 2^29
466 * normal mode:fout = fin * finc / 2^28
467 */
468static int dto_clk_is_enabled(struct clk_hw *hw)
469{
470 struct clk_dto *clk = to_dtoclk(hw);
471 int reg;
472
473 reg = clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_ENA - SIRFSOC_CLKC_AUDIO_DTO_SRC;
474
475 return !!(clkc_readl(reg) & BIT(0));
476}
477
478static int dto_clk_enable(struct clk_hw *hw)
479{
480 u32 val, reg;
481 struct clk_dto *clk = to_dtoclk(hw);
482
483 reg = clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_ENA - SIRFSOC_CLKC_AUDIO_DTO_SRC;
484
485 val = clkc_readl(reg) | BIT(0);
486 clkc_writel(val, reg);
487 return 0;
488}
489
490static void dto_clk_disable(struct clk_hw *hw)
491{
492 u32 val, reg;
493 struct clk_dto *clk = to_dtoclk(hw);
494
495 reg = clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_ENA - SIRFSOC_CLKC_AUDIO_DTO_SRC;
496
497 val = clkc_readl(reg) & ~BIT(0);
498 clkc_writel(val, reg);
499}
500
501static unsigned long dto_clk_recalc_rate(struct clk_hw *hw,
502 unsigned long parent_rate)
503{
504 u64 rate = parent_rate;
505 struct clk_dto *clk = to_dtoclk(hw);
506 u32 finc = clkc_readl(clk->inc_offset);
507 u32 droff = clkc_readl(clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_DROFF - SIRFSOC_CLKC_AUDIO_DTO_SRC);
508
509 rate *= finc;
510 if (droff & BIT(0))
511 /* Double resolution off */
512 do_div(rate, 1 << 28);
513 else
514 do_div(rate, 1 << 29);
515
516 return rate;
517}
518
519static long dto_clk_round_rate(struct clk_hw *hw, unsigned long rate,
520 unsigned long *parent_rate)
521{
522 u64 dividend = rate * (1 << 29);
523
524 do_div(dividend, *parent_rate);
525 dividend *= *parent_rate;
526 do_div(dividend, 1 << 29);
527
528 return dividend;
529}
530
531static int dto_clk_set_rate(struct clk_hw *hw, unsigned long rate,
532 unsigned long parent_rate)
533{
534 u64 dividend = rate * (1 << 29);
535 struct clk_dto *clk = to_dtoclk(hw);
536
537 do_div(dividend, parent_rate);
538 clkc_writel(0, clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_DROFF - SIRFSOC_CLKC_AUDIO_DTO_SRC);
539 clkc_writel(dividend, clk->inc_offset);
540
541 return 0;
542}
543
544static u8 dto_clk_get_parent(struct clk_hw *hw)
545{
546 struct clk_dto *clk = to_dtoclk(hw);
547
548 return clkc_readl(clk->src_offset);
549}
550
551/*
552 * dto need CLK_SET_PARENT_GATE
553 */
554static int dto_clk_set_parent(struct clk_hw *hw, u8 index)
555{
556 struct clk_dto *clk = to_dtoclk(hw);
557
558 clkc_writel(index, clk->src_offset);
559 return 0;
560}
561
562static const struct clk_ops dto_ops = {
563 .is_enabled = dto_clk_is_enabled,
564 .enable = dto_clk_enable,
565 .disable = dto_clk_disable,
566 .recalc_rate = dto_clk_recalc_rate,
567 .round_rate = dto_clk_round_rate,
568 .set_rate = dto_clk_set_rate,
569 .get_parent = dto_clk_get_parent,
570 .set_parent = dto_clk_set_parent,
571};
572
573/* dto parent clock as syspllvco/clk1 */
574static const char * const audiodto_clk_parents[] = {
575 "sys0pll_clk1",
576 "sys1pll_clk1",
577 "sys3pll_clk1",
578};
579
580static struct clk_init_data clk_audiodto_init = {
581 .name = "audio_dto",
582 .ops = &dto_ops,
583 .parent_names = audiodto_clk_parents,
584 .num_parents = ARRAY_SIZE(audiodto_clk_parents),
585};
586
587static struct clk_dto clk_audio_dto = {
588 .inc_offset = SIRFSOC_CLKC_AUDIO_DTO_INC,
589 .src_offset = SIRFSOC_CLKC_AUDIO_DTO_SRC,
590 .hw = {
591 .init = &clk_audiodto_init,
592 },
593};
594
595static const char * const disp0dto_clk_parents[] = {
596 "sys0pll_clk1",
597 "sys1pll_clk1",
598 "sys3pll_clk1",
599};
600
601static struct clk_init_data clk_disp0dto_init = {
602 .name = "disp0_dto",
603 .ops = &dto_ops,
604 .parent_names = disp0dto_clk_parents,
605 .num_parents = ARRAY_SIZE(disp0dto_clk_parents),
606};
607
608static struct clk_dto clk_disp0_dto = {
609 .inc_offset = SIRFSOC_CLKC_DISP0_DTO_INC,
610 .src_offset = SIRFSOC_CLKC_DISP0_DTO_SRC,
611 .hw = {
612 .init = &clk_disp0dto_init,
613 },
614};
615
616static const char * const disp1dto_clk_parents[] = {
617 "sys0pll_clk1",
618 "sys1pll_clk1",
619 "sys3pll_clk1",
620};
621
622static struct clk_init_data clk_disp1dto_init = {
623 .name = "disp1_dto",
624 .ops = &dto_ops,
625 .parent_names = disp1dto_clk_parents,
626 .num_parents = ARRAY_SIZE(disp1dto_clk_parents),
627};
628
629static struct clk_dto clk_disp1_dto = {
630 .inc_offset = SIRFSOC_CLKC_DISP1_DTO_INC,
631 .src_offset = SIRFSOC_CLKC_DISP1_DTO_SRC,
632 .hw = {
633 .init = &clk_disp1dto_init,
634 },
635};
636
637static struct atlas7_div_init_data divider_list[] __initdata = {
638 /* div_name, parent_name, gate_name, clk_flag, divider_flag, gate_flag, div_offset, shift, wdith, gate_offset, bit_enable, lock */
639 { "sys0pll_qa1", "sys0pll_fixdiv", "sys0pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 0, &usbphy_div_lock },
640 { "sys1pll_qa1", "sys1pll_fixdiv", "sys1pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 4, &usbphy_div_lock },
641 { "sys2pll_qa1", "sys2pll_fixdiv", "sys2pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 8, &usbphy_div_lock },
642 { "sys3pll_qa1", "sys3pll_fixdiv", "sys3pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 12, &usbphy_div_lock },
643 { "sys0pll_qa2", "sys0pll_fixdiv", "sys0pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 0, &btss_div_lock },
644 { "sys1pll_qa2", "sys1pll_fixdiv", "sys1pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 4, &btss_div_lock },
645 { "sys2pll_qa2", "sys2pll_fixdiv", "sys2pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 8, &btss_div_lock },
646 { "sys3pll_qa2", "sys3pll_fixdiv", "sys3pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 12, &btss_div_lock },
647 { "sys0pll_qa3", "sys0pll_fixdiv", "sys0pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 0, &rgmii_div_lock },
648 { "sys1pll_qa3", "sys1pll_fixdiv", "sys1pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 4, &rgmii_div_lock },
649 { "sys2pll_qa3", "sys2pll_fixdiv", "sys2pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 8, &rgmii_div_lock },
650 { "sys3pll_qa3", "sys3pll_fixdiv", "sys3pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 12, &rgmii_div_lock },
651 { "sys0pll_qa4", "sys0pll_fixdiv", "sys0pll_a4", 0, 0, 0, SIRFSOC_CLKC_CPU_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_CPU_CLKDIV_ENA, 0, &cpu_div_lock },
652 { "sys1pll_qa4", "sys1pll_fixdiv", "sys1pll_a4", 0, 0, CLK_IGNORE_UNUSED, SIRFSOC_CLKC_CPU_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_CPU_CLKDIV_ENA, 4, &cpu_div_lock },
653 { "sys0pll_qa5", "sys0pll_fixdiv", "sys0pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 0, &sdphy01_div_lock },
654 { "sys1pll_qa5", "sys1pll_fixdiv", "sys1pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 4, &sdphy01_div_lock },
655 { "sys2pll_qa5", "sys2pll_fixdiv", "sys2pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 8, &sdphy01_div_lock },
656 { "sys3pll_qa5", "sys3pll_fixdiv", "sys3pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 12, &sdphy01_div_lock },
657 { "sys0pll_qa6", "sys0pll_fixdiv", "sys0pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 0, &sdphy23_div_lock },
658 { "sys1pll_qa6", "sys1pll_fixdiv", "sys1pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 4, &sdphy23_div_lock },
659 { "sys2pll_qa6", "sys2pll_fixdiv", "sys2pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 8, &sdphy23_div_lock },
660 { "sys3pll_qa6", "sys3pll_fixdiv", "sys3pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 12, &sdphy23_div_lock },
661 { "sys0pll_qa7", "sys0pll_fixdiv", "sys0pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 0, &sdphy45_div_lock },
662 { "sys1pll_qa7", "sys1pll_fixdiv", "sys1pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 4, &sdphy45_div_lock },
663 { "sys2pll_qa7", "sys2pll_fixdiv", "sys2pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 8, &sdphy45_div_lock },
664 { "sys3pll_qa7", "sys3pll_fixdiv", "sys3pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 12, &sdphy45_div_lock },
665 { "sys0pll_qa8", "sys0pll_fixdiv", "sys0pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 0, &sdphy67_div_lock },
666 { "sys1pll_qa8", "sys1pll_fixdiv", "sys1pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 4, &sdphy67_div_lock },
667 { "sys2pll_qa8", "sys2pll_fixdiv", "sys2pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 8, &sdphy67_div_lock },
668 { "sys3pll_qa8", "sys3pll_fixdiv", "sys3pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 12, &sdphy67_div_lock },
669 { "sys0pll_qa9", "sys0pll_fixdiv", "sys0pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 0, &can_div_lock },
670 { "sys1pll_qa9", "sys1pll_fixdiv", "sys1pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 4, &can_div_lock },
671 { "sys2pll_qa9", "sys2pll_fixdiv", "sys2pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 8, &can_div_lock },
672 { "sys3pll_qa9", "sys3pll_fixdiv", "sys3pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 12, &can_div_lock },
673 { "sys0pll_qa10", "sys0pll_fixdiv", "sys0pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 0, &deint_div_lock },
674 { "sys1pll_qa10", "sys1pll_fixdiv", "sys1pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 4, &deint_div_lock },
675 { "sys2pll_qa10", "sys2pll_fixdiv", "sys2pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 8, &deint_div_lock },
676 { "sys3pll_qa10", "sys3pll_fixdiv", "sys3pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 12, &deint_div_lock },
677 { "sys0pll_qa11", "sys0pll_fixdiv", "sys0pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 0, &nand_div_lock },
678 { "sys1pll_qa11", "sys1pll_fixdiv", "sys1pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 4, &nand_div_lock },
679 { "sys2pll_qa11", "sys2pll_fixdiv", "sys2pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 8, &nand_div_lock },
680 { "sys3pll_qa11", "sys3pll_fixdiv", "sys3pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 12, &nand_div_lock },
681 { "sys0pll_qa12", "sys0pll_fixdiv", "sys0pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 0, &disp0_div_lock },
682 { "sys1pll_qa12", "sys1pll_fixdiv", "sys1pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 4, &disp0_div_lock },
683 { "sys2pll_qa12", "sys2pll_fixdiv", "sys2pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 8, &disp0_div_lock },
684 { "sys3pll_qa12", "sys3pll_fixdiv", "sys3pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 12, &disp0_div_lock },
685 { "sys0pll_qa13", "sys0pll_fixdiv", "sys0pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 0, &disp1_div_lock },
686 { "sys1pll_qa13", "sys1pll_fixdiv", "sys1pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 4, &disp1_div_lock },
687 { "sys2pll_qa13", "sys2pll_fixdiv", "sys2pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 8, &disp1_div_lock },
688 { "sys3pll_qa13", "sys3pll_fixdiv", "sys3pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 12, &disp1_div_lock },
689 { "sys0pll_qa14", "sys0pll_fixdiv", "sys0pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 0, &gpu_div_lock },
690 { "sys1pll_qa14", "sys1pll_fixdiv", "sys1pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 4, &gpu_div_lock },
691 { "sys2pll_qa14", "sys2pll_fixdiv", "sys2pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 8, &gpu_div_lock },
692 { "sys3pll_qa14", "sys3pll_fixdiv", "sys3pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 12, &gpu_div_lock },
693 { "sys0pll_qa15", "sys0pll_fixdiv", "sys0pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 0, &gnss_div_lock },
694 { "sys1pll_qa15", "sys1pll_fixdiv", "sys1pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 4, &gnss_div_lock },
695 { "sys2pll_qa15", "sys2pll_fixdiv", "sys2pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 8, &gnss_div_lock },
696 { "sys3pll_qa15", "sys3pll_fixdiv", "sys3pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 12, &gnss_div_lock },
697 { "sys1pll_qa18", "sys1pll_fixdiv", "sys1pll_a18", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 24, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 12, &share_div_lock },
698 { "sys1pll_qa19", "sys1pll_fixdiv", "sys1pll_a19", 0, 0, CLK_IGNORE_UNUSED, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 16, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 8, &share_div_lock },
699 { "sys1pll_qa20", "sys1pll_fixdiv", "sys1pll_a20", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 8, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 4, &share_div_lock },
700 { "sys2pll_qa20", "sys2pll_fixdiv", "sys2pll_a20", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 0, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 0, &share_div_lock },
701 { "sys1pll_qa17", "sys1pll_fixdiv", "sys1pll_a17", 0, 0, CLK_IGNORE_UNUSED, SIRFSOC_CLKC_SHARED_DIVIDER_CFG1, 8, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 20, &share_div_lock },
702 { "sys0pll_qa20", "sys0pll_fixdiv", "sys0pll_a20", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG1, 0, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 16, &share_div_lock },
703};
704
705static const char * const i2s_clk_parents[] = {
706 "xin",
707 "xinw",
708 "audio_dto",
709 /* "pwm_i2s01" */
710};
711
712static const char * const usbphy_clk_parents[] = {
713 "xin",
714 "xinw",
715 "sys0pll_a1",
716 "sys1pll_a1",
717 "sys2pll_a1",
718 "sys3pll_a1",
719};
720
721static const char * const btss_clk_parents[] = {
722 "xin",
723 "xinw",
724 "sys0pll_a2",
725 "sys1pll_a2",
726 "sys2pll_a2",
727 "sys3pll_a2",
728};
729
730static const char * const rgmii_clk_parents[] = {
731 "xin",
732 "xinw",
733 "sys0pll_a3",
734 "sys1pll_a3",
735 "sys2pll_a3",
736 "sys3pll_a3",
737};
738
739static const char * const cpu_clk_parents[] = {
740 "xin",
741 "xinw",
742 "sys0pll_a4",
743 "sys1pll_a4",
744 "cpupll_clk1",
745};
746
747static const char * const sdphy01_clk_parents[] = {
748 "xin",
749 "xinw",
750 "sys0pll_a5",
751 "sys1pll_a5",
752 "sys2pll_a5",
753 "sys3pll_a5",
754};
755
756static const char * const sdphy23_clk_parents[] = {
757 "xin",
758 "xinw",
759 "sys0pll_a6",
760 "sys1pll_a6",
761 "sys2pll_a6",
762 "sys3pll_a6",
763};
764
765static const char * const sdphy45_clk_parents[] = {
766 "xin",
767 "xinw",
768 "sys0pll_a7",
769 "sys1pll_a7",
770 "sys2pll_a7",
771 "sys3pll_a7",
772};
773
774static const char * const sdphy67_clk_parents[] = {
775 "xin",
776 "xinw",
777 "sys0pll_a8",
778 "sys1pll_a8",
779 "sys2pll_a8",
780 "sys3pll_a8",
781};
782
783static const char * const can_clk_parents[] = {
784 "xin",
785 "xinw",
786 "sys0pll_a9",
787 "sys1pll_a9",
788 "sys2pll_a9",
789 "sys3pll_a9",
790};
791
792static const char * const deint_clk_parents[] = {
793 "xin",
794 "xinw",
795 "sys0pll_a10",
796 "sys1pll_a10",
797 "sys2pll_a10",
798 "sys3pll_a10",
799};
800
801static const char * const nand_clk_parents[] = {
802 "xin",
803 "xinw",
804 "sys0pll_a11",
805 "sys1pll_a11",
806 "sys2pll_a11",
807 "sys3pll_a11",
808};
809
810static const char * const disp0_clk_parents[] = {
811 "xin",
812 "xinw",
813 "sys0pll_a12",
814 "sys1pll_a12",
815 "sys2pll_a12",
816 "sys3pll_a12",
817 "disp0_dto",
818};
819
820static const char * const disp1_clk_parents[] = {
821 "xin",
822 "xinw",
823 "sys0pll_a13",
824 "sys1pll_a13",
825 "sys2pll_a13",
826 "sys3pll_a13",
827 "disp1_dto",
828};
829
830static const char * const gpu_clk_parents[] = {
831 "xin",
832 "xinw",
833 "sys0pll_a14",
834 "sys1pll_a14",
835 "sys2pll_a14",
836 "sys3pll_a14",
837};
838
839static const char * const gnss_clk_parents[] = {
840 "xin",
841 "xinw",
842 "sys0pll_a15",
843 "sys1pll_a15",
844 "sys2pll_a15",
845 "sys3pll_a15",
846};
847
848static const char * const sys_clk_parents[] = {
849 "xin",
850 "xinw",
851 "sys2pll_a20",
852 "sys1pll_a20",
853 "sys1pll_a19",
854 "sys1pll_a18",
855 "sys0pll_a20",
856 "sys1pll_a17",
857};
858
859static const char * const io_clk_parents[] = {
860 "xin",
861 "xinw",
862 "sys2pll_a20",
863 "sys1pll_a20",
864 "sys1pll_a19",
865 "sys1pll_a18",
866 "sys0pll_a20",
867 "sys1pll_a17",
868};
869
870static const char * const g2d_clk_parents[] = {
871 "xin",
872 "xinw",
873 "sys2pll_a20",
874 "sys1pll_a20",
875 "sys1pll_a19",
876 "sys1pll_a18",
877 "sys0pll_a20",
878 "sys1pll_a17",
879};
880
881static const char * const jpenc_clk_parents[] = {
882 "xin",
883 "xinw",
884 "sys2pll_a20",
885 "sys1pll_a20",
886 "sys1pll_a19",
887 "sys1pll_a18",
888 "sys0pll_a20",
889 "sys1pll_a17",
890};
891
892static const char * const vdec_clk_parents[] = {
893 "xin",
894 "xinw",
895 "sys2pll_a20",
896 "sys1pll_a20",
897 "sys1pll_a19",
898 "sys1pll_a18",
899 "sys0pll_a20",
900 "sys1pll_a17",
901};
902
903static const char * const gmac_clk_parents[] = {
904 "xin",
905 "xinw",
906 "sys2pll_a20",
907 "sys1pll_a20",
908 "sys1pll_a19",
909 "sys1pll_a18",
910 "sys0pll_a20",
911 "sys1pll_a17",
912};
913
914static const char * const usb_clk_parents[] = {
915 "xin",
916 "xinw",
917 "sys2pll_a20",
918 "sys1pll_a20",
919 "sys1pll_a19",
920 "sys1pll_a18",
921 "sys0pll_a20",
922 "sys1pll_a17",
923};
924
925static const char * const kas_clk_parents[] = {
926 "xin",
927 "xinw",
928 "sys2pll_a20",
929 "sys1pll_a20",
930 "sys1pll_a19",
931 "sys1pll_a18",
932 "sys0pll_a20",
933 "sys1pll_a17",
934};
935
936static const char * const sec_clk_parents[] = {
937 "xin",
938 "xinw",
939 "sys2pll_a20",
940 "sys1pll_a20",
941 "sys1pll_a19",
942 "sys1pll_a18",
943 "sys0pll_a20",
944 "sys1pll_a17",
945};
946
947static const char * const sdr_clk_parents[] = {
948 "xin",
949 "xinw",
950 "sys2pll_a20",
951 "sys1pll_a20",
952 "sys1pll_a19",
953 "sys1pll_a18",
954 "sys0pll_a20",
955 "sys1pll_a17",
956};
957
958static const char * const vip_clk_parents[] = {
959 "xin",
960 "xinw",
961 "sys2pll_a20",
962 "sys1pll_a20",
963 "sys1pll_a19",
964 "sys1pll_a18",
965 "sys0pll_a20",
966 "sys1pll_a17",
967};
968
969static const char * const nocd_clk_parents[] = {
970 "xin",
971 "xinw",
972 "sys2pll_a20",
973 "sys1pll_a20",
974 "sys1pll_a19",
975 "sys1pll_a18",
976 "sys0pll_a20",
977 "sys1pll_a17",
978};
979
980static const char * const nocr_clk_parents[] = {
981 "xin",
982 "xinw",
983 "sys2pll_a20",
984 "sys1pll_a20",
985 "sys1pll_a19",
986 "sys1pll_a18",
987 "sys0pll_a20",
988 "sys1pll_a17",
989};
990
991static const char * const tpiu_clk_parents[] = {
992 "xin",
993 "xinw",
994 "sys2pll_a20",
995 "sys1pll_a20",
996 "sys1pll_a19",
997 "sys1pll_a18",
998 "sys0pll_a20",
999 "sys1pll_a17",
1000};
1001
1002static struct atlas7_mux_init_data mux_list[] __initdata = {
1003 /* mux_name, parent_names, parent_num, flags, mux_flags, mux_offset, shift, width */
1004 { "i2s_mux", i2s_clk_parents, ARRAY_SIZE(i2s_clk_parents), 0, 0, SIRFSOC_CLKC_I2S_CLK_SEL, 0, 2 },
1005 { "usbphy_mux", usbphy_clk_parents, ARRAY_SIZE(usbphy_clk_parents), 0, 0, SIRFSOC_CLKC_I2S_CLK_SEL, 0, 3 },
1006 { "btss_mux", btss_clk_parents, ARRAY_SIZE(btss_clk_parents), 0, 0, SIRFSOC_CLKC_BTSS_CLK_SEL, 0, 3 },
1007 { "rgmii_mux", rgmii_clk_parents, ARRAY_SIZE(rgmii_clk_parents), 0, 0, SIRFSOC_CLKC_RGMII_CLK_SEL, 0, 3 },
1008 { "cpu_mux", cpu_clk_parents, ARRAY_SIZE(cpu_clk_parents), 0, 0, SIRFSOC_CLKC_CPU_CLK_SEL, 0, 3 },
1009 { "sdphy01_mux", sdphy01_clk_parents, ARRAY_SIZE(sdphy01_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY01_CLK_SEL, 0, 3 },
1010 { "sdphy23_mux", sdphy23_clk_parents, ARRAY_SIZE(sdphy23_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY23_CLK_SEL, 0, 3 },
1011 { "sdphy45_mux", sdphy45_clk_parents, ARRAY_SIZE(sdphy45_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY45_CLK_SEL, 0, 3 },
1012 { "sdphy67_mux", sdphy67_clk_parents, ARRAY_SIZE(sdphy67_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY67_CLK_SEL, 0, 3 },
1013 { "can_mux", can_clk_parents, ARRAY_SIZE(can_clk_parents), 0, 0, SIRFSOC_CLKC_CAN_CLK_SEL, 0, 3 },
1014 { "deint_mux", deint_clk_parents, ARRAY_SIZE(deint_clk_parents), 0, 0, SIRFSOC_CLKC_DEINT_CLK_SEL, 0, 3 },
1015 { "nand_mux", nand_clk_parents, ARRAY_SIZE(nand_clk_parents), 0, 0, SIRFSOC_CLKC_NAND_CLK_SEL, 0, 3 },
1016 { "disp0_mux", disp0_clk_parents, ARRAY_SIZE(disp0_clk_parents), 0, 0, SIRFSOC_CLKC_DISP0_CLK_SEL, 0, 3 },
1017 { "disp1_mux", disp1_clk_parents, ARRAY_SIZE(disp1_clk_parents), 0, 0, SIRFSOC_CLKC_DISP1_CLK_SEL, 0, 3 },
1018 { "gpu_mux", gpu_clk_parents, ARRAY_SIZE(gpu_clk_parents), 0, 0, SIRFSOC_CLKC_GPU_CLK_SEL, 0, 3 },
1019 { "gnss_mux", gnss_clk_parents, ARRAY_SIZE(gnss_clk_parents), 0, 0, SIRFSOC_CLKC_GNSS_CLK_SEL, 0, 3 },
1020 { "sys_mux", sys_clk_parents, ARRAY_SIZE(sys_clk_parents), 0, 0, SIRFSOC_CLKC_SYS_CLK_SEL, 0, 3 },
1021 { "io_mux", io_clk_parents, ARRAY_SIZE(io_clk_parents), 0, 0, SIRFSOC_CLKC_IO_CLK_SEL, 0, 3 },
1022 { "g2d_mux", g2d_clk_parents, ARRAY_SIZE(g2d_clk_parents), 0, 0, SIRFSOC_CLKC_G2D_CLK_SEL, 0, 3 },
1023 { "jpenc_mux", jpenc_clk_parents, ARRAY_SIZE(jpenc_clk_parents), 0, 0, SIRFSOC_CLKC_JPENC_CLK_SEL, 0, 3 },
1024 { "vdec_mux", vdec_clk_parents, ARRAY_SIZE(vdec_clk_parents), 0, 0, SIRFSOC_CLKC_VDEC_CLK_SEL, 0, 3 },
1025 { "gmac_mux", gmac_clk_parents, ARRAY_SIZE(gmac_clk_parents), 0, 0, SIRFSOC_CLKC_GMAC_CLK_SEL, 0, 3 },
1026 { "usb_mux", usb_clk_parents, ARRAY_SIZE(usb_clk_parents), 0, 0, SIRFSOC_CLKC_USB_CLK_SEL, 0, 3 },
1027 { "kas_mux", kas_clk_parents, ARRAY_SIZE(kas_clk_parents), 0, 0, SIRFSOC_CLKC_KAS_CLK_SEL, 0, 3 },
1028 { "sec_mux", sec_clk_parents, ARRAY_SIZE(sec_clk_parents), 0, 0, SIRFSOC_CLKC_SEC_CLK_SEL, 0, 3 },
1029 { "sdr_mux", sdr_clk_parents, ARRAY_SIZE(sdr_clk_parents), 0, 0, SIRFSOC_CLKC_SDR_CLK_SEL, 0, 3 },
1030 { "vip_mux", vip_clk_parents, ARRAY_SIZE(vip_clk_parents), 0, 0, SIRFSOC_CLKC_VIP_CLK_SEL, 0, 3 },
1031 { "nocd_mux", nocd_clk_parents, ARRAY_SIZE(nocd_clk_parents), 0, 0, SIRFSOC_CLKC_NOCD_CLK_SEL, 0, 3 },
1032 { "nocr_mux", nocr_clk_parents, ARRAY_SIZE(nocr_clk_parents), 0, 0, SIRFSOC_CLKC_NOCR_CLK_SEL, 0, 3 },
1033 { "tpiu_mux", tpiu_clk_parents, ARRAY_SIZE(tpiu_clk_parents), 0, 0, SIRFSOC_CLKC_TPIU_CLK_SEL, 0, 3 },
1034};
1035
1036 /* new unit should add start from the tail of list */
1037static struct atlas7_unit_init_data unit_list[] __initdata = {
1038 /* unit_name, parent_name, flags, regofs, bit, lock */
1039 { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock },
1040 { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock },
1041 { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock },
1042 { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock },
1043 { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock },
1044 { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock },
1045 { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock },
1046 { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock },
1047 { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock },
1048 { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock },
1049 { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock },
1050 { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock },
1051 { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock },
1052 { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock },
1053 { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock },
1054 { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock },
1055 { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock },
1056 { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock },
1057 { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock },
1058 { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock },
1059 { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock },
1060 { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock },
1061 { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock },
1062 { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock },
1063 { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock },
1064 { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock },
1065 { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock },
1066 { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock },
1067 { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock },
1068 { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock },
1069 { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock },
1070 { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock },
1071 { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock },
1072 { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock },
1073 { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock },
1074 { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock },
1075 { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock },
1076 { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock },
1077 { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock },
1078 { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock },
1079 { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock },
1080 { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock },
1081 { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock },
1082 { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock },
1083 { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock },
1084 { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock },
1085 { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock },
1086 { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock },
1087 { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock },
1088 { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock },
1089 { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock },
1090 { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock },
1091 { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock },
1092 { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock },
1093 { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock },
1094 { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock },
1095 { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock },
1096 { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock },
1097 { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock },
1098 { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock },
1099 { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock },
1100 { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock },
1101 { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock },
1102 { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock },
1103 { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock },
1104 { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock },
1105 { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock },
1106 { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock },
1107 { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock },
1108 { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock },
1109 { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock },
1110 { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock },
1111 { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock },
1112 { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock },
1113 { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock },
1114 { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock },
1115 { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock },
1116 { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock },
1117 { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock },
1118 { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock },
1119 { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock },
1120 { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock },
1121 { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock },
1122 { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock },
1123 { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock },
1124 { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock },
1125 { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock },
1126 { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock },
1127 { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock },
1128 { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock },
1129 { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock },
1130 { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock },
1131 { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock },
1132 { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock },
1133 { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock },
1134 { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock },
1135 { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock },
1136 { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock },
1137 { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock },
1138 { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock },
1139 { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock },
1140 { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock },
1141 { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock },
1142 { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock },
1143 { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock },
1144 { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock },
1145 { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock },
1146 { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock },
1147 { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock },
1148 { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock },
1149 { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock },
1150 { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock },
1151 { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock },
1152 { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock },
1153 { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock },
1154 { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock },
1155 { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock },
1156 { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock },
1157 { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock },
1158 { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock },
1159 { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock },
1160 { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock },
1161 { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
1162 { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
1163 { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
1164 { 125, "thcpum_cpudiv4", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
1165 { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock },
1166 { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
1167 { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
1168 { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock },
1169 { 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
1170 { 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
1171 { 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
1172 { 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
1173 { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock },
1174 { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
1175 { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
1176 { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
1177};
1178
1179static struct clk *atlas7_clks[ARRAY_SIZE(unit_list)];
1180
1181static int unit_clk_is_enabled(struct clk_hw *hw)
1182{
1183 struct clk_unit *clk = to_unitclk(hw);
1184 u32 reg;
1185
1186 reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_STAT - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
1187
1188 return !!(clkc_readl(reg) & BIT(clk->bit));
1189}
1190
1191static int unit_clk_enable(struct clk_hw *hw)
1192{
1193 u32 reg;
1194 struct clk_unit *clk = to_unitclk(hw);
1195 unsigned long flags;
1196
1197 reg = clk->regofs;
1198
1199 spin_lock_irqsave(clk->lock, flags);
1200 clkc_writel(BIT(clk->bit), reg);
1201 spin_unlock_irqrestore(clk->lock, flags);
1202 return 0;
1203}
1204
1205static void unit_clk_disable(struct clk_hw *hw)
1206{
1207 u32 reg;
1208 struct clk_unit *clk = to_unitclk(hw);
1209 unsigned long flags;
1210
1211 reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
1212
1213 spin_lock_irqsave(clk->lock, flags);
1214 clkc_writel(BIT(clk->bit), reg);
1215 spin_unlock_irqrestore(clk->lock, flags);
1216}
1217
1218static const struct clk_ops unit_clk_ops = {
1219 .is_enabled = unit_clk_is_enabled,
1220 .enable = unit_clk_enable,
1221 .disable = unit_clk_disable,
1222};
1223
1224static struct clk * __init
1225atlas7_unit_clk_register(struct device *dev, const char *name,
1226 const char * const parent_name, unsigned long flags,
1227 u32 regofs, u8 bit, spinlock_t *lock)
1228{
1229 struct clk *clk;
1230 struct clk_unit *unit;
1231 struct clk_init_data init;
1232
1233 unit = kzalloc(sizeof(*unit), GFP_KERNEL);
1234 if (!unit)
1235 return ERR_PTR(-ENOMEM);
1236
1237 init.name = name;
1238 init.parent_names = &parent_name;
1239 init.num_parents = 1;
1240 init.ops = &unit_clk_ops;
1241 init.flags = flags;
1242
1243 unit->hw.init = &init;
1244 unit->regofs = regofs;
1245 unit->bit = bit;
1246 unit->lock = lock;
1247
1248 clk = clk_register(dev, &unit->hw);
1249 if (IS_ERR(clk))
1250 kfree(unit);
1251
1252 return clk;
1253}
1254
1255static struct atlas7_reset_desc atlas7_reset_unit[] = {
1256 { "PWM", 0x0244, 0, 0x0320, 0, &leaf0_gate_lock }, /* 0-5 */
1257 { "THCGUM", 0x0244, 3, 0x0320, 1, &leaf0_gate_lock },
1258 { "CVD", 0x04A0, 0, 0x032C, 0, &leaf1_gate_lock },
1259 { "TIMER", 0x04A0, 1, 0x032C, 1, &leaf1_gate_lock },
1260 { "PULSEC", 0x04A0, 2, 0x032C, 2, &leaf1_gate_lock },
1261 { "TSC", 0x04A0, 3, 0x032C, 3, &leaf1_gate_lock },
1262 { "IOCTOP", 0x04A0, 4, 0x032C, 4, &leaf1_gate_lock }, /* 6-10 */
1263 { "RSC", 0x04A0, 5, 0x032C, 5, &leaf1_gate_lock },
1264 { "DVM", 0x04A0, 6, 0x032C, 6, &leaf1_gate_lock },
1265 { "LVDS", 0x04A0, 7, 0x032C, 7, &leaf1_gate_lock },
1266 { "KAS", 0x04A0, 8, 0x032C, 8, &leaf1_gate_lock },
1267 { "AC97", 0x04A0, 9, 0x032C, 9, &leaf1_gate_lock }, /* 11-15 */
1268 { "USP0", 0x04A0, 10, 0x032C, 10, &leaf1_gate_lock },
1269 { "USP1", 0x04A0, 11, 0x032C, 11, &leaf1_gate_lock },
1270 { "USP2", 0x04A0, 12, 0x032C, 12, &leaf1_gate_lock },
1271 { "DMAC2", 0x04A0, 13, 0x032C, 13, &leaf1_gate_lock },
1272 { "DMAC3", 0x04A0, 14, 0x032C, 14, &leaf1_gate_lock }, /* 16-20 */
1273 { "AUDIO", 0x04A0, 15, 0x032C, 15, &leaf1_gate_lock },
1274 { "I2S1", 0x04A0, 17, 0x032C, 16, &leaf1_gate_lock },
1275 { "PMU_AUDIO", 0x04A0, 22, 0x032C, 17, &leaf1_gate_lock },
1276 { "THAUDMSCM", 0x04A0, 23, 0x032C, 18, &leaf1_gate_lock },
1277 { "SYS2PCI", 0x04B8, 0, 0x0338, 0, &leaf2_gate_lock }, /* 21-25 */
1278 { "PCIARB", 0x04B8, 1, 0x0338, 1, &leaf2_gate_lock },
1279 { "PCICOPY", 0x04B8, 2, 0x0338, 2, &leaf2_gate_lock },
1280 { "ROM", 0x04B8, 3, 0x0338, 3, &leaf2_gate_lock },
1281 { "SDIO23", 0x04B8, 4, 0x0338, 4, &leaf2_gate_lock },
1282 { "SDIO45", 0x04B8, 5, 0x0338, 5, &leaf2_gate_lock }, /* 26-30 */
1283 { "SDIO67", 0x04B8, 6, 0x0338, 6, &leaf2_gate_lock },
1284 { "VIP1", 0x04B8, 7, 0x0338, 7, &leaf2_gate_lock },
1285 { "VPP0", 0x04B8, 11, 0x0338, 8, &leaf2_gate_lock },
1286 { "LCD0", 0x04B8, 12, 0x0338, 9, &leaf2_gate_lock },
1287 { "VPP1", 0x04B8, 13, 0x0338, 10, &leaf2_gate_lock }, /* 31-35 */
1288 { "LCD1", 0x04B8, 14, 0x0338, 11, &leaf2_gate_lock },
1289 { "DCU", 0x04B8, 15, 0x0338, 12, &leaf2_gate_lock },
1290 { "GPIO", 0x04B8, 18, 0x0338, 13, &leaf2_gate_lock },
1291 { "DAPA_VDIFM", 0x04B8, 17, 0x0338, 15, &leaf2_gate_lock },
1292 { "THVDIFM", 0x04B8, 19, 0x0338, 16, &leaf2_gate_lock }, /* 36-40 */
1293 { "RGMII", 0x04D0, 0, 0x0344, 0, &leaf3_gate_lock },
1294 { "GMAC", 0x04D0, 1, 0x0344, 1, &leaf3_gate_lock },
1295 { "UART1", 0x04D0, 2, 0x0344, 2, &leaf3_gate_lock },
1296 { "DMAC0", 0x04D0, 3, 0x0344, 3, &leaf3_gate_lock },
1297 { "UART0", 0x04D0, 4, 0x0344, 4, &leaf3_gate_lock }, /* 41-45 */
1298 { "UART2", 0x04D0, 5, 0x0344, 5, &leaf3_gate_lock },
1299 { "UART3", 0x04D0, 6, 0x0344, 6, &leaf3_gate_lock },
1300 { "UART4", 0x04D0, 7, 0x0344, 7, &leaf3_gate_lock },
1301 { "UART5", 0x04D0, 8, 0x0344, 8, &leaf3_gate_lock },
1302 { "SPI1", 0x04D0, 9, 0x0344, 9, &leaf3_gate_lock }, /* 46-50 */
1303 { "GNSS_SYS_M0", 0x04D0, 10, 0x0344, 10, &leaf3_gate_lock },
1304 { "CANBUS1", 0x04D0, 12, 0x0344, 11, &leaf3_gate_lock },
1305 { "CCSEC", 0x04D0, 15, 0x0344, 12, &leaf3_gate_lock },
1306 { "CCPUB", 0x04D0, 16, 0x0344, 13, &leaf3_gate_lock },
1307 { "DAPA_GNSSM", 0x04D0, 13, 0x0344, 14, &leaf3_gate_lock }, /* 51-55 */
1308 { "THGNSSM", 0x04D0, 14, 0x0344, 15, &leaf3_gate_lock },
1309 { "VDEC", 0x04E8, 0, 0x0350, 0, &leaf4_gate_lock },
1310 { "JPENC", 0x04E8, 1, 0x0350, 1, &leaf4_gate_lock },
1311 { "G2D", 0x04E8, 2, 0x0350, 2, &leaf4_gate_lock },
1312 { "I2C0", 0x04E8, 3, 0x0350, 3, &leaf4_gate_lock }, /* 56-60 */
1313 { "I2C1", 0x04E8, 4, 0x0350, 4, &leaf4_gate_lock },
1314 { "GPIO0", 0x04E8, 5, 0x0350, 5, &leaf4_gate_lock },
1315 { "NAND", 0x04E8, 6, 0x0350, 6, &leaf4_gate_lock },
1316 { "SDIO01", 0x04E8, 7, 0x0350, 7, &leaf4_gate_lock },
1317 { "SYS2PCI2", 0x04E8, 8, 0x0350, 8, &leaf4_gate_lock }, /* 61-65 */
1318 { "USB0", 0x04E8, 11, 0x0350, 9, &leaf4_gate_lock },
1319 { "USB1", 0x04E8, 12, 0x0350, 10, &leaf4_gate_lock },
1320 { "THMEDIAM", 0x04E8, 15, 0x0350, 11, &leaf4_gate_lock },
1321 { "MEMC_DDRPHY", 0x0500, 0, 0x035C, 0, &leaf5_gate_lock },
1322 { "MEMC_UPCTL", 0x0500, 0, 0x035C, 1, &leaf5_gate_lock }, /* 66-70 */
1323 { "DAPA_MEM", 0x0500, 1, 0x035C, 2, &leaf5_gate_lock },
1324 { "MEMC_MEMDIV", 0x0500, 0, 0x035C, 3, &leaf5_gate_lock },
1325 { "THDDRM", 0x0500, 3, 0x035C, 4, &leaf5_gate_lock },
1326 { "CORESIGHT", 0x0518, 3, 0x0368, 13, &leaf6_gate_lock },
1327 { "THCPUM", 0x0518, 4, 0x0368, 17, &leaf6_gate_lock }, /* 71-75 */
1328 { "GRAPHIC", 0x0530, 0, 0x0374, 0, &leaf7_gate_lock },
1329 { "VSS_SDR", 0x0530, 1, 0x0374, 1, &leaf7_gate_lock },
1330 { "THGPUM", 0x0530, 2, 0x0374, 2, &leaf7_gate_lock },
1331 { "DMAC4", 0x0548, 2, 0x0380, 1, &leaf8_gate_lock },
1332 { "UART6", 0x0548, 3, 0x0380, 2, &leaf8_gate_lock }, /* 76- */
1333 { "USP3", 0x0548, 4, 0x0380, 3, &leaf8_gate_lock },
1334 { "THBTM", 0x0548, 5, 0x0380, 5, &leaf8_gate_lock },
1335 { "A7CA", 0x0548, 1, 0x0380, 0, &leaf8_gate_lock },
1336 { "A7CA_APB", 0x0548, 5, 0x0380, 4, &leaf8_gate_lock },
1337};
1338
1339static int atlas7_reset_module(struct reset_controller_dev *rcdev,
1340 unsigned long reset_idx)
1341{
1342 struct atlas7_reset_desc *reset = &atlas7_reset_unit[reset_idx];
1343 unsigned long flags;
1344
1345 /*
1346 * HW suggest unit reset sequence:
1347 * assert sw reset (0)
1348 * setting sw clk_en to if the clock was disabled before reset
1349 * delay 16 clocks
1350 * disable clock (sw clk_en = 0)
1351 * de-assert reset (1)
1352 * after this sequence, restore clock or not is decided by SW
1353 */
1354
1355 spin_lock_irqsave(reset->lock, flags);
1356 /* clock enable or not */
1357 if (clkc_readl(reset->clk_ofs + 8) & (1 << reset->clk_bit)) {
1358 clkc_writel(1 << reset->rst_bit, reset->rst_ofs + 4);
1359 udelay(2);
1360 clkc_writel(1 << reset->clk_bit, reset->clk_ofs + 4);
1361 clkc_writel(1 << reset->rst_bit, reset->rst_ofs);
1362 /* restore clock enable */
1363 clkc_writel(1 << reset->clk_bit, reset->clk_ofs);
1364 } else {
1365 clkc_writel(1 << reset->rst_bit, reset->rst_ofs + 4);
1366 clkc_writel(1 << reset->clk_bit, reset->clk_ofs);
1367 udelay(2);
1368 clkc_writel(1 << reset->clk_bit, reset->clk_ofs + 4);
1369 clkc_writel(1 << reset->rst_bit, reset->rst_ofs);
1370 }
1371 spin_unlock_irqrestore(reset->lock, flags);
1372
1373 return 0;
1374}
1375
1376static struct reset_control_ops atlas7_rst_ops = {
1377 .reset = atlas7_reset_module,
1378};
1379
1380static struct reset_controller_dev atlas7_rst_ctlr = {
1381 .ops = &atlas7_rst_ops,
1382 .owner = THIS_MODULE,
1383 .of_reset_n_cells = 1,
1384};
1385
1386static void __init atlas7_clk_init(struct device_node *np)
1387{
1388 struct clk *clk;
1389 struct atlas7_div_init_data *div;
1390 struct atlas7_mux_init_data *mux;
1391 struct atlas7_unit_init_data *unit;
1392 int i;
1393 int ret;
1394
1395 sirfsoc_clk_vbase = of_iomap(np, 0);
1396 if (!sirfsoc_clk_vbase)
1397 panic("unable to map clkc registers\n");
1398
1399 of_node_put(np);
1400
1401 clk = clk_register(NULL, &clk_cpupll.hw);
1402 BUG_ON(!clk);
1403 clk = clk_register(NULL, &clk_mempll.hw);
1404 BUG_ON(!clk);
1405 clk = clk_register(NULL, &clk_sys0pll.hw);
1406 BUG_ON(!clk);
1407 clk = clk_register(NULL, &clk_sys1pll.hw);
1408 BUG_ON(!clk);
1409 clk = clk_register(NULL, &clk_sys2pll.hw);
1410 BUG_ON(!clk);
1411 clk = clk_register(NULL, &clk_sys3pll.hw);
1412 BUG_ON(!clk);
1413
1414 clk = clk_register_divider_table(NULL, "cpupll_div1", "cpupll_vco", 0,
1415 sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1, 0, 3, 0,
1416 pll_div_table, &cpupll_ctrl1_lock);
1417 BUG_ON(!clk);
1418 clk = clk_register_divider_table(NULL, "cpupll_div2", "cpupll_vco", 0,
1419 sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1, 4, 3, 0,
1420 pll_div_table, &cpupll_ctrl1_lock);
1421 BUG_ON(!clk);
1422 clk = clk_register_divider_table(NULL, "cpupll_div3", "cpupll_vco", 0,
1423 sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1, 8, 3, 0,
1424 pll_div_table, &cpupll_ctrl1_lock);
1425 BUG_ON(!clk);
1426
1427 clk = clk_register_divider_table(NULL, "mempll_div1", "mempll_vco", 0,
1428 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1, 0, 3, 0,
1429 pll_div_table, &mempll_ctrl1_lock);
1430 BUG_ON(!clk);
1431 clk = clk_register_divider_table(NULL, "mempll_div2", "mempll_vco", 0,
1432 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1, 4, 3, 0,
1433 pll_div_table, &mempll_ctrl1_lock);
1434 BUG_ON(!clk);
1435 clk = clk_register_divider_table(NULL, "mempll_div3", "mempll_vco", 0,
1436 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1, 8, 3, 0,
1437 pll_div_table, &mempll_ctrl1_lock);
1438 BUG_ON(!clk);
1439
1440 clk = clk_register_divider_table(NULL, "sys0pll_div1", "sys0pll_vco", 0,
1441 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1, 0, 3, 0,
1442 pll_div_table, &sys0pll_ctrl1_lock);
1443 BUG_ON(!clk);
1444 clk = clk_register_divider_table(NULL, "sys0pll_div2", "sys0pll_vco", 0,
1445 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1, 4, 3, 0,
1446 pll_div_table, &sys0pll_ctrl1_lock);
1447 BUG_ON(!clk);
1448 clk = clk_register_divider_table(NULL, "sys0pll_div3", "sys0pll_vco", 0,
1449 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1, 8, 3, 0,
1450 pll_div_table, &sys0pll_ctrl1_lock);
1451 BUG_ON(!clk);
1452 clk = clk_register_fixed_factor(NULL, "sys0pll_fixdiv", "sys0pll_vco",
1453 CLK_SET_RATE_PARENT, 1, 2);
1454
1455 clk = clk_register_divider_table(NULL, "sys1pll_div1", "sys1pll_vco", 0,
1456 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1, 0, 3, 0,
1457 pll_div_table, &sys1pll_ctrl1_lock);
1458 BUG_ON(!clk);
1459 clk = clk_register_divider_table(NULL, "sys1pll_div2", "sys1pll_vco", 0,
1460 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1, 4, 3, 0,
1461 pll_div_table, &sys1pll_ctrl1_lock);
1462 BUG_ON(!clk);
1463 clk = clk_register_divider_table(NULL, "sys1pll_div3", "sys1pll_vco", 0,
1464 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1, 8, 3, 0,
1465 pll_div_table, &sys1pll_ctrl1_lock);
1466 BUG_ON(!clk);
1467 clk = clk_register_fixed_factor(NULL, "sys1pll_fixdiv", "sys1pll_vco",
1468 CLK_SET_RATE_PARENT, 1, 2);
1469
1470 clk = clk_register_divider_table(NULL, "sys2pll_div1", "sys2pll_vco", 0,
1471 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1, 0, 3, 0,
1472 pll_div_table, &sys2pll_ctrl1_lock);
1473 BUG_ON(!clk);
1474 clk = clk_register_divider_table(NULL, "sys2pll_div2", "sys2pll_vco", 0,
1475 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1, 4, 3, 0,
1476 pll_div_table, &sys2pll_ctrl1_lock);
1477 BUG_ON(!clk);
1478 clk = clk_register_divider_table(NULL, "sys2pll_div3", "sys2pll_vco", 0,
1479 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1, 8, 3, 0,
1480 pll_div_table, &sys2pll_ctrl1_lock);
1481 BUG_ON(!clk);
1482 clk = clk_register_fixed_factor(NULL, "sys2pll_fixdiv", "sys2pll_vco",
1483 CLK_SET_RATE_PARENT, 1, 2);
1484
1485 clk = clk_register_divider_table(NULL, "sys3pll_div1", "sys3pll_vco", 0,
1486 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1, 0, 3, 0,
1487 pll_div_table, &sys3pll_ctrl1_lock);
1488 BUG_ON(!clk);
1489 clk = clk_register_divider_table(NULL, "sys3pll_div2", "sys3pll_vco", 0,
1490 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1, 4, 3, 0,
1491 pll_div_table, &sys3pll_ctrl1_lock);
1492 BUG_ON(!clk);
1493 clk = clk_register_divider_table(NULL, "sys3pll_div3", "sys3pll_vco", 0,
1494 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1, 8, 3, 0,
1495 pll_div_table, &sys3pll_ctrl1_lock);
1496 BUG_ON(!clk);
1497 clk = clk_register_fixed_factor(NULL, "sys3pll_fixdiv", "sys3pll_vco",
1498 CLK_SET_RATE_PARENT, 1, 2);
1499
1500 BUG_ON(!clk);
1501 clk = clk_register_fixed_factor(NULL, "xinw_fixdiv_btslow", "xinw",
1502 CLK_SET_RATE_PARENT, 1, 4);
1503
1504 BUG_ON(!clk);
1505 clk = clk_register_gate(NULL, "cpupll_clk1", "cpupll_div1",
1506 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1,
1507 12, 0, &cpupll_ctrl1_lock);
1508 BUG_ON(!clk);
1509 clk = clk_register_gate(NULL, "cpupll_clk2", "cpupll_div2",
1510 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1,
1511 13, 0, &cpupll_ctrl1_lock);
1512 BUG_ON(!clk);
1513 clk = clk_register_gate(NULL, "cpupll_clk3", "cpupll_div3",
1514 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1,
1515 14, 0, &cpupll_ctrl1_lock);
1516 BUG_ON(!clk);
1517
1518 clk = clk_register_gate(NULL, "mempll_clk1", "mempll_div1",
1519 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1520 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1,
1521 12, 0, &mempll_ctrl1_lock);
1522 BUG_ON(!clk);
1523 clk = clk_register_gate(NULL, "mempll_clk2", "mempll_div2",
1524 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1,
1525 13, 0, &mempll_ctrl1_lock);
1526 BUG_ON(!clk);
1527 clk = clk_register_gate(NULL, "mempll_clk3", "mempll_div3",
1528 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1,
1529 14, 0, &mempll_ctrl1_lock);
1530 BUG_ON(!clk);
1531
1532 clk = clk_register_gate(NULL, "sys0pll_clk1", "sys0pll_div1",
1533 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1,
1534 12, 0, &sys0pll_ctrl1_lock);
1535 BUG_ON(!clk);
1536 clk = clk_register_gate(NULL, "sys0pll_clk2", "sys0pll_div2",
1537 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1,
1538 13, 0, &sys0pll_ctrl1_lock);
1539 BUG_ON(!clk);
1540 clk = clk_register_gate(NULL, "sys0pll_clk3", "sys0pll_div3",
1541 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1,
1542 14, 0, &sys0pll_ctrl1_lock);
1543 BUG_ON(!clk);
1544
1545 clk = clk_register_gate(NULL, "sys1pll_clk1", "sys1pll_div1",
1546 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1,
1547 12, 0, &sys1pll_ctrl1_lock);
1548 BUG_ON(!clk);
1549 clk = clk_register_gate(NULL, "sys1pll_clk2", "sys1pll_div2",
1550 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1,
1551 13, 0, &sys1pll_ctrl1_lock);
1552 BUG_ON(!clk);
1553 clk = clk_register_gate(NULL, "sys1pll_clk3", "sys1pll_div3",
1554 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1,
1555 14, 0, &sys1pll_ctrl1_lock);
1556 BUG_ON(!clk);
1557
1558 clk = clk_register_gate(NULL, "sys2pll_clk1", "sys2pll_div1",
1559 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1,
1560 12, 0, &sys2pll_ctrl1_lock);
1561 BUG_ON(!clk);
1562 clk = clk_register_gate(NULL, "sys2pll_clk2", "sys2pll_div2",
1563 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1,
1564 13, 0, &sys2pll_ctrl1_lock);
1565 BUG_ON(!clk);
1566 clk = clk_register_gate(NULL, "sys2pll_clk3", "sys2pll_div3",
1567 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1,
1568 14, 0, &sys2pll_ctrl1_lock);
1569 BUG_ON(!clk);
1570
1571 clk = clk_register_gate(NULL, "sys3pll_clk1", "sys3pll_div1",
1572 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1,
1573 12, 0, &sys3pll_ctrl1_lock);
1574 BUG_ON(!clk);
1575 clk = clk_register_gate(NULL, "sys3pll_clk2", "sys3pll_div2",
1576 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1,
1577 13, 0, &sys3pll_ctrl1_lock);
1578 BUG_ON(!clk);
1579 clk = clk_register_gate(NULL, "sys3pll_clk3", "sys3pll_div3",
1580 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1,
1581 14, 0, &sys3pll_ctrl1_lock);
1582 BUG_ON(!clk);
1583
1584 clk = clk_register(NULL, &clk_audio_dto.hw);
1585 BUG_ON(!clk);
1586
1587 clk = clk_register(NULL, &clk_disp0_dto.hw);
1588 BUG_ON(!clk);
1589
1590 clk = clk_register(NULL, &clk_disp1_dto.hw);
1591 BUG_ON(!clk);
1592
1593 for (i = 0; i < ARRAY_SIZE(divider_list); i++) {
1594 div = &divider_list[i];
1595 clk = clk_register_divider(NULL, div->div_name,
1596 div->parent_name, div->divider_flags, sirfsoc_clk_vbase + div->div_offset,
1597 div->shift, div->width, 0, div->lock);
1598 BUG_ON(!clk);
1599 clk = clk_register_gate(NULL, div->gate_name, div->div_name,
1600 div->gate_flags, sirfsoc_clk_vbase + div->gate_offset,
1601 div->gate_bit, 0, div->lock);
1602 BUG_ON(!clk);
1603 }
1604 /* ignore selector status register check */
1605 for (i = 0; i < ARRAY_SIZE(mux_list); i++) {
1606 mux = &mux_list[i];
1607 clk = clk_register_mux(NULL, mux->mux_name, mux->parent_names,
1608 mux->parent_num, mux->flags,
1609 sirfsoc_clk_vbase + mux->mux_offset,
1610 mux->shift, mux->width,
1611 mux->mux_flags, NULL);
1612 BUG_ON(!clk);
1613 }
1614
1615 for (i = 0; i < ARRAY_SIZE(unit_list); i++) {
1616 unit = &unit_list[i];
1617 atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name,
1618 unit->flags, unit->regofs, unit->bit, unit->lock);
1619 BUG_ON(!atlas7_clks[i]);
1620 }
1621
1622 clk_data.clks = atlas7_clks;
1623 clk_data.clk_num = ARRAY_SIZE(unit_list);
1624
1625 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1626 BUG_ON(ret);
1627
1628 atlas7_rst_ctlr.of_node = np;
1629 atlas7_rst_ctlr.nr_resets = ARRAY_SIZE(atlas7_reset_unit);
1630 reset_controller_register(&atlas7_rst_ctlr);
1631}
1632CLK_OF_DECLARE(atlas7_clk, "sirf,atlas7-car", atlas7_clk_init);