1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2fe7710faSRobert Jarzmik /*
3fe7710faSRobert Jarzmik * Marvell PXA25x family clocks
4fe7710faSRobert Jarzmik *
5fe7710faSRobert Jarzmik * Copyright (C) 2014 Robert Jarzmik
6fe7710faSRobert Jarzmik *
7fe7710faSRobert Jarzmik * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c.
8fe7710faSRobert Jarzmik *
9fe7710faSRobert Jarzmik * For non-devicetree platforms. Once pxa is fully converted to devicetree, this
10fe7710faSRobert Jarzmik * should go away.
11fe7710faSRobert Jarzmik */
12fe7710faSRobert Jarzmik #include <linux/clk-provider.h>
13fe7710faSRobert Jarzmik #include <linux/clk.h>
14*a9ae9c52SArnd Bergmann #include <linux/clk/pxa.h>
15fe7710faSRobert Jarzmik #include <linux/clkdev.h>
16fe7710faSRobert Jarzmik #include <linux/io.h>
17fe7710faSRobert Jarzmik #include <linux/of.h>
18fd13f811SArnd Bergmann #include <linux/soc/pxa/smemc.h>
19*a9ae9c52SArnd Bergmann #include <linux/soc/pxa/cpu.h>
20fe7710faSRobert Jarzmik
21fe7710faSRobert Jarzmik #include <dt-bindings/clock/pxa-clock.h>
22fe7710faSRobert Jarzmik #include "clk-pxa.h"
233c816d95SArnd Bergmann #include "clk-pxa2xx.h"
24fe7710faSRobert Jarzmik
25fe7710faSRobert Jarzmik #define KHz 1000
26fe7710faSRobert Jarzmik #define MHz (1000 * 1000)
27fe7710faSRobert Jarzmik
28fe7710faSRobert Jarzmik enum {
29fe7710faSRobert Jarzmik PXA_CORE_RUN = 0,
30fe7710faSRobert Jarzmik PXA_CORE_TURBO,
31fe7710faSRobert Jarzmik };
32fe7710faSRobert Jarzmik
339fe69429SRobert Jarzmik #define PXA25x_CLKCFG(T) \
349fe69429SRobert Jarzmik (CLKCFG_FCS | \
359fe69429SRobert Jarzmik ((T) ? CLKCFG_TURBO : 0))
369fe69429SRobert Jarzmik #define PXA25x_CCCR(N2, M, L) (N2 << 7 | M << 5 | L)
379fe69429SRobert Jarzmik
389fe69429SRobert Jarzmik /* Define the refresh period in mSec for the SDRAM and the number of rows */
399fe69429SRobert Jarzmik #define SDRAM_TREF 64 /* standard 64ms SDRAM */
409fe69429SRobert Jarzmik
41fe7710faSRobert Jarzmik /*
42fe7710faSRobert Jarzmik * Various clock factors driven by the CCCR register.
43fe7710faSRobert Jarzmik */
443c816d95SArnd Bergmann static void __iomem *clk_regs;
45fe7710faSRobert Jarzmik
46fe7710faSRobert Jarzmik /* Crystal Frequency to Memory Frequency Multiplier (L) */
47fe7710faSRobert Jarzmik static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
48fe7710faSRobert Jarzmik
49fe7710faSRobert Jarzmik /* Memory Frequency to Run Mode Frequency Multiplier (M) */
50fe7710faSRobert Jarzmik static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
51fe7710faSRobert Jarzmik
52fe7710faSRobert Jarzmik /* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
53fe7710faSRobert Jarzmik /* Note: we store the value N * 2 here. */
54fe7710faSRobert Jarzmik static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
55fe7710faSRobert Jarzmik
56fe7710faSRobert Jarzmik static const char * const get_freq_khz[] = {
57fe7710faSRobert Jarzmik "core", "run", "cpll", "memory"
58fe7710faSRobert Jarzmik };
59fe7710faSRobert Jarzmik
mdrefr_dri(unsigned int freq_khz)609fe69429SRobert Jarzmik static u32 mdrefr_dri(unsigned int freq_khz)
619fe69429SRobert Jarzmik {
62fd13f811SArnd Bergmann u32 interval = freq_khz * SDRAM_TREF / pxa2xx_smemc_get_sdram_rows();
639fe69429SRobert Jarzmik
649fe69429SRobert Jarzmik return interval / 32;
659fe69429SRobert Jarzmik }
669fe69429SRobert Jarzmik
67fe7710faSRobert Jarzmik /*
68fe7710faSRobert Jarzmik * Get the clock frequency as reflected by CCCR and the turbo flag.
69fe7710faSRobert Jarzmik * We assume these values have been applied via a fcs.
70fe7710faSRobert Jarzmik * If info is not 0 we also display the current settings.
71fe7710faSRobert Jarzmik */
pxa25x_get_clk_frequency_khz(int info)72fe7710faSRobert Jarzmik unsigned int pxa25x_get_clk_frequency_khz(int info)
73fe7710faSRobert Jarzmik {
74fe7710faSRobert Jarzmik struct clk *clk;
75fe7710faSRobert Jarzmik unsigned long clks[5];
76fe7710faSRobert Jarzmik int i;
77fe7710faSRobert Jarzmik
78fe7710faSRobert Jarzmik for (i = 0; i < ARRAY_SIZE(get_freq_khz); i++) {
79fe7710faSRobert Jarzmik clk = clk_get(NULL, get_freq_khz[i]);
80fe7710faSRobert Jarzmik if (IS_ERR(clk)) {
81fe7710faSRobert Jarzmik clks[i] = 0;
82fe7710faSRobert Jarzmik } else {
83fe7710faSRobert Jarzmik clks[i] = clk_get_rate(clk);
84fe7710faSRobert Jarzmik clk_put(clk);
85fe7710faSRobert Jarzmik }
86fe7710faSRobert Jarzmik }
87fe7710faSRobert Jarzmik
88fe7710faSRobert Jarzmik if (info) {
89fe7710faSRobert Jarzmik pr_info("Run Mode clock: %ld.%02ldMHz\n",
90fe7710faSRobert Jarzmik clks[1] / 1000000, (clks[1] % 1000000) / 10000);
91fe7710faSRobert Jarzmik pr_info("Turbo Mode clock: %ld.%02ldMHz\n",
92fe7710faSRobert Jarzmik clks[2] / 1000000, (clks[2] % 1000000) / 10000);
93fe7710faSRobert Jarzmik pr_info("Memory clock: %ld.%02ldMHz\n",
94fe7710faSRobert Jarzmik clks[3] / 1000000, (clks[3] % 1000000) / 10000);
95fe7710faSRobert Jarzmik }
96fe7710faSRobert Jarzmik
974b5fb7dcSRobert Jarzmik return (unsigned int)clks[0] / KHz;
98fe7710faSRobert Jarzmik }
99fe7710faSRobert Jarzmik
clk_pxa25x_memory_get_rate(struct clk_hw * hw,unsigned long parent_rate)100fe7710faSRobert Jarzmik static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw,
101fe7710faSRobert Jarzmik unsigned long parent_rate)
102fe7710faSRobert Jarzmik {
1033c816d95SArnd Bergmann unsigned long cccr = readl(clk_regs + CCCR);
104fe7710faSRobert Jarzmik unsigned int m = M_clk_mult[(cccr >> 5) & 0x03];
105fe7710faSRobert Jarzmik
106fe7710faSRobert Jarzmik return parent_rate / m;
107fe7710faSRobert Jarzmik }
108fe7710faSRobert Jarzmik PARENTS(clk_pxa25x_memory) = { "run" };
109fe7710faSRobert Jarzmik RATE_RO_OPS(clk_pxa25x_memory, "memory");
110fe7710faSRobert Jarzmik
111fe7710faSRobert Jarzmik PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" };
112fe7710faSRobert Jarzmik PARENTS(pxa25x_pbus147) = { "ppll_147_46mhz", "ppll_147_46mhz" };
113fe7710faSRobert Jarzmik PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" };
114fe7710faSRobert Jarzmik
115fe7710faSRobert Jarzmik #define PXA25X_CKEN(dev_id, con_id, parents, mult, div, \
116fe7710faSRobert Jarzmik bit, is_lp, flags) \
117fe7710faSRobert Jarzmik PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div, \
118ea7743e2SArnd Bergmann is_lp, CKEN, CKEN_ ## bit, flags)
119fe7710faSRobert Jarzmik #define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \
120fe7710faSRobert Jarzmik PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp, \
121fe7710faSRobert Jarzmik div_hp, bit, NULL, 0)
122fe7710faSRobert Jarzmik #define PXA25X_PBUS147_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)\
123fe7710faSRobert Jarzmik PXA25X_CKEN(dev_id, con_id, pxa25x_pbus147_parents, mult_hp, \
124fe7710faSRobert Jarzmik div_hp, bit, NULL, 0)
125fe7710faSRobert Jarzmik #define PXA25X_OSC3_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \
126fe7710faSRobert Jarzmik PXA25X_CKEN(dev_id, con_id, pxa25x_osc3_parents, mult_hp, \
127fe7710faSRobert Jarzmik div_hp, bit, NULL, 0)
128fe7710faSRobert Jarzmik
129fe7710faSRobert Jarzmik #define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \
130fe7710faSRobert Jarzmik PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
131ea7743e2SArnd Bergmann CKEN, CKEN_ ## bit, 0)
132fe7710faSRobert Jarzmik #define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \
133fe7710faSRobert Jarzmik PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \
134ea7743e2SArnd Bergmann CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
135fe7710faSRobert Jarzmik
136fe7710faSRobert Jarzmik static struct desc_clk_cken pxa25x_clocks[] __initdata = {
137fe7710faSRobert Jarzmik PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0),
138fe7710faSRobert Jarzmik PXA25X_PBUS95_CKEN("pxa2xx-i2c.0", NULL, I2C, 1, 3, 0),
139fe7710faSRobert Jarzmik PXA25X_PBUS95_CKEN("pxa2xx-ir", "FICPCLK", FICP, 1, 2, 0),
140fe7710faSRobert Jarzmik PXA25X_PBUS95_CKEN("pxa25x-udc", NULL, USB, 1, 2, 5),
141fe7710faSRobert Jarzmik PXA25X_PBUS147_CKEN("pxa2xx-uart.0", NULL, FFUART, 1, 10, 1),
142fe7710faSRobert Jarzmik PXA25X_PBUS147_CKEN("pxa2xx-uart.1", NULL, BTUART, 1, 10, 1),
143fe7710faSRobert Jarzmik PXA25X_PBUS147_CKEN("pxa2xx-uart.2", NULL, STUART, 1, 10, 1),
144fe7710faSRobert Jarzmik PXA25X_PBUS147_CKEN("pxa2xx-uart.3", NULL, HWUART, 1, 10, 1),
145fe7710faSRobert Jarzmik PXA25X_PBUS147_CKEN("pxa2xx-i2s", NULL, I2S, 1, 10, 0),
146fe7710faSRobert Jarzmik PXA25X_PBUS147_CKEN(NULL, "AC97CLK", AC97, 1, 12, 0),
147fe7710faSRobert Jarzmik PXA25X_OSC3_CKEN("pxa25x-ssp.0", NULL, SSP, 1, 1, 0),
148fe7710faSRobert Jarzmik PXA25X_OSC3_CKEN("pxa25x-nssp.1", NULL, NSSP, 1, 1, 0),
149fe7710faSRobert Jarzmik PXA25X_OSC3_CKEN("pxa25x-nssp.2", NULL, ASSP, 1, 1, 0),
150fe7710faSRobert Jarzmik PXA25X_OSC3_CKEN("pxa25x-pwm.0", NULL, PWM0, 1, 1, 0),
151fe7710faSRobert Jarzmik PXA25X_OSC3_CKEN("pxa25x-pwm.1", NULL, PWM1, 1, 1, 0),
152fe7710faSRobert Jarzmik
153fe7710faSRobert Jarzmik PXA25X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, clk_pxa25x_memory_parents, 0),
154fe7710faSRobert Jarzmik PXA25X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC,
155fe7710faSRobert Jarzmik clk_pxa25x_memory_parents, 0),
156fe7710faSRobert Jarzmik };
157fe7710faSRobert Jarzmik
1589fe69429SRobert Jarzmik /*
1599fe69429SRobert Jarzmik * In this table, PXA25x_CCCR(N2, M, L) has the following meaning, where :
1609fe69429SRobert Jarzmik * - freq_cpll = n * m * L * 3.6864 MHz
1619fe69429SRobert Jarzmik * - n = N2 / 2
1629fe69429SRobert Jarzmik * - m = 2^(M - 1), where 1 <= M <= 3
1639fe69429SRobert Jarzmik * - l = L_clk_mult[L], ie. { 0, 27, 32, 36, 40, 45, 0, }[L]
1649fe69429SRobert Jarzmik */
1659fe69429SRobert Jarzmik static struct pxa2xx_freq pxa25x_freqs[] = {
1669fe69429SRobert Jarzmik /* CPU MEMBUS CCCR DIV2 CCLKCFG */
1679fe69429SRobert Jarzmik { 99532800, 99500, PXA25x_CCCR(2, 1, 1), 1, PXA25x_CLKCFG(1)},
1689fe69429SRobert Jarzmik {199065600, 99500, PXA25x_CCCR(4, 1, 1), 0, PXA25x_CLKCFG(1)},
1699fe69429SRobert Jarzmik {298598400, 99500, PXA25x_CCCR(3, 2, 1), 0, PXA25x_CLKCFG(1)},
1709fe69429SRobert Jarzmik {398131200, 99500, PXA25x_CCCR(4, 2, 1), 0, PXA25x_CLKCFG(1)},
1719fe69429SRobert Jarzmik };
1729fe69429SRobert Jarzmik
clk_pxa25x_core_get_parent(struct clk_hw * hw)173fe7710faSRobert Jarzmik static u8 clk_pxa25x_core_get_parent(struct clk_hw *hw)
174fe7710faSRobert Jarzmik {
175fe7710faSRobert Jarzmik unsigned long clkcfg;
176fe7710faSRobert Jarzmik unsigned int t;
177fe7710faSRobert Jarzmik
178fe7710faSRobert Jarzmik asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
179fe7710faSRobert Jarzmik t = clkcfg & (1 << 0);
180fe7710faSRobert Jarzmik if (t)
181fe7710faSRobert Jarzmik return PXA_CORE_TURBO;
182fe7710faSRobert Jarzmik return PXA_CORE_RUN;
183fe7710faSRobert Jarzmik }
184fe7710faSRobert Jarzmik
clk_pxa25x_core_set_parent(struct clk_hw * hw,u8 index)1859fe69429SRobert Jarzmik static int clk_pxa25x_core_set_parent(struct clk_hw *hw, u8 index)
186fe7710faSRobert Jarzmik {
1879fe69429SRobert Jarzmik if (index > PXA_CORE_TURBO)
1889fe69429SRobert Jarzmik return -EINVAL;
1899fe69429SRobert Jarzmik
1909fe69429SRobert Jarzmik pxa2xx_core_turbo_switch(index == PXA_CORE_TURBO);
1919fe69429SRobert Jarzmik
1929fe69429SRobert Jarzmik return 0;
193fe7710faSRobert Jarzmik }
1949fe69429SRobert Jarzmik
clk_pxa25x_core_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)1959fe69429SRobert Jarzmik static int clk_pxa25x_core_determine_rate(struct clk_hw *hw,
1969fe69429SRobert Jarzmik struct clk_rate_request *req)
1979fe69429SRobert Jarzmik {
1989fe69429SRobert Jarzmik return __clk_mux_determine_rate(hw, req);
1999fe69429SRobert Jarzmik }
2009fe69429SRobert Jarzmik
201fe7710faSRobert Jarzmik PARENTS(clk_pxa25x_core) = { "run", "cpll" };
2029fe69429SRobert Jarzmik MUX_OPS(clk_pxa25x_core, "core", CLK_SET_RATE_PARENT);
203fe7710faSRobert Jarzmik
clk_pxa25x_run_get_rate(struct clk_hw * hw,unsigned long parent_rate)204fe7710faSRobert Jarzmik static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw,
205fe7710faSRobert Jarzmik unsigned long parent_rate)
206fe7710faSRobert Jarzmik {
2073c816d95SArnd Bergmann unsigned long cccr = readl(clk_regs + CCCR);
208fe7710faSRobert Jarzmik unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07];
209fe7710faSRobert Jarzmik
210fe7710faSRobert Jarzmik return (parent_rate / n2) * 2;
211fe7710faSRobert Jarzmik }
212fe7710faSRobert Jarzmik PARENTS(clk_pxa25x_run) = { "cpll" };
213fe7710faSRobert Jarzmik RATE_RO_OPS(clk_pxa25x_run, "run");
214fe7710faSRobert Jarzmik
clk_pxa25x_cpll_get_rate(struct clk_hw * hw,unsigned long parent_rate)215fe7710faSRobert Jarzmik static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw,
216fe7710faSRobert Jarzmik unsigned long parent_rate)
217fe7710faSRobert Jarzmik {
2183c816d95SArnd Bergmann unsigned long clkcfg, cccr = readl(clk_regs + CCCR);
219fe7710faSRobert Jarzmik unsigned int l, m, n2, t;
220fe7710faSRobert Jarzmik
221fe7710faSRobert Jarzmik asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
222fe7710faSRobert Jarzmik t = clkcfg & (1 << 0);
223fe7710faSRobert Jarzmik l = L_clk_mult[(cccr >> 0) & 0x1f];
224fe7710faSRobert Jarzmik m = M_clk_mult[(cccr >> 5) & 0x03];
225fe7710faSRobert Jarzmik n2 = N2_clk_mult[(cccr >> 7) & 0x07];
226fe7710faSRobert Jarzmik
227fe7710faSRobert Jarzmik return m * l * n2 * parent_rate / 2;
228fe7710faSRobert Jarzmik }
2299fe69429SRobert Jarzmik
clk_pxa25x_cpll_determine_rate(struct clk_hw * hw,struct clk_rate_request * req)2309fe69429SRobert Jarzmik static int clk_pxa25x_cpll_determine_rate(struct clk_hw *hw,
2319fe69429SRobert Jarzmik struct clk_rate_request *req)
2329fe69429SRobert Jarzmik {
2339fe69429SRobert Jarzmik return pxa2xx_determine_rate(req, pxa25x_freqs,
2349fe69429SRobert Jarzmik ARRAY_SIZE(pxa25x_freqs));
2359fe69429SRobert Jarzmik }
2369fe69429SRobert Jarzmik
clk_pxa25x_cpll_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)2379fe69429SRobert Jarzmik static int clk_pxa25x_cpll_set_rate(struct clk_hw *hw, unsigned long rate,
2389fe69429SRobert Jarzmik unsigned long parent_rate)
2399fe69429SRobert Jarzmik {
2409fe69429SRobert Jarzmik int i;
2419fe69429SRobert Jarzmik
2429fe69429SRobert Jarzmik pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate);
2439fe69429SRobert Jarzmik for (i = 0; i < ARRAY_SIZE(pxa25x_freqs); i++)
2449fe69429SRobert Jarzmik if (pxa25x_freqs[i].cpll == rate)
2459fe69429SRobert Jarzmik break;
2469fe69429SRobert Jarzmik
2479fe69429SRobert Jarzmik if (i >= ARRAY_SIZE(pxa25x_freqs))
2489fe69429SRobert Jarzmik return -EINVAL;
2499fe69429SRobert Jarzmik
2503c816d95SArnd Bergmann pxa2xx_cpll_change(&pxa25x_freqs[i], mdrefr_dri, clk_regs + CCCR);
2519fe69429SRobert Jarzmik
2529fe69429SRobert Jarzmik return 0;
2539fe69429SRobert Jarzmik }
254fe7710faSRobert Jarzmik PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" };
2559fe69429SRobert Jarzmik RATE_OPS(clk_pxa25x_cpll, "cpll");
256fe7710faSRobert Jarzmik
pxa25x_register_core(void)257fe7710faSRobert Jarzmik static void __init pxa25x_register_core(void)
258fe7710faSRobert Jarzmik {
259fb16d9e5SRobert Jarzmik clkdev_pxa_register(CLK_NONE, "cpll", NULL,
260fb16d9e5SRobert Jarzmik clk_register_clk_pxa25x_cpll());
261fb16d9e5SRobert Jarzmik clkdev_pxa_register(CLK_NONE, "run", NULL,
262fb16d9e5SRobert Jarzmik clk_register_clk_pxa25x_run());
263fe7710faSRobert Jarzmik clkdev_pxa_register(CLK_CORE, "core", NULL,
264fe7710faSRobert Jarzmik clk_register_clk_pxa25x_core());
265fe7710faSRobert Jarzmik }
266fe7710faSRobert Jarzmik
pxa25x_register_plls(void)267fe7710faSRobert Jarzmik static void __init pxa25x_register_plls(void)
268fe7710faSRobert Jarzmik {
269fe7710faSRobert Jarzmik clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL,
2702c63935dSStephen Boyd CLK_GET_RATE_NOCACHE, 3686400);
271fc206543SRobert Jarzmik clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL,
272fe7710faSRobert Jarzmik clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
273fc206543SRobert Jarzmik CLK_GET_RATE_NOCACHE,
274fc206543SRobert Jarzmik 32768));
2752c63935dSStephen Boyd clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0);
276fe7710faSRobert Jarzmik clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz",
277fe7710faSRobert Jarzmik 0, 26, 1);
278fe7710faSRobert Jarzmik clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz",
279fe7710faSRobert Jarzmik 0, 40, 1);
280fe7710faSRobert Jarzmik }
281fe7710faSRobert Jarzmik
pxa25x_base_clocks_init(void)282fe7710faSRobert Jarzmik static void __init pxa25x_base_clocks_init(void)
283fe7710faSRobert Jarzmik {
284fe7710faSRobert Jarzmik pxa25x_register_plls();
285fe7710faSRobert Jarzmik pxa25x_register_core();
286fb16d9e5SRobert Jarzmik clkdev_pxa_register(CLK_NONE, "system_bus", NULL,
287fb16d9e5SRobert Jarzmik clk_register_clk_pxa25x_memory());
288fe7710faSRobert Jarzmik }
289fe7710faSRobert Jarzmik
290fe7710faSRobert Jarzmik #define DUMMY_CLK(_con_id, _dev_id, _parent) \
291fe7710faSRobert Jarzmik { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent }
292fe7710faSRobert Jarzmik struct dummy_clk {
293fe7710faSRobert Jarzmik const char *con_id;
294fe7710faSRobert Jarzmik const char *dev_id;
295fe7710faSRobert Jarzmik const char *parent;
296fe7710faSRobert Jarzmik };
297fe7710faSRobert Jarzmik static struct dummy_clk dummy_clks[] __initdata = {
298fe7710faSRobert Jarzmik DUMMY_CLK(NULL, "pxa25x-gpio", "osc_32_768khz"),
299fe7710faSRobert Jarzmik DUMMY_CLK(NULL, "pxa26x-gpio", "osc_32_768khz"),
300fe7710faSRobert Jarzmik DUMMY_CLK("GPIO11_CLK", NULL, "osc_3_6864mhz"),
301fe7710faSRobert Jarzmik DUMMY_CLK("GPIO12_CLK", NULL, "osc_32_768khz"),
302fe7710faSRobert Jarzmik DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
303a758c9b9SRussell King - ARM Linux DUMMY_CLK("OSTIMER0", NULL, "osc_3_6864mhz"),
304fe7710faSRobert Jarzmik DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
305fe7710faSRobert Jarzmik };
306fe7710faSRobert Jarzmik
pxa25x_dummy_clocks_init(void)307fe7710faSRobert Jarzmik static void __init pxa25x_dummy_clocks_init(void)
308fe7710faSRobert Jarzmik {
309fe7710faSRobert Jarzmik struct clk *clk;
310fe7710faSRobert Jarzmik struct dummy_clk *d;
311fe7710faSRobert Jarzmik const char *name;
312fe7710faSRobert Jarzmik int i;
313fe7710faSRobert Jarzmik
314fe7710faSRobert Jarzmik /*
315fe7710faSRobert Jarzmik * All pinctrl logic has been wiped out of the clock driver, especially
316fe7710faSRobert Jarzmik * for gpio11 and gpio12 outputs. Machine code should ensure proper pin
317fe7710faSRobert Jarzmik * control (ie. pxa2xx_mfp_config() invocation).
318fe7710faSRobert Jarzmik */
319fe7710faSRobert Jarzmik for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
320fe7710faSRobert Jarzmik d = &dummy_clks[i];
321fe7710faSRobert Jarzmik name = d->dev_id ? d->dev_id : d->con_id;
322fe7710faSRobert Jarzmik clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
323fe7710faSRobert Jarzmik clk_register_clkdev(clk, d->con_id, d->dev_id);
324fe7710faSRobert Jarzmik }
325fe7710faSRobert Jarzmik }
326fe7710faSRobert Jarzmik
pxa25x_clocks_init(void __iomem * regs)3273c816d95SArnd Bergmann int __init pxa25x_clocks_init(void __iomem *regs)
328fe7710faSRobert Jarzmik {
3293c816d95SArnd Bergmann clk_regs = regs;
330fe7710faSRobert Jarzmik pxa25x_base_clocks_init();
331fe7710faSRobert Jarzmik pxa25x_dummy_clocks_init();
3323c816d95SArnd Bergmann return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks), clk_regs);
333fe7710faSRobert Jarzmik }
334fe7710faSRobert Jarzmik
pxa25x_dt_clocks_init(struct device_node * np)335fe7710faSRobert Jarzmik static void __init pxa25x_dt_clocks_init(struct device_node *np)
336fe7710faSRobert Jarzmik {
3373c816d95SArnd Bergmann pxa25x_clocks_init(ioremap(0x41300000ul, 0x10));
338fe7710faSRobert Jarzmik clk_pxa_dt_common_init(np);
339fe7710faSRobert Jarzmik }
340fe7710faSRobert Jarzmik CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks",
341fe7710faSRobert Jarzmik pxa25x_dt_clocks_init);
342