1
2
3
4
5
6
7
8#include <linux/clk.h>
9#include <linux/clkdev.h>
10#include <linux/err.h>
11#include <linux/io.h>
12#include <linux/clk-provider.h>
13#include <linux/spinlock.h>
14#include <linux/of.h>
15
16
17
18#define U300_SYSCON_CCR (0x0000)
19#define U300_SYSCON_CCR_I2S1_USE_VCXO (0x0040)
20#define U300_SYSCON_CCR_I2S0_USE_VCXO (0x0020)
21#define U300_SYSCON_CCR_TURN_VCXO_ON (0x0008)
22#define U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK (0x0007)
23#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER (0x04)
24#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW (0x03)
25#define U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE (0x02)
26#define U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH (0x01)
27#define U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST (0x00)
28
29#define U300_SYSCON_CSR (0x0004)
30#define U300_SYSCON_CSR_PLL208_LOCK_IND (0x0002)
31#define U300_SYSCON_CSR_PLL13_LOCK_IND (0x0001)
32
33#define U300_SYSCON_RSR (0x0014)
34#define U300_SYSCON_RSR_PPM_RESET_EN (0x0200)
35#define U300_SYSCON_RSR_ACC_TMR_RESET_EN (0x0100)
36#define U300_SYSCON_RSR_APP_TMR_RESET_EN (0x0080)
37#define U300_SYSCON_RSR_RTC_RESET_EN (0x0040)
38#define U300_SYSCON_RSR_KEYPAD_RESET_EN (0x0020)
39#define U300_SYSCON_RSR_GPIO_RESET_EN (0x0010)
40#define U300_SYSCON_RSR_EH_RESET_EN (0x0008)
41#define U300_SYSCON_RSR_BTR_RESET_EN (0x0004)
42#define U300_SYSCON_RSR_UART_RESET_EN (0x0002)
43#define U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN (0x0001)
44
45#define U300_SYSCON_RFR (0x0018)
46#define U300_SYSCON_RFR_UART1_RESET_ENABLE (0x0080)
47#define U300_SYSCON_RFR_SPI_RESET_ENABLE (0x0040)
48#define U300_SYSCON_RFR_MMC_RESET_ENABLE (0x0020)
49#define U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE (0x0010)
50#define U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE (0x0008)
51#define U300_SYSCON_RFR_I2C1_RESET_ENABLE (0x0004)
52#define U300_SYSCON_RFR_I2C0_RESET_ENABLE (0x0002)
53#define U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE (0x0001)
54
55#define U300_SYSCON_RRR (0x001c)
56#define U300_SYSCON_RRR_CDS_RESET_EN (0x4000)
57#define U300_SYSCON_RRR_ISP_RESET_EN (0x2000)
58#define U300_SYSCON_RRR_INTCON_RESET_EN (0x1000)
59#define U300_SYSCON_RRR_MSPRO_RESET_EN (0x0800)
60#define U300_SYSCON_RRR_XGAM_RESET_EN (0x0100)
61#define U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN (0x0080)
62#define U300_SYSCON_RRR_NANDIF_RESET_EN (0x0040)
63#define U300_SYSCON_RRR_EMIF_RESET_EN (0x0020)
64#define U300_SYSCON_RRR_DMAC_RESET_EN (0x0010)
65#define U300_SYSCON_RRR_CPU_RESET_EN (0x0008)
66#define U300_SYSCON_RRR_APEX_RESET_EN (0x0004)
67#define U300_SYSCON_RRR_AHB_RESET_EN (0x0002)
68#define U300_SYSCON_RRR_AAIF_RESET_EN (0x0001)
69
70#define U300_SYSCON_CESR (0x0020)
71#define U300_SYSCON_CESR_PPM_CLK_EN (0x0200)
72#define U300_SYSCON_CESR_ACC_TMR_CLK_EN (0x0100)
73#define U300_SYSCON_CESR_APP_TMR_CLK_EN (0x0080)
74#define U300_SYSCON_CESR_KEYPAD_CLK_EN (0x0040)
75#define U300_SYSCON_CESR_GPIO_CLK_EN (0x0010)
76#define U300_SYSCON_CESR_EH_CLK_EN (0x0008)
77#define U300_SYSCON_CESR_BTR_CLK_EN (0x0004)
78#define U300_SYSCON_CESR_UART_CLK_EN (0x0002)
79#define U300_SYSCON_CESR_SLOW_BRIDGE_CLK_EN (0x0001)
80
81#define U300_SYSCON_CEFR (0x0024)
82#define U300_SYSCON_CEFR_UART1_CLK_EN (0x0200)
83#define U300_SYSCON_CEFR_I2S1_CORE_CLK_EN (0x0100)
84#define U300_SYSCON_CEFR_I2S0_CORE_CLK_EN (0x0080)
85#define U300_SYSCON_CEFR_SPI_CLK_EN (0x0040)
86#define U300_SYSCON_CEFR_MMC_CLK_EN (0x0020)
87#define U300_SYSCON_CEFR_I2S1_CLK_EN (0x0010)
88#define U300_SYSCON_CEFR_I2S0_CLK_EN (0x0008)
89#define U300_SYSCON_CEFR_I2C1_CLK_EN (0x0004)
90#define U300_SYSCON_CEFR_I2C0_CLK_EN (0x0002)
91#define U300_SYSCON_CEFR_FAST_BRIDGE_CLK_EN (0x0001)
92
93#define U300_SYSCON_CERR (0x0028)
94#define U300_SYSCON_CERR_CDS_CLK_EN (0x2000)
95#define U300_SYSCON_CERR_ISP_CLK_EN (0x1000)
96#define U300_SYSCON_CERR_MSPRO_CLK_EN (0x0800)
97#define U300_SYSCON_CERR_AHB_SUBSYS_BRIDGE_CLK_EN (0x0400)
98#define U300_SYSCON_CERR_SEMI_CLK_EN (0x0200)
99#define U300_SYSCON_CERR_XGAM_CLK_EN (0x0100)
100#define U300_SYSCON_CERR_VIDEO_ENC_CLK_EN (0x0080)
101#define U300_SYSCON_CERR_NANDIF_CLK_EN (0x0040)
102#define U300_SYSCON_CERR_EMIF_CLK_EN (0x0020)
103#define U300_SYSCON_CERR_DMAC_CLK_EN (0x0010)
104#define U300_SYSCON_CERR_CPU_CLK_EN (0x0008)
105#define U300_SYSCON_CERR_APEX_CLK_EN (0x0004)
106#define U300_SYSCON_CERR_AHB_CLK_EN (0x0002)
107#define U300_SYSCON_CERR_AAIF_CLK_EN (0x0001)
108
109#define U300_SYSCON_SBCER (0x002c)
110#define U300_SYSCON_SBCER_PPM_CLK_EN (0x0009)
111#define U300_SYSCON_SBCER_ACC_TMR_CLK_EN (0x0008)
112#define U300_SYSCON_SBCER_APP_TMR_CLK_EN (0x0007)
113#define U300_SYSCON_SBCER_KEYPAD_CLK_EN (0x0006)
114#define U300_SYSCON_SBCER_GPIO_CLK_EN (0x0004)
115#define U300_SYSCON_SBCER_EH_CLK_EN (0x0003)
116#define U300_SYSCON_SBCER_BTR_CLK_EN (0x0002)
117#define U300_SYSCON_SBCER_UART_CLK_EN (0x0001)
118#define U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN (0x0000)
119#define U300_SYSCON_SBCER_UART1_CLK_EN (0x0019)
120#define U300_SYSCON_SBCER_I2S1_CORE_CLK_EN (0x0018)
121#define U300_SYSCON_SBCER_I2S0_CORE_CLK_EN (0x0017)
122#define U300_SYSCON_SBCER_SPI_CLK_EN (0x0016)
123#define U300_SYSCON_SBCER_MMC_CLK_EN (0x0015)
124#define U300_SYSCON_SBCER_I2S1_CLK_EN (0x0014)
125#define U300_SYSCON_SBCER_I2S0_CLK_EN (0x0013)
126#define U300_SYSCON_SBCER_I2C1_CLK_EN (0x0012)
127#define U300_SYSCON_SBCER_I2C0_CLK_EN (0x0011)
128#define U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN (0x0010)
129#define U300_SYSCON_SBCER_CDS_CLK_EN (0x002D)
130#define U300_SYSCON_SBCER_ISP_CLK_EN (0x002C)
131#define U300_SYSCON_SBCER_MSPRO_CLK_EN (0x002B)
132#define U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN (0x002A)
133#define U300_SYSCON_SBCER_SEMI_CLK_EN (0x0029)
134#define U300_SYSCON_SBCER_XGAM_CLK_EN (0x0028)
135#define U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN (0x0027)
136#define U300_SYSCON_SBCER_NANDIF_CLK_EN (0x0026)
137#define U300_SYSCON_SBCER_EMIF_CLK_EN (0x0025)
138#define U300_SYSCON_SBCER_DMAC_CLK_EN (0x0024)
139#define U300_SYSCON_SBCER_CPU_CLK_EN (0x0023)
140#define U300_SYSCON_SBCER_APEX_CLK_EN (0x0022)
141#define U300_SYSCON_SBCER_AHB_CLK_EN (0x0021)
142#define U300_SYSCON_SBCER_AAIF_CLK_EN (0x0020)
143
144#define U300_SYSCON_SBCDR (0x0030)
145
146
147#define U300_SYSCON_CFSR (0x003c)
148#define U300_SYSCON_CFSR_PPM_CLK_FORCE_EN (0x0200)
149#define U300_SYSCON_CFSR_ACC_TMR_CLK_FORCE_EN (0x0100)
150#define U300_SYSCON_CFSR_APP_TMR_CLK_FORCE_EN (0x0080)
151#define U300_SYSCON_CFSR_KEYPAD_CLK_FORCE_EN (0x0020)
152#define U300_SYSCON_CFSR_GPIO_CLK_FORCE_EN (0x0010)
153#define U300_SYSCON_CFSR_EH_CLK_FORCE_EN (0x0008)
154#define U300_SYSCON_CFSR_BTR_CLK_FORCE_EN (0x0004)
155#define U300_SYSCON_CFSR_UART_CLK_FORCE_EN (0x0002)
156#define U300_SYSCON_CFSR_SLOW_BRIDGE_CLK_FORCE_EN (0x0001)
157
158#define U300_SYSCON_CFFR (0x40)
159
160
161#define U300_SYSCON_CFRR (0x44)
162#define U300_SYSCON_CFRR_CDS_CLK_FORCE_EN (0x2000)
163#define U300_SYSCON_CFRR_ISP_CLK_FORCE_EN (0x1000)
164#define U300_SYSCON_CFRR_MSPRO_CLK_FORCE_EN (0x0800)
165#define U300_SYSCON_CFRR_AHB_SUBSYS_BRIDGE_CLK_FORCE_EN (0x0400)
166#define U300_SYSCON_CFRR_SEMI_CLK_FORCE_EN (0x0200)
167#define U300_SYSCON_CFRR_XGAM_CLK_FORCE_EN (0x0100)
168#define U300_SYSCON_CFRR_VIDEO_ENC_CLK_FORCE_EN (0x0080)
169#define U300_SYSCON_CFRR_NANDIF_CLK_FORCE_EN (0x0040)
170#define U300_SYSCON_CFRR_EMIF_CLK_FORCE_EN (0x0020)
171#define U300_SYSCON_CFRR_DMAC_CLK_FORCE_EN (0x0010)
172#define U300_SYSCON_CFRR_CPU_CLK_FORCE_EN (0x0008)
173#define U300_SYSCON_CFRR_APEX_CLK_FORCE_EN (0x0004)
174#define U300_SYSCON_CFRR_AHB_CLK_FORCE_EN (0x0002)
175#define U300_SYSCON_CFRR_AAIF_CLK_FORCE_EN (0x0001)
176
177#define U300_SYSCON_PFCR (0x48)
178#define U300_SYSCON_PFCR_DPLL_MULT_NUM (0x000F)
179
180#define U300_SYSCON_PMCR (0x50)
181#define U300_SYSCON_PMCR_DCON_ENABLE (0x0002)
182#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE (0x0001)
183
184#define U300_SYSCON_RCR (0x6c)
185#define U300_SYSCON_RCR_RESOUT0_RST_N_DISABLE (0x0001)
186
187#define U300_SYSCON_SRCLR (0x70)
188#define U300_SYSCON_SRCLR_MASK (0x03FF)
189#define U300_SYSCON_SRCLR_VALUE (0x03FF)
190#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_B (0x0200)
191#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_A (0x0100)
192#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_B (0x0080)
193#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_A (0x0040)
194#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_B (0x0020)
195#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_A (0x0010)
196#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_B (0x0008)
197#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_A (0x0004)
198#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_B (0x0002)
199#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_A (0x0001)
200
201#define U300_SYSCON_ECCR (0x0078)
202#define U300_SYSCON_ECCR_MASK (0x000F)
203#define U300_SYSCON_ECCR_EMIF_1_STATIC_CLK_EN_N_DISABLE (0x0008)
204#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004)
205#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002)
206#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001)
207
208#define U300_SYSCON_MMF0R (0x90)
209#define U300_SYSCON_MMF0R_MASK (0x00FF)
210#define U300_SYSCON_MMF0R_FREQ_0_HIGH_MASK (0x00F0)
211#define U300_SYSCON_MMF0R_FREQ_0_LOW_MASK (0x000F)
212
213#define U300_SYSCON_MMF1R (0x94)
214#define U300_SYSCON_MMF1R_MASK (0x00FF)
215#define U300_SYSCON_MMF1R_FREQ_1_HIGH_MASK (0x00F0)
216#define U300_SYSCON_MMF1R_FREQ_1_LOW_MASK (0x000F)
217
218#define U300_SYSCON_MMCR (0x9C)
219#define U300_SYSCON_MMCR_MASK (0x0003)
220#define U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE (0x0002)
221#define U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE (0x0001)
222
223#define U300_SYSCON_S0CCR (0x120)
224#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF)
225#define U300_SYSCON_S0CCR_CLOCK_REQ (0x4000)
226#define U300_SYSCON_S0CCR_CLOCK_REQ_MONITOR (0x2000)
227#define U300_SYSCON_S0CCR_CLOCK_INV (0x0200)
228#define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK (0x01E0)
229#define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK (0x001E)
230#define U300_SYSCON_S0CCR_CLOCK_ENABLE (0x0001)
231#define U300_SYSCON_S0CCR_SEL_MCLK (0x8<<1)
232#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK (0xA<<1)
233#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK (0xC<<1)
234#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK (0xD<<1)
235#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK (0xE<<1)
236#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK (0x0<<1)
237#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK (0x2<<1)
238#define U300_SYSCON_S0CCR_SEL_RTC_CLK (0x4<<1)
239#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK (0x6<<1)
240
241#define U300_SYSCON_S1CCR (0x124)
242#define U300_SYSCON_S1CCR_FIELD_MASK (0x43FF)
243#define U300_SYSCON_S1CCR_CLOCK_REQ (0x4000)
244#define U300_SYSCON_S1CCR_CLOCK_REQ_MONITOR (0x2000)
245#define U300_SYSCON_S1CCR_CLOCK_INV (0x0200)
246#define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK (0x01E0)
247#define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK (0x001E)
248#define U300_SYSCON_S1CCR_CLOCK_ENABLE (0x0001)
249#define U300_SYSCON_S1CCR_SEL_MCLK (0x8<<1)
250#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK (0xA<<1)
251#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK (0xC<<1)
252#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK (0xD<<1)
253#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK (0xE<<1)
254#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK (0x0<<1)
255#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK (0x2<<1)
256#define U300_SYSCON_S1CCR_SEL_RTC_CLK (0x4<<1)
257#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK (0x6<<1)
258
259#define U300_SYSCON_S2CCR (0x128)
260#define U300_SYSCON_S2CCR_FIELD_MASK (0xC3FF)
261#define U300_SYSCON_S2CCR_CLK_STEAL (0x8000)
262#define U300_SYSCON_S2CCR_CLOCK_REQ (0x4000)
263#define U300_SYSCON_S2CCR_CLOCK_REQ_MONITOR (0x2000)
264#define U300_SYSCON_S2CCR_CLOCK_INV (0x0200)
265#define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK (0x01E0)
266#define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK (0x001E)
267#define U300_SYSCON_S2CCR_CLOCK_ENABLE (0x0001)
268#define U300_SYSCON_S2CCR_SEL_MCLK (0x8<<1)
269#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK (0xA<<1)
270#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK (0xC<<1)
271#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK (0xD<<1)
272#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK (0xE<<1)
273#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK (0x0<<1)
274#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK (0x2<<1)
275#define U300_SYSCON_S2CCR_SEL_RTC_CLK (0x4<<1)
276#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK (0x6<<1)
277
278#define U300_SYSCON_PICR (0x0130)
279#define U300_SYSCON_PICR_MASK (0x00FF)
280#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_LOW_ENABLE (0x0080)
281#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_HIGH_ENABLE (0x0040)
282#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_LOW_ENABLE (0x0020)
283#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_HIGH_ENABLE (0x0010)
284#define U300_SYSCON_PICR_IRQMASK_PLL13_UNLOCK_ENABLE (0x0008)
285#define U300_SYSCON_PICR_IRQMASK_PLL13_LOCK_ENABLE (0x0004)
286#define U300_SYSCON_PICR_IRQMASK_PLL208_UNLOCK_ENABLE (0x0002)
287#define U300_SYSCON_PICR_IRQMASK_PLL208_LOCK_ENABLE (0x0001)
288
289#define U300_SYSCON_PISR (0x0134)
290#define U300_SYSCON_PISR_MASK (0x000F)
291#define U300_SYSCON_PISR_PLL13_UNLOCK_IND (0x0008)
292#define U300_SYSCON_PISR_PLL13_LOCK_IND (0x0004)
293#define U300_SYSCON_PISR_PLL208_UNLOCK_IND (0x0002)
294#define U300_SYSCON_PISR_PLL208_LOCK_IND (0x0001)
295
296#define U300_SYSCON_PICLR (0x0138)
297#define U300_SYSCON_PICLR_MASK (0x000F)
298#define U300_SYSCON_PICLR_RWMASK (0x0000)
299#define U300_SYSCON_PICLR_PLL13_UNLOCK_SC (0x0008)
300#define U300_SYSCON_PICLR_PLL13_LOCK_SC (0x0004)
301#define U300_SYSCON_PICLR_PLL208_UNLOCK_SC (0x0002)
302#define U300_SYSCON_PICLR_PLL208_LOCK_SC (0x0001)
303
304#define U300_SYSCON_C0OAR (0x140)
305#define U300_SYSCON_C0OAR_MASK (0xFFFF)
306#define U300_SYSCON_C0OAR_VALUE (0xFFFF)
307#define U300_SYSCON_C0OAR_BT_H_CLK (0x8000)
308#define U300_SYSCON_C0OAR_ASPB_P_CLK (0x4000)
309#define U300_SYSCON_C0OAR_APP_SEMI_H_CLK (0x2000)
310#define U300_SYSCON_C0OAR_APP_SEMI_CLK (0x1000)
311#define U300_SYSCON_C0OAR_APP_MMC_MSPRO_CLK (0x0800)
312#define U300_SYSCON_C0OAR_APP_I2S1_CLK (0x0400)
313#define U300_SYSCON_C0OAR_APP_I2S0_CLK (0x0200)
314#define U300_SYSCON_C0OAR_APP_CPU_CLK (0x0100)
315#define U300_SYSCON_C0OAR_APP_52_CLK (0x0080)
316#define U300_SYSCON_C0OAR_APP_208_CLK (0x0040)
317#define U300_SYSCON_C0OAR_APP_104_CLK (0x0020)
318#define U300_SYSCON_C0OAR_APEX_CLK (0x0010)
319#define U300_SYSCON_C0OAR_AHPB_M_H_CLK (0x0008)
320#define U300_SYSCON_C0OAR_AHB_CLK (0x0004)
321#define U300_SYSCON_C0OAR_AFPB_P_CLK (0x0002)
322#define U300_SYSCON_C0OAR_AAIF_CLK (0x0001)
323
324#define U300_SYSCON_C1OAR (0x144)
325#define U300_SYSCON_C1OAR_MASK (0x3FFE)
326#define U300_SYSCON_C1OAR_VALUE (0x3FFE)
327#define U300_SYSCON_C1OAR_NFIF_F_CLK (0x2000)
328#define U300_SYSCON_C1OAR_MSPRO_CLK (0x1000)
329#define U300_SYSCON_C1OAR_MMC_P_CLK (0x0800)
330#define U300_SYSCON_C1OAR_MMC_CLK (0x0400)
331#define U300_SYSCON_C1OAR_KP_P_CLK (0x0200)
332#define U300_SYSCON_C1OAR_I2C1_P_CLK (0x0100)
333#define U300_SYSCON_C1OAR_I2C0_P_CLK (0x0080)
334#define U300_SYSCON_C1OAR_GPIO_CLK (0x0040)
335#define U300_SYSCON_C1OAR_EMIF_MPMC_CLK (0x0020)
336#define U300_SYSCON_C1OAR_EMIF_H_CLK (0x0010)
337#define U300_SYSCON_C1OAR_EVHIST_CLK (0x0008)
338#define U300_SYSCON_C1OAR_PPM_CLK (0x0004)
339#define U300_SYSCON_C1OAR_DMA_CLK (0x0002)
340
341#define U300_SYSCON_C2OAR (0x148)
342#define U300_SYSCON_C2OAR_MASK (0x0FFF)
343#define U300_SYSCON_C2OAR_VALUE (0x0FFF)
344#define U300_SYSCON_C2OAR_XGAM_CDI_CLK (0x0800)
345#define U300_SYSCON_C2OAR_XGAM_CLK (0x0400)
346#define U300_SYSCON_C2OAR_VC_H_CLK (0x0200)
347#define U300_SYSCON_C2OAR_VC_CLK (0x0100)
348#define U300_SYSCON_C2OAR_UA_P_CLK (0x0080)
349#define U300_SYSCON_C2OAR_TMR1_CLK (0x0040)
350#define U300_SYSCON_C2OAR_TMR0_CLK (0x0020)
351#define U300_SYSCON_C2OAR_SPI_P_CLK (0x0010)
352#define U300_SYSCON_C2OAR_PCM_I2S1_CORE_CLK (0x0008)
353#define U300_SYSCON_C2OAR_PCM_I2S1_CLK (0x0004)
354#define U300_SYSCON_C2OAR_PCM_I2S0_CORE_CLK (0x0002)
355#define U300_SYSCON_C2OAR_PCM_I2S0_CLK (0x0001)
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418static void __iomem *syscon_vbase;
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433struct clk_syscon {
434 struct clk_hw hw;
435 bool hw_ctrld;
436 bool reset;
437 void __iomem *res_reg;
438 u8 res_bit;
439 void __iomem *en_reg;
440 u8 en_bit;
441 u16 clk_val;
442};
443
444#define to_syscon(_hw) container_of(_hw, struct clk_syscon, hw)
445
446static DEFINE_SPINLOCK(syscon_resetreg_lock);
447
448
449
450
451
452
453
454static void syscon_block_reset_enable(struct clk_syscon *sclk)
455{
456 unsigned long iflags;
457 u16 val;
458
459
460 if (!sclk->res_reg)
461 return;
462 spin_lock_irqsave(&syscon_resetreg_lock, iflags);
463 val = readw(sclk->res_reg);
464 val |= BIT(sclk->res_bit);
465 writew(val, sclk->res_reg);
466 spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
467 sclk->reset = true;
468}
469
470static void syscon_block_reset_disable(struct clk_syscon *sclk)
471{
472 unsigned long iflags;
473 u16 val;
474
475
476 if (!sclk->res_reg)
477 return;
478 spin_lock_irqsave(&syscon_resetreg_lock, iflags);
479 val = readw(sclk->res_reg);
480 val &= ~BIT(sclk->res_bit);
481 writew(val, sclk->res_reg);
482 spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
483 sclk->reset = false;
484}
485
486static int syscon_clk_prepare(struct clk_hw *hw)
487{
488 struct clk_syscon *sclk = to_syscon(hw);
489
490
491 if (sclk->reset)
492 syscon_block_reset_disable(sclk);
493 return 0;
494}
495
496static void syscon_clk_unprepare(struct clk_hw *hw)
497{
498 struct clk_syscon *sclk = to_syscon(hw);
499
500
501 if (sclk->clk_val == U300_SYSCON_SBCER_UART_CLK_EN)
502 return;
503
504 if (!sclk->reset)
505 syscon_block_reset_enable(sclk);
506}
507
508static int syscon_clk_enable(struct clk_hw *hw)
509{
510 struct clk_syscon *sclk = to_syscon(hw);
511
512
513 if (sclk->hw_ctrld)
514 return 0;
515
516 if (sclk->clk_val == 0xFFFFU)
517 return 0;
518
519 writew(sclk->clk_val, syscon_vbase + U300_SYSCON_SBCER);
520 return 0;
521}
522
523static void syscon_clk_disable(struct clk_hw *hw)
524{
525 struct clk_syscon *sclk = to_syscon(hw);
526
527
528 if (sclk->hw_ctrld)
529 return;
530 if (sclk->clk_val == 0xFFFFU)
531 return;
532
533 if (sclk->clk_val == U300_SYSCON_SBCER_UART_CLK_EN)
534 return;
535
536 writew(sclk->clk_val, syscon_vbase + U300_SYSCON_SBCDR);
537}
538
539static int syscon_clk_is_enabled(struct clk_hw *hw)
540{
541 struct clk_syscon *sclk = to_syscon(hw);
542 u16 val;
543
544
545 if (!sclk->en_reg)
546 return 1;
547
548 val = readw(sclk->en_reg);
549 val &= BIT(sclk->en_bit);
550
551 return val ? 1 : 0;
552}
553
554static u16 syscon_get_perf(void)
555{
556 u16 val;
557
558 val = readw(syscon_vbase + U300_SYSCON_CCR);
559 val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
560 return val;
561}
562
563static unsigned long
564syscon_clk_recalc_rate(struct clk_hw *hw,
565 unsigned long parent_rate)
566{
567 struct clk_syscon *sclk = to_syscon(hw);
568 u16 perf = syscon_get_perf();
569
570 switch(sclk->clk_val) {
571 case U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN:
572 case U300_SYSCON_SBCER_I2C0_CLK_EN:
573 case U300_SYSCON_SBCER_I2C1_CLK_EN:
574 case U300_SYSCON_SBCER_MMC_CLK_EN:
575 case U300_SYSCON_SBCER_SPI_CLK_EN:
576
577 switch(perf) {
578 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
579 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
580 return 13000000;
581 default:
582 return parent_rate;
583 }
584 case U300_SYSCON_SBCER_DMAC_CLK_EN:
585 case U300_SYSCON_SBCER_NANDIF_CLK_EN:
586 case U300_SYSCON_SBCER_XGAM_CLK_EN:
587
588 switch(perf) {
589 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
590 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
591 return 6500000;
592 case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
593 return 26000000;
594 default:
595 return parent_rate;
596 }
597 case U300_SYSCON_SBCER_SEMI_CLK_EN:
598 case U300_SYSCON_SBCER_EMIF_CLK_EN:
599
600 switch(perf) {
601 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
602 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
603 return 13000000;
604 case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
605 return 52000000;
606 default:
607 return 104000000;
608 }
609 case U300_SYSCON_SBCER_CPU_CLK_EN:
610
611 switch(perf) {
612 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
613 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
614 return 13000000;
615 case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
616 return 52000000;
617 case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
618 return 104000000;
619 default:
620 return parent_rate;
621 }
622 default:
623
624
625
626
627 return parent_rate;
628 }
629}
630
631static long
632syscon_clk_round_rate(struct clk_hw *hw, unsigned long rate,
633 unsigned long *prate)
634{
635 struct clk_syscon *sclk = to_syscon(hw);
636
637 if (sclk->clk_val != U300_SYSCON_SBCER_CPU_CLK_EN)
638 return *prate;
639
640 if (rate <= 13000000)
641 return 13000000;
642 if (rate <= 52000000)
643 return 52000000;
644 if (rate <= 104000000)
645 return 104000000;
646 return 208000000;
647}
648
649static int syscon_clk_set_rate(struct clk_hw *hw, unsigned long rate,
650 unsigned long parent_rate)
651{
652 struct clk_syscon *sclk = to_syscon(hw);
653 u16 val;
654
655
656 if (sclk->clk_val != U300_SYSCON_SBCER_CPU_CLK_EN)
657 return -EINVAL;
658 switch (rate) {
659 case 13000000:
660 val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER;
661 break;
662 case 52000000:
663 val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE;
664 break;
665 case 104000000:
666 val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH;
667 break;
668 case 208000000:
669 val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST;
670 break;
671 default:
672 return -EINVAL;
673 }
674 val |= readw(syscon_vbase + U300_SYSCON_CCR) &
675 ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ;
676 writew(val, syscon_vbase + U300_SYSCON_CCR);
677 return 0;
678}
679
680static const struct clk_ops syscon_clk_ops = {
681 .prepare = syscon_clk_prepare,
682 .unprepare = syscon_clk_unprepare,
683 .enable = syscon_clk_enable,
684 .disable = syscon_clk_disable,
685 .is_enabled = syscon_clk_is_enabled,
686 .recalc_rate = syscon_clk_recalc_rate,
687 .round_rate = syscon_clk_round_rate,
688 .set_rate = syscon_clk_set_rate,
689};
690
691static struct clk * __init
692syscon_clk_register(struct device *dev, const char *name,
693 const char *parent_name, unsigned long flags,
694 bool hw_ctrld,
695 void __iomem *res_reg, u8 res_bit,
696 void __iomem *en_reg, u8 en_bit,
697 u16 clk_val)
698{
699 struct clk *clk;
700 struct clk_syscon *sclk;
701 struct clk_init_data init;
702
703 sclk = kzalloc(sizeof(struct clk_syscon), GFP_KERNEL);
704 if (!sclk) {
705 pr_err("could not allocate syscon clock %s\n",
706 name);
707 return ERR_PTR(-ENOMEM);
708 }
709 init.name = name;
710 init.ops = &syscon_clk_ops;
711 init.flags = flags;
712 init.parent_names = (parent_name ? &parent_name : NULL);
713 init.num_parents = (parent_name ? 1 : 0);
714 sclk->hw.init = &init;
715 sclk->hw_ctrld = hw_ctrld;
716
717 sclk->reset = true;
718 sclk->res_reg = res_reg;
719 sclk->res_bit = res_bit;
720 sclk->en_reg = en_reg;
721 sclk->en_bit = en_bit;
722 sclk->clk_val = clk_val;
723
724 clk = clk_register(dev, &sclk->hw);
725 if (IS_ERR(clk))
726 kfree(sclk);
727
728 return clk;
729}
730
731#define U300_CLK_TYPE_SLOW 0
732#define U300_CLK_TYPE_FAST 1
733#define U300_CLK_TYPE_REST 2
734
735
736
737
738
739
740
741
742struct u300_clock {
743 u8 type;
744 u8 id;
745 bool hw_ctrld;
746 u16 clk_val;
747};
748
749static struct u300_clock const u300_clk_lookup[] __initconst = {
750 {
751 .type = U300_CLK_TYPE_REST,
752 .id = 3,
753 .hw_ctrld = true,
754 .clk_val = U300_SYSCON_SBCER_CPU_CLK_EN,
755 },
756 {
757 .type = U300_CLK_TYPE_REST,
758 .id = 4,
759 .hw_ctrld = true,
760 .clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN,
761 },
762 {
763 .type = U300_CLK_TYPE_REST,
764 .id = 5,
765 .hw_ctrld = false,
766 .clk_val = U300_SYSCON_SBCER_EMIF_CLK_EN,
767 },
768 {
769 .type = U300_CLK_TYPE_REST,
770 .id = 6,
771 .hw_ctrld = false,
772 .clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN,
773 },
774 {
775 .type = U300_CLK_TYPE_REST,
776 .id = 8,
777 .hw_ctrld = true,
778 .clk_val = U300_SYSCON_SBCER_XGAM_CLK_EN,
779 },
780 {
781 .type = U300_CLK_TYPE_REST,
782 .id = 9,
783 .hw_ctrld = false,
784 .clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN,
785 },
786 {
787 .type = U300_CLK_TYPE_REST,
788 .id = 10,
789 .hw_ctrld = true,
790 .clk_val = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN,
791 },
792 {
793 .type = U300_CLK_TYPE_REST,
794 .id = 12,
795 .hw_ctrld = false,
796
797 .clk_val = 0xFFFFU,
798 },
799 {
800 .type = U300_CLK_TYPE_FAST,
801 .id = 0,
802 .hw_ctrld = true,
803 .clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN,
804 },
805 {
806 .type = U300_CLK_TYPE_FAST,
807 .id = 1,
808 .hw_ctrld = false,
809 .clk_val = U300_SYSCON_SBCER_I2C0_CLK_EN,
810 },
811 {
812 .type = U300_CLK_TYPE_FAST,
813 .id = 2,
814 .hw_ctrld = false,
815 .clk_val = U300_SYSCON_SBCER_I2C1_CLK_EN,
816 },
817 {
818 .type = U300_CLK_TYPE_FAST,
819 .id = 5,
820 .hw_ctrld = false,
821 .clk_val = U300_SYSCON_SBCER_MMC_CLK_EN,
822 },
823 {
824 .type = U300_CLK_TYPE_FAST,
825 .id = 6,
826 .hw_ctrld = false,
827 .clk_val = U300_SYSCON_SBCER_SPI_CLK_EN,
828 },
829 {
830 .type = U300_CLK_TYPE_SLOW,
831 .id = 0,
832 .hw_ctrld = true,
833 .clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN,
834 },
835 {
836 .type = U300_CLK_TYPE_SLOW,
837 .id = 1,
838 .hw_ctrld = false,
839 .clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
840 },
841 {
842 .type = U300_CLK_TYPE_SLOW,
843 .id = 4,
844 .hw_ctrld = false,
845 .clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN,
846 },
847 {
848 .type = U300_CLK_TYPE_SLOW,
849 .id = 6,
850 .hw_ctrld = true,
851
852 .clk_val = 0xFFFFU,
853 },
854 {
855 .type = U300_CLK_TYPE_SLOW,
856 .id = 7,
857 .hw_ctrld = false,
858 .clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN,
859 },
860 {
861 .type = U300_CLK_TYPE_SLOW,
862 .id = 8,
863 .hw_ctrld = false,
864 .clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN,
865 },
866};
867
868static void __init of_u300_syscon_clk_init(struct device_node *np)
869{
870 struct clk *clk = ERR_PTR(-EINVAL);
871 const char *clk_name = np->name;
872 const char *parent_name;
873 void __iomem *res_reg;
874 void __iomem *en_reg;
875 u32 clk_type;
876 u32 clk_id;
877 int i;
878
879 if (of_property_read_u32(np, "clock-type", &clk_type)) {
880 pr_err("%s: syscon clock \"%s\" missing clock-type property\n",
881 __func__, clk_name);
882 return;
883 }
884 if (of_property_read_u32(np, "clock-id", &clk_id)) {
885 pr_err("%s: syscon clock \"%s\" missing clock-id property\n",
886 __func__, clk_name);
887 return;
888 }
889 parent_name = of_clk_get_parent_name(np, 0);
890
891 switch (clk_type) {
892 case U300_CLK_TYPE_SLOW:
893 res_reg = syscon_vbase + U300_SYSCON_RSR;
894 en_reg = syscon_vbase + U300_SYSCON_CESR;
895 break;
896 case U300_CLK_TYPE_FAST:
897 res_reg = syscon_vbase + U300_SYSCON_RFR;
898 en_reg = syscon_vbase + U300_SYSCON_CEFR;
899 break;
900 case U300_CLK_TYPE_REST:
901 res_reg = syscon_vbase + U300_SYSCON_RRR;
902 en_reg = syscon_vbase + U300_SYSCON_CERR;
903 break;
904 default:
905 pr_err("unknown clock type %x specified\n", clk_type);
906 return;
907 }
908
909 for (i = 0; i < ARRAY_SIZE(u300_clk_lookup); i++) {
910 const struct u300_clock *u3clk = &u300_clk_lookup[i];
911
912 if (u3clk->type == clk_type && u3clk->id == clk_id)
913 clk = syscon_clk_register(NULL,
914 clk_name, parent_name,
915 0, u3clk->hw_ctrld,
916 res_reg, u3clk->id,
917 en_reg, u3clk->id,
918 u3clk->clk_val);
919 }
920
921 if (!IS_ERR(clk)) {
922 of_clk_add_provider(np, of_clk_src_simple_get, clk);
923
924
925
926
927
928
929 if (clk_type == U300_CLK_TYPE_REST && clk_id == 5)
930 clk_register_clkdev(clk, NULL, "pl172");
931 if (clk_type == U300_CLK_TYPE_REST && clk_id == 9)
932 clk_register_clkdev(clk, NULL, "semi");
933 if (clk_type == U300_CLK_TYPE_REST && clk_id == 12)
934 clk_register_clkdev(clk, NULL, "intcon");
935 }
936}
937
938
939
940
941
942
943struct clk_mclk {
944 struct clk_hw hw;
945 bool is_mspro;
946};
947
948#define to_mclk(_hw) container_of(_hw, struct clk_mclk, hw)
949
950static int mclk_clk_prepare(struct clk_hw *hw)
951{
952 struct clk_mclk *mclk = to_mclk(hw);
953 u16 val;
954
955
956 if (!mclk->is_mspro) {
957
958 writew(0x0054U, syscon_vbase + U300_SYSCON_MMF0R);
959 val = readw(syscon_vbase + U300_SYSCON_MMCR);
960
961 val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
962
963 val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
964 writew(val, syscon_vbase + U300_SYSCON_MMCR);
965 } else {
966 val = readw(syscon_vbase + U300_SYSCON_MMCR);
967
968 val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
969
970 val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
971 writew(val, syscon_vbase + U300_SYSCON_MMCR);
972 }
973
974 return 0;
975}
976
977static unsigned long
978mclk_clk_recalc_rate(struct clk_hw *hw,
979 unsigned long parent_rate)
980{
981 u16 perf = syscon_get_perf();
982
983 switch (perf) {
984 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
985
986
987
988
989
990 return 13000000;
991 case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
992 case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
993 case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
994 case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
995 {
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009 u16 val = readw(syscon_vbase + U300_SYSCON_MMF0R) &
1010 U300_SYSCON_MMF0R_MASK;
1011 switch (val) {
1012 case 0x0054:
1013 return 18900000;
1014 case 0x0044:
1015 return 20800000;
1016 case 0x0043:
1017 return 23100000;
1018 case 0x0033:
1019 return 26000000;
1020 case 0x0032:
1021 return 29700000;
1022 case 0x0022:
1023 return 34700000;
1024 case 0x0021:
1025 return 41600000;
1026 case 0x0011:
1027 return 52000000;
1028 case 0x0000:
1029 return 104000000;
1030 default:
1031 break;
1032 }
1033 }
1034 default:
1035 break;
1036 }
1037 return parent_rate;
1038}
1039
1040static long
1041mclk_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1042 unsigned long *prate)
1043{
1044 if (rate <= 18900000)
1045 return 18900000;
1046 if (rate <= 20800000)
1047 return 20800000;
1048 if (rate <= 23100000)
1049 return 23100000;
1050 if (rate <= 26000000)
1051 return 26000000;
1052 if (rate <= 29700000)
1053 return 29700000;
1054 if (rate <= 34700000)
1055 return 34700000;
1056 if (rate <= 41600000)
1057 return 41600000;
1058
1059 return 52000000;
1060}
1061
1062static int mclk_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1063 unsigned long parent_rate)
1064{
1065 u16 val;
1066 u16 reg;
1067
1068 switch (rate) {
1069 case 18900000:
1070 val = 0x0054;
1071 break;
1072 case 20800000:
1073 val = 0x0044;
1074 break;
1075 case 23100000:
1076 val = 0x0043;
1077 break;
1078 case 26000000:
1079 val = 0x0033;
1080 break;
1081 case 29700000:
1082 val = 0x0032;
1083 break;
1084 case 34700000:
1085 val = 0x0022;
1086 break;
1087 case 41600000:
1088 val = 0x0021;
1089 break;
1090 case 52000000:
1091 val = 0x0011;
1092 break;
1093 case 104000000:
1094 val = 0x0000;
1095 break;
1096 default:
1097 return -EINVAL;
1098 }
1099
1100 reg = readw(syscon_vbase + U300_SYSCON_MMF0R) &
1101 ~U300_SYSCON_MMF0R_MASK;
1102 writew(reg | val, syscon_vbase + U300_SYSCON_MMF0R);
1103 return 0;
1104}
1105
1106static const struct clk_ops mclk_ops = {
1107 .prepare = mclk_clk_prepare,
1108 .recalc_rate = mclk_clk_recalc_rate,
1109 .round_rate = mclk_clk_round_rate,
1110 .set_rate = mclk_clk_set_rate,
1111};
1112
1113static struct clk * __init
1114mclk_clk_register(struct device *dev, const char *name,
1115 const char *parent_name, bool is_mspro)
1116{
1117 struct clk *clk;
1118 struct clk_mclk *mclk;
1119 struct clk_init_data init;
1120
1121 mclk = kzalloc(sizeof(struct clk_mclk), GFP_KERNEL);
1122 if (!mclk) {
1123 pr_err("could not allocate MMC/SD clock %s\n",
1124 name);
1125 return ERR_PTR(-ENOMEM);
1126 }
1127 init.name = "mclk";
1128 init.ops = &mclk_ops;
1129 init.flags = 0;
1130 init.parent_names = (parent_name ? &parent_name : NULL);
1131 init.num_parents = (parent_name ? 1 : 0);
1132 mclk->hw.init = &init;
1133 mclk->is_mspro = is_mspro;
1134
1135 clk = clk_register(dev, &mclk->hw);
1136 if (IS_ERR(clk))
1137 kfree(mclk);
1138
1139 return clk;
1140}
1141
1142static void __init of_u300_syscon_mclk_init(struct device_node *np)
1143{
1144 struct clk *clk = ERR_PTR(-EINVAL);
1145 const char *clk_name = np->name;
1146 const char *parent_name;
1147
1148 parent_name = of_clk_get_parent_name(np, 0);
1149 clk = mclk_clk_register(NULL, clk_name, parent_name, false);
1150 if (!IS_ERR(clk))
1151 of_clk_add_provider(np, of_clk_src_simple_get, clk);
1152}
1153
1154static const struct of_device_id u300_clk_match[] __initconst = {
1155 {
1156 .compatible = "fixed-clock",
1157 .data = of_fixed_clk_setup,
1158 },
1159 {
1160 .compatible = "fixed-factor-clock",
1161 .data = of_fixed_factor_clk_setup,
1162 },
1163 {
1164 .compatible = "stericsson,u300-syscon-clk",
1165 .data = of_u300_syscon_clk_init,
1166 },
1167 {
1168 .compatible = "stericsson,u300-syscon-mclk",
1169 .data = of_u300_syscon_mclk_init,
1170 },
1171 {}
1172};
1173
1174
1175void __init u300_clk_init(void __iomem *base)
1176{
1177 u16 val;
1178
1179 syscon_vbase = base;
1180
1181
1182 val = readw(syscon_vbase + U300_SYSCON_CCR);
1183 val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
1184 writew(val, syscon_vbase + U300_SYSCON_CCR);
1185
1186 while (!(readw(syscon_vbase + U300_SYSCON_CSR) &
1187 U300_SYSCON_CSR_PLL208_LOCK_IND));
1188
1189
1190 val = readw(syscon_vbase + U300_SYSCON_PMCR);
1191 val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE;
1192 writew(val, syscon_vbase + U300_SYSCON_PMCR);
1193
1194 of_clk_init(u300_clk_match);
1195}
1196