2 * Marvell PXA27x family clocks
4 * Copyright (C) 2014 Robert Jarzmik
6 * Heavily inspired from former arch/arm/mach-pxa/clock.c.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
13 #include <linux/clk-provider.h>
14 #include <mach/pxa2xx-regs.h>
16 #include <linux/clk.h>
17 #include <linux/clkdev.h>
20 #include <dt-bindings/clock/pxa-clock.h>
24 #define MHz (1000 * 1000)
48 static const char * const get_freq_khz
[] = {
49 "core", "run", "cpll", "memory",
54 * Get the clock frequency as reflected by CCSR and the turbo flag.
55 * We assume these values have been applied via a fcs.
56 * If info is not 0 we also display the current settings.
58 unsigned int pxa27x_get_clk_frequency_khz(int info
)
61 unsigned long clks
[5];
64 for (i
= 0; i
< 5; i
++) {
65 clk
= clk_get(NULL
, get_freq_khz
[i
]);
69 clks
[i
] = clk_get_rate(clk
);
74 pr_info("Run Mode clock: %ld.%02ldMHz\n",
75 clks
[1] / 1000000, (clks
[1] % 1000000) / 10000);
76 pr_info("Turbo Mode clock: %ld.%02ldMHz\n",
77 clks
[2] / 1000000, (clks
[2] % 1000000) / 10000);
78 pr_info("Memory clock: %ld.%02ldMHz\n",
79 clks
[3] / 1000000, (clks
[3] % 1000000) / 10000);
80 pr_info("System bus clock: %ld.%02ldMHz\n",
81 clks
[4] / 1000000, (clks
[4] % 1000000) / 10000);
83 return (unsigned int)clks
[0] / KHz
;
86 bool pxa27x_is_ppll_disabled(void)
88 unsigned long ccsr
= CCSR
;
90 return ccsr
& (1 << CCCR_PPDIS_BIT
);
93 #define PXA27X_CKEN(dev_id, con_id, parents, mult_hp, div_hp, \
95 PXA_CKEN(dev_id, con_id, bit, parents, 1, 1, mult_hp, div_hp, \
96 is_lp, &CKEN, CKEN_ ## bit, flags)
97 #define PXA27X_PBUS_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \
98 PXA27X_CKEN(dev_id, con_id, pxa27x_pbus_parents, mult_hp, \
99 div_hp, bit, pxa27x_is_ppll_disabled, 0)
101 PARENTS(pxa27x_pbus
) = { "osc_13mhz", "ppll_312mhz" };
102 PARENTS(pxa27x_sbus
) = { "system_bus", "system_bus" };
103 PARENTS(pxa27x_32Mhz_bus
) = { "osc_32_768khz", "osc_32_768khz" };
104 PARENTS(pxa27x_lcd_bus
) = { "lcd_base", "lcd_base" };
105 PARENTS(pxa27x_membus
) = { "lcd_base", "lcd_base" };
107 #define PXA27X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \
108 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
109 &CKEN, CKEN_ ## bit, 0)
110 #define PXA27X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \
111 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
112 &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
114 static struct desc_clk_cken pxa27x_clocks
[] __initdata
= {
115 PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL
, FFUART
, 2, 42, 1),
116 PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL
, BTUART
, 2, 42, 1),
117 PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL
, STUART
, 2, 42, 1),
118 PXA27X_PBUS_CKEN("pxa2xx-i2s", NULL
, I2S
, 2, 51, 0),
119 PXA27X_PBUS_CKEN("pxa2xx-i2c.0", NULL
, I2C
, 2, 19, 0),
120 PXA27X_PBUS_CKEN("pxa27x-udc", NULL
, USB
, 2, 13, 5),
121 PXA27X_PBUS_CKEN("pxa2xx-mci.0", NULL
, MMC
, 2, 32, 0),
122 PXA27X_PBUS_CKEN("pxa2xx-ir", "FICPCLK", FICP
, 2, 13, 0),
123 PXA27X_PBUS_CKEN("pxa27x-ohci", NULL
, USBHOST
, 2, 13, 0),
124 PXA27X_PBUS_CKEN("pxa2xx-i2c.1", NULL
, PWRI2C
, 1, 24, 0),
125 PXA27X_PBUS_CKEN("pxa27x-ssp.0", NULL
, SSP1
, 1, 24, 0),
126 PXA27X_PBUS_CKEN("pxa27x-ssp.1", NULL
, SSP2
, 1, 24, 0),
127 PXA27X_PBUS_CKEN("pxa27x-ssp.2", NULL
, SSP3
, 1, 24, 0),
128 PXA27X_PBUS_CKEN("pxa27x-pwm.0", NULL
, PWM0
, 1, 24, 0),
129 PXA27X_PBUS_CKEN("pxa27x-pwm.1", NULL
, PWM1
, 1, 24, 0),
130 PXA27X_PBUS_CKEN(NULL
, "MSLCLK", MSL
, 2, 13, 0),
131 PXA27X_PBUS_CKEN(NULL
, "USIMCLK", USIM
, 2, 13, 0),
132 PXA27X_PBUS_CKEN(NULL
, "MSTKCLK", MEMSTK
, 2, 32, 0),
133 PXA27X_PBUS_CKEN(NULL
, "AC97CLK", AC97
, 1, 1, 0),
134 PXA27X_PBUS_CKEN(NULL
, "AC97CONFCLK", AC97CONF
, 1, 1, 0),
135 PXA27X_PBUS_CKEN(NULL
, "OSTIMER0", OSTIMER
, 1, 96, 0),
137 PXA27X_CKEN_1RATE("pxa27x-keypad", NULL
, KEYPAD
,
138 pxa27x_32Mhz_bus_parents
, 0),
139 PXA27X_CKEN_1RATE(NULL
, "IMCLK", IM
, pxa27x_sbus_parents
, 0),
140 PXA27X_CKEN_1RATE("pxa2xx-fb", NULL
, LCD
, pxa27x_lcd_bus_parents
, 0),
141 PXA27X_CKEN_1RATE("pxa27x-camera.0", NULL
, CAMERA
,
142 pxa27x_lcd_bus_parents
, 0),
143 PXA27X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL
, MEMC
,
144 pxa27x_membus_parents
, 0),
148 static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw
*hw
,
149 unsigned long parent_rate
)
151 unsigned long clkcfg
;
153 unsigned int l
, L
, n2
, N
;
154 unsigned long ccsr
= CCSR
;
156 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg
));
157 t
= clkcfg
& (1 << 0);
158 ht
= clkcfg
& (1 << 2);
160 l
= ccsr
& CCSR_L_MASK
;
161 n2
= (ccsr
& CCSR_N2_MASK
) >> CCSR_N2_SHIFT
;
167 PARENTS(clk_pxa27x_cpll
) = { "osc_13mhz" };
168 RATE_RO_OPS(clk_pxa27x_cpll
, "cpll");
170 static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw
*hw
,
171 unsigned long parent_rate
)
173 unsigned int l
, osc_forced
;
174 unsigned long ccsr
= CCSR
;
175 unsigned long cccr
= CCCR
;
177 l
= ccsr
& CCSR_L_MASK
;
178 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
180 if (cccr
& (1 << CCCR_LCD_26_BIT
))
181 return parent_rate
* 2;
189 return parent_rate
/ 2;
190 return parent_rate
/ 4;
193 static u8
clk_pxa27x_lcd_base_get_parent(struct clk_hw
*hw
)
195 unsigned int osc_forced
;
196 unsigned long ccsr
= CCSR
;
198 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
200 return PXA_LCD_13Mhz
;
205 PARENTS(clk_pxa27x_lcd_base
) = { "osc_13mhz", "run" };
206 MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base
, "lcd_base");
208 static void __init
pxa27x_register_plls(void)
210 clk_register_fixed_rate(NULL
, "osc_13mhz", NULL
,
211 CLK_GET_RATE_NOCACHE
| CLK_IS_ROOT
,
213 clk_register_fixed_rate(NULL
, "osc_32_768khz", NULL
,
214 CLK_GET_RATE_NOCACHE
| CLK_IS_ROOT
,
216 clk_register_fixed_rate(NULL
, "clk_dummy", NULL
, CLK_IS_ROOT
, 0);
217 clk_register_fixed_factor(NULL
, "ppll_312mhz", "osc_13mhz", 0, 24, 1);
220 static unsigned long clk_pxa27x_core_get_rate(struct clk_hw
*hw
,
221 unsigned long parent_rate
)
223 unsigned long clkcfg
;
224 unsigned int t
, ht
, b
, osc_forced
;
225 unsigned long ccsr
= CCSR
;
227 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
228 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg
));
229 t
= clkcfg
& (1 << 0);
230 ht
= clkcfg
& (1 << 2);
231 b
= clkcfg
& (1 << 3);
236 return parent_rate
/ 2;
241 static u8
clk_pxa27x_core_get_parent(struct clk_hw
*hw
)
243 unsigned long clkcfg
;
244 unsigned int t
, ht
, b
, osc_forced
;
245 unsigned long ccsr
= CCSR
;
247 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
249 return PXA_CORE_13Mhz
;
251 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg
));
252 t
= clkcfg
& (1 << 0);
253 ht
= clkcfg
& (1 << 2);
254 b
= clkcfg
& (1 << 3);
257 return PXA_CORE_TURBO
;
260 PARENTS(clk_pxa27x_core
) = { "osc_13mhz", "run", "cpll" };
261 MUX_RO_RATE_RO_OPS(clk_pxa27x_core
, "core");
263 static unsigned long clk_pxa27x_run_get_rate(struct clk_hw
*hw
,
264 unsigned long parent_rate
)
266 unsigned long ccsr
= CCSR
;
267 unsigned int n2
= (ccsr
& CCSR_N2_MASK
) >> CCSR_N2_SHIFT
;
269 return (parent_rate
/ n2
) * 2;
271 PARENTS(clk_pxa27x_run
) = { "cpll" };
272 RATE_RO_OPS(clk_pxa27x_run
, "run");
274 static void __init
pxa27x_register_core(void)
276 clk_register_clk_pxa27x_cpll();
277 clk_register_clk_pxa27x_run();
279 clkdev_pxa_register(CLK_CORE
, "core", NULL
,
280 clk_register_clk_pxa27x_core());
283 static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw
*hw
,
284 unsigned long parent_rate
)
286 unsigned long clkcfg
;
287 unsigned int b
, osc_forced
;
288 unsigned long ccsr
= CCSR
;
290 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
291 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg
));
292 b
= clkcfg
& (1 << 3);
297 return parent_rate
/ 2;
302 static u8
clk_pxa27x_system_bus_get_parent(struct clk_hw
*hw
)
304 unsigned int osc_forced
;
305 unsigned long ccsr
= CCSR
;
307 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
309 return PXA_BUS_13Mhz
;
314 PARENTS(clk_pxa27x_system_bus
) = { "osc_13mhz", "run" };
315 MUX_RO_RATE_RO_OPS(clk_pxa27x_system_bus
, "system_bus");
317 static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw
*hw
,
318 unsigned long parent_rate
)
320 unsigned int a
, l
, osc_forced
;
321 unsigned long cccr
= CCCR
;
322 unsigned long ccsr
= CCSR
;
324 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
325 a
= cccr
& (1 << CCCR_A_BIT
);
326 l
= ccsr
& CCSR_L_MASK
;
333 return parent_rate
/ 2;
334 return parent_rate
/ 4;
337 static u8
clk_pxa27x_memory_get_parent(struct clk_hw
*hw
)
339 unsigned int osc_forced
, a
;
340 unsigned long cccr
= CCCR
;
341 unsigned long ccsr
= CCSR
;
343 osc_forced
= ccsr
& (1 << CCCR_CPDIS_BIT
);
344 a
= cccr
& (1 << CCCR_A_BIT
);
346 return PXA_MEM_13Mhz
;
348 return PXA_MEM_SYSTEM_BUS
;
353 PARENTS(clk_pxa27x_memory
) = { "osc_13mhz", "system_bus", "run" };
354 MUX_RO_RATE_RO_OPS(clk_pxa27x_memory
, "memory");
356 #define DUMMY_CLK(_con_id, _dev_id, _parent) \
357 { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent }
363 static struct dummy_clk dummy_clks
[] __initdata
= {
364 DUMMY_CLK(NULL
, "pxa27x-gpio", "osc_32_768khz"),
365 DUMMY_CLK(NULL
, "sa1100-rtc", "osc_32_768khz"),
366 DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
369 static void __init
pxa27x_dummy_clocks_init(void)
376 for (i
= 0; i
< ARRAY_SIZE(dummy_clks
); i
++) {
378 name
= d
->dev_id
? d
->dev_id
: d
->con_id
;
379 clk
= clk_register_fixed_factor(NULL
, name
, d
->parent
, 0, 1, 1);
380 clk_register_clkdev(clk
, d
->con_id
, d
->dev_id
);
384 static void __init
pxa27x_base_clocks_init(void)
386 pxa27x_register_plls();
387 pxa27x_register_core();
388 clk_register_clk_pxa27x_system_bus();
389 clk_register_clk_pxa27x_memory();
390 clk_register_clk_pxa27x_lcd_base();
393 int __init
pxa27x_clocks_init(void)
395 pxa27x_base_clocks_init();
396 pxa27x_dummy_clocks_init();
397 return clk_pxa_cken_init(pxa27x_clocks
, ARRAY_SIZE(pxa27x_clocks
));
400 static void __init
pxa27x_dt_clocks_init(struct device_node
*np
)
402 pxa27x_clocks_init();
403 clk_pxa_dt_common_init(np
);
405 CLK_OF_DECLARE(pxa_clks
, "marvell,pxa270-clocks", pxa27x_dt_clocks_init
);