clk-pxa25x.c (fd13f8117f7a2d4054bf420ec1428e918a24a480) clk-pxa25x.c (3c816d950a494ae6e16b1fa017af29bc53cb7791)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Marvell PXA25x family clocks
4 *
5 * Copyright (C) 2014 Robert Jarzmik
6 *
7 * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c.
8 *
9 * For non-devicetree platforms. Once pxa is fully converted to devicetree, this
10 * should go away.
11 */
12#include <linux/clk-provider.h>
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/io.h>
16#include <linux/of.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Marvell PXA25x family clocks
4 *
5 * Copyright (C) 2014 Robert Jarzmik
6 *
7 * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c.
8 *
9 * For non-devicetree platforms. Once pxa is fully converted to devicetree, this
10 * should go away.
11 */
12#include <linux/clk-provider.h>
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/io.h>
16#include <linux/of.h>
17#include <mach/pxa2xx-regs.h>
18#include <linux/soc/pxa/smemc.h>
19
20#include <dt-bindings/clock/pxa-clock.h>
21#include "clk-pxa.h"
17#include <linux/soc/pxa/smemc.h>
18
19#include <dt-bindings/clock/pxa-clock.h>
20#include "clk-pxa.h"
21#include "clk-pxa2xx.h"
22
23#define KHz 1000
24#define MHz (1000 * 1000)
25
26enum {
27 PXA_CORE_RUN = 0,
28 PXA_CORE_TURBO,
29};

--- 4 unchanged lines hidden (view full) ---

34#define PXA25x_CCCR(N2, M, L) (N2 << 7 | M << 5 | L)
35
36/* Define the refresh period in mSec for the SDRAM and the number of rows */
37#define SDRAM_TREF 64 /* standard 64ms SDRAM */
38
39/*
40 * Various clock factors driven by the CCCR register.
41 */
22
23#define KHz 1000
24#define MHz (1000 * 1000)
25
26enum {
27 PXA_CORE_RUN = 0,
28 PXA_CORE_TURBO,
29};

--- 4 unchanged lines hidden (view full) ---

34#define PXA25x_CCCR(N2, M, L) (N2 << 7 | M << 5 | L)
35
36/* Define the refresh period in mSec for the SDRAM and the number of rows */
37#define SDRAM_TREF 64 /* standard 64ms SDRAM */
38
39/*
40 * Various clock factors driven by the CCCR register.
41 */
42static void __iomem *clk_regs;
42
43/* Crystal Frequency to Memory Frequency Multiplier (L) */
44static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
45
46/* Memory Frequency to Run Mode Frequency Multiplier (M) */
47static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
48
49/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */

--- 42 unchanged lines hidden (view full) ---

92 }
93
94 return (unsigned int)clks[0] / KHz;
95}
96
97static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw,
98 unsigned long parent_rate)
99{
43
44/* Crystal Frequency to Memory Frequency Multiplier (L) */
45static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
46
47/* Memory Frequency to Run Mode Frequency Multiplier (M) */
48static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
49
50/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */

--- 42 unchanged lines hidden (view full) ---

93 }
94
95 return (unsigned int)clks[0] / KHz;
96}
97
98static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw,
99 unsigned long parent_rate)
100{
100 unsigned long cccr = readl(CCCR);
101 unsigned long cccr = readl(clk_regs + CCCR);
101 unsigned int m = M_clk_mult[(cccr >> 5) & 0x03];
102
103 return parent_rate / m;
104}
105PARENTS(clk_pxa25x_memory) = { "run" };
106RATE_RO_OPS(clk_pxa25x_memory, "memory");
107
108PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" };

--- 87 unchanged lines hidden (view full) ---

196}
197
198PARENTS(clk_pxa25x_core) = { "run", "cpll" };
199MUX_OPS(clk_pxa25x_core, "core", CLK_SET_RATE_PARENT);
200
201static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw,
202 unsigned long parent_rate)
203{
102 unsigned int m = M_clk_mult[(cccr >> 5) & 0x03];
103
104 return parent_rate / m;
105}
106PARENTS(clk_pxa25x_memory) = { "run" };
107RATE_RO_OPS(clk_pxa25x_memory, "memory");
108
109PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" };

--- 87 unchanged lines hidden (view full) ---

197}
198
199PARENTS(clk_pxa25x_core) = { "run", "cpll" };
200MUX_OPS(clk_pxa25x_core, "core", CLK_SET_RATE_PARENT);
201
202static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw,
203 unsigned long parent_rate)
204{
204 unsigned long cccr = readl(CCCR);
205 unsigned long cccr = readl(clk_regs + CCCR);
205 unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07];
206
207 return (parent_rate / n2) * 2;
208}
209PARENTS(clk_pxa25x_run) = { "cpll" };
210RATE_RO_OPS(clk_pxa25x_run, "run");
211
212static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw,
213 unsigned long parent_rate)
214{
206 unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07];
207
208 return (parent_rate / n2) * 2;
209}
210PARENTS(clk_pxa25x_run) = { "cpll" };
211RATE_RO_OPS(clk_pxa25x_run, "run");
212
213static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw,
214 unsigned long parent_rate)
215{
215 unsigned long clkcfg, cccr = readl(CCCR);
216 unsigned long clkcfg, cccr = readl(clk_regs + CCCR);
216 unsigned int l, m, n2, t;
217
218 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
219 t = clkcfg & (1 << 0);
220 l = L_clk_mult[(cccr >> 0) & 0x1f];
221 m = M_clk_mult[(cccr >> 5) & 0x03];
222 n2 = N2_clk_mult[(cccr >> 7) & 0x07];
223

--- 15 unchanged lines hidden (view full) ---

239 pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate);
240 for (i = 0; i < ARRAY_SIZE(pxa25x_freqs); i++)
241 if (pxa25x_freqs[i].cpll == rate)
242 break;
243
244 if (i >= ARRAY_SIZE(pxa25x_freqs))
245 return -EINVAL;
246
217 unsigned int l, m, n2, t;
218
219 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
220 t = clkcfg & (1 << 0);
221 l = L_clk_mult[(cccr >> 0) & 0x1f];
222 m = M_clk_mult[(cccr >> 5) & 0x03];
223 n2 = N2_clk_mult[(cccr >> 7) & 0x07];
224

--- 15 unchanged lines hidden (view full) ---

240 pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate);
241 for (i = 0; i < ARRAY_SIZE(pxa25x_freqs); i++)
242 if (pxa25x_freqs[i].cpll == rate)
243 break;
244
245 if (i >= ARRAY_SIZE(pxa25x_freqs))
246 return -EINVAL;
247
247 pxa2xx_cpll_change(&pxa25x_freqs[i], mdrefr_dri, CCCR);
248 pxa2xx_cpll_change(&pxa25x_freqs[i], mdrefr_dri, clk_regs + CCCR);
248
249 return 0;
250}
251PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" };
252RATE_OPS(clk_pxa25x_cpll, "cpll");
253
254static void __init pxa25x_register_core(void)
255{

--- 60 unchanged lines hidden (view full) ---

316 for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
317 d = &dummy_clks[i];
318 name = d->dev_id ? d->dev_id : d->con_id;
319 clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
320 clk_register_clkdev(clk, d->con_id, d->dev_id);
321 }
322}
323
249
250 return 0;
251}
252PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" };
253RATE_OPS(clk_pxa25x_cpll, "cpll");
254
255static void __init pxa25x_register_core(void)
256{

--- 60 unchanged lines hidden (view full) ---

317 for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
318 d = &dummy_clks[i];
319 name = d->dev_id ? d->dev_id : d->con_id;
320 clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
321 clk_register_clkdev(clk, d->con_id, d->dev_id);
322 }
323}
324
324int __init pxa25x_clocks_init(void)
325int __init pxa25x_clocks_init(void __iomem *regs)
325{
326{
327 clk_regs = regs;
326 pxa25x_base_clocks_init();
327 pxa25x_dummy_clocks_init();
328 pxa25x_base_clocks_init();
329 pxa25x_dummy_clocks_init();
328 return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks));
330 return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks), clk_regs);
329}
330
331static void __init pxa25x_dt_clocks_init(struct device_node *np)
332{
331}
332
333static void __init pxa25x_dt_clocks_init(struct device_node *np)
334{
333 pxa25x_clocks_init();
335 pxa25x_clocks_init(ioremap(0x41300000ul, 0x10));
334 clk_pxa_dt_common_init(np);
335}
336CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks",
337 pxa25x_dt_clocks_init);
336 clk_pxa_dt_common_init(np);
337}
338CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks",
339 pxa25x_dt_clocks_init);