1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12#include "../../arch/arm/clock.h"
13#include "../../mach/exynos/clock.h"
14#if defined(CONFIG_PLAT_EXYNOS5422)
15#include "exynos_5422_clock.h"
16#else
17#include "exynos_common_clock.h"
18#endif
19#include "../../services.h"
20#include <assert.h>
21#include <string.h>
22#include <utils/util.h>
23
24#define EXYNOS5_CMU_CPU_PADDR   0x10010000
25#define EXYNOS5_CMU_CORE_PADDR  0x10014000
26#define EXYNOS5_CMU_ACP_PADDR   0x10018000
27#define EXYNOS5_CMU_ISP_PADDR   0x1001C000
28#define EXYNOS5_CMU_TOP_PADDR   0x10020000
29#define EXYNOS5_CMU_LEX_PADDR   0x10024000
30#define EXYNOS5_CMU_R0X_PADDR   0x10028000
31#define EXYNOS5_CMU_R1X_PADDR   0x1002C000
32#define EXYNOS5_CMU_CDREX_PADDR 0x10030000
33#define EXYNOS5_CMU_MEM_PADDR   0x10038000
34
35#define EXYNOS5_CMU_SIZE       0x1000
36#define EXYNOS5_CMU_CPU_SIZE    EXYNOS5_CMU_SIZE
37#define EXYNOS5_CMU_CORE_SIZE   EXYNOS5_CMU_SIZE
38#define EXYNOS5_CMU_ACP_SIZE    EXYNOS5_CMU_SIZE
39#define EXYNOS5_CMU_ISP_SIZE    EXYNOS5_CMU_SIZE
40#define EXYNOS5_CMU_TOP_SIZE    EXYNOS5_CMU_SIZE
41#define EXYNOS5_CMU_LEX_SIZE    EXYNOS5_CMU_SIZE
42#define EXYNOS5_CMU_R0X_SIZE    EXYNOS5_CMU_SIZE
43#define EXYNOS5_CMU_R1X_SIZE    EXYNOS5_CMU_SIZE
44#define EXYNOS5_CMU_CDREX_SIZE  EXYNOS5_CMU_SIZE
45#define EXYNOS5_CMU_MEM_SIZE    EXYNOS5_CMU_SIZE
46
47#define CLKID_UART0      CLKID(TOP, 20, 0)
48#define CLKID_UART1      CLKID(TOP, 20, 1)
49#define CLKID_UART2      CLKID(TOP, 20, 2)
50#define CLKID_UART3      CLKID(TOP, 20, 3)
51#define CLKID_PWM        CLKID(TOP, 20, 5)
52#define CLKID_SPI0       CLKID(TOP, 21, 4)
53#define CLKID_SPI1       CLKID(TOP, 21, 5)
54#define CLKID_SPI2       CLKID(TOP, 21, 6)
55#define CLKID_SPI0_ISP   CLKID(TOP, 28, 0)
56#define CLKID_SPI1_ISP   CLKID(TOP, 28, 1)
57
58volatile struct clk_regs* _clk_regs[NCLKREGS];
59
60static struct clock master_clk = { CLK_OPS(MASTER, default_clk, NULL) };
61
62static struct mpsk_tbl _ambcgpll_tbl[] = {
63    {  200, PLL_MPS( 100,  3, 2), 0 },
64    {  333, PLL_MPS( 222,  4, 2), 0 },
65    {  400, PLL_MPS( 100,  3, 1), 0 },
66    {  533, PLL_MPS( 533, 12, 1), 0 },
67    {  600, PLL_MPS( 200,  4, 1), 0 },
68    {  667, PLL_MPS( 389,  7, 1), 0 },
69    {  800, PLL_MPS( 100,  3, 0), 0 },
70    { 1000, PLL_MPS( 125,  3, 0), 0 },
71    { 1066, PLL_MPS( 533, 12, 0), 0 },
72    { 1200, PLL_MPS( 150,  3, 0), 0 },
73    { 1400, PLL_MPS( 175,  3, 0), 0 },
74    { 1600, PLL_MPS( 200,  3, 0), 0 }
75};
76
77static struct mpsk_tbl _epll_tbl[] = {
78    {  33, PLL_MPS( 131, 3, 5),  4719 },
79    {  45, PLL_MPS(  90, 3, 4), 20762 },
80    {  48, PLL_MPS(  64, 2, 4),     0 },
81    {  49, PLL_MPS(  98, 3, 4), 19923 },
82    {  50, PLL_MPS(  67, 2, 4), 43691 },
83    {  68, PLL_MPS(  90, 2, 4), 20762 },
84    {  74, PLL_MPS(  98, 2, 4), 19923 },
85    {  80, PLL_MPS( 107, 2, 4), 43691 },
86    {  84, PLL_MPS( 112, 2, 4),     0 },
87    {  96, PLL_MPS(  64, 2, 3),     0 },
88    { 144, PLL_MPS(  96, 2, 3),     0 },
89    { 192, PLL_MPS(  64, 2, 2),     0 },
90    { 288, PLL_MPS(  96, 2, 2),     0 },
91};
92
93static struct mpsk_tbl _vpll_tbl[] = {
94    {  27, PLL_MPS(  72, 2, 5),     0 },
95    {  54, PLL_MPS(  72, 2, 4),     0 },
96    {  74, PLL_MPS(  99, 2, 4),     0 },
97    { 108, PLL_MPS(  72, 2, 3),     0 },
98    { 148, PLL_MPS(  99, 2, 3), 59070 },
99    { 149, PLL_MPS(  99, 2, 3),     0 },
100    { 223, PLL_MPS(  74, 2, 2), 16384 },
101    { 300, PLL_MPS( 100, 2, 2),     0 },
102    { 320, PLL_MPS( 107, 2, 2), 43691 },
103    { 330, PLL_MPS( 110, 2, 2),     0 },
104    { 333, PLL_MPS( 111, 2, 2),     0 },
105    { 335, PLL_MPS( 112, 2, 2), 43691 },
106    { 371, PLL_MPS(  62, 2, 1), 53292 },
107    { 445, PLL_MPS( 111, 3, 1), 17285 },
108    { 446, PLL_MPS(  74, 2, 1), 16384 },
109    { 519, PLL_MPS( 130, 3, 1), 52937 },
110    { 600, PLL_MPS( 100, 2, 1),     0 },
111};
112
113static struct pll_priv sclkmpll_priv = PLL_PRIV(SCLKMPLL, MPS, _ambcgpll_tbl);
114static struct pll_priv sclkcpll_priv = PLL_PRIV(SCLKCPLL, MPS, _ambcgpll_tbl);
115
116static struct pll_priv sclkepll_priv = PLL_PRIV(SCLKEPLL, MPSK, _epll_tbl);
117static struct pll_priv sclkvpll_priv = PLL_PRIV(SCLKVPLL, MPSK, _vpll_tbl);
118
119static struct clock sclkmpll_clk  = { CLK_OPS(SCLKMPLL, pll, &sclkmpll_priv) };
120static struct clock sclkcpll_clk  = { CLK_OPS(SCLKCPLL, pll, &sclkcpll_priv) };
121static struct clock sclkepll_clk  = { CLK_OPS(SCLKEPLL, pll, &sclkepll_priv) };
122static struct clock sclkvpll_clk  = { CLK_OPS(SCLKVPLL, pll, &sclkvpll_priv) };
123
124#if !defined(CONFIG_PLAT_EXYNOS5422)
125static struct pll_priv sclkbpll_priv = PLL_PRIV(SCLKBPLL, MPS, _ambcgpll_tbl);
126static struct pll_priv sclkgpll_priv = PLL_PRIV(SCLKGPLL, MPS, _ambcgpll_tbl);
127
128static struct clock sclkgpll_clk  = { CLK_OPS(SCLKGPLL, pll, &sclkgpll_priv) };
129static struct clock sclkbpll_clk  = { CLK_OPS(SCLKBPLL, pll, &sclkbpll_priv) };
130#endif
131
132/* The SPI div register is a special case as we have 2 dividers, one of which
133 * is 2 nibbles wide */
134static freq_t
135_spi_get_freq(clk_t* clk)
136{
137    freq_t fin;
138    int clkid;
139    int rpre, r;
140    clkid = exynos_clk_get_priv_id(clk);
141    switch (clk->id) {
142    case CLK_SPI0_ISP:
143        clkid += 32;
144        break;
145    case CLK_SPI1_ISP:
146        clkid += 35;
147        break;
148    case CLK_SPI0:
149        clkid += 12;
150        break;
151    case CLK_SPI1:
152        clkid += 15;
153        break;
154    case CLK_SPI2:
155        clkid += 18;
156        break;
157    default:
158        return 0;
159    }
160    r = exynos_cmu_get_div(_clk_regs, clkid, 1);
161    rpre = exynos_cmu_get_div(_clk_regs, clkid + 2, 2);
162    fin = clk_get_freq(clk->parent);
163    return fin / (r + 1) / (rpre + 1);
164}
165
166static freq_t
167_spi_set_freq(clk_t* clk, freq_t hz)
168{
169    freq_t fin;
170    int clkid;
171    int rpre, r;
172    clkid = exynos_clk_get_priv_id(clk);
173    switch (clk->id) {
174    case CLK_SPI0_ISP:
175        clkid += 32;
176        break;
177    case CLK_SPI1_ISP:
178        clkid += 35;
179        break;
180    case CLK_SPI0:
181        clkid += 12;
182        break;
183    case CLK_SPI1:
184        clkid += 15;
185        break;
186    case CLK_SPI2:
187        clkid += 18;
188        break;
189    default:
190        return 0;
191    }
192    fin = clk_get_freq(clk->parent);
193    rpre = fin / 0xf / hz;
194    r = fin / (rpre + 1) / hz;
195    exynos_cmu_set_div(_clk_regs, clkid, 1, r);
196    exynos_cmu_set_div(_clk_regs, clkid + 2, 2, rpre);
197    return clk_get_freq(clk);
198}
199
200static void
201_spi_recal(clk_t* clk)
202{
203    assert(!"Not implemented");
204}
205
206static clk_t*
207_spi_init(clk_t* clk)
208{
209    /* MUX -> DIVspix -> DIVspipre */
210    clk_t* parent;
211    int clkid;
212    int src;
213    clkid = exynos_clk_get_priv_id(clk);
214    src = exynos_cmu_get_src(_clk_regs, clkid);
215    assert(src < ARRAY_SIZE(clk_src_peri_blk) && src >= 0);
216    assert(clk_src_peri_blk[src] != -1);
217    parent = clk_get_clock(clk->clk_sys, clk_src_peri_blk[src]);
218    assert(parent);
219    clk_init(parent);
220    clk_register_child(parent, clk);
221    return clk;
222}
223
224static struct clock spi0_clk     = { CLK_OPS(SPI0    , spi, CLKID_SPI0    ) };
225static struct clock spi1_clk     = { CLK_OPS(SPI1    , spi, CLKID_SPI1    ) };
226static struct clock spi2_clk     = { CLK_OPS(SPI2    , spi, CLKID_SPI2    ) };
227static struct clock spi0_isp_clk = { CLK_OPS(SPI0_ISP, spi, CLKID_SPI0_ISP) };
228static struct clock spi1_isp_clk = { CLK_OPS(SPI1_ISP, spi, CLKID_SPI1_ISP) };
229
230static freq_t
231_peric_clk_get_freq(clk_t* clk)
232{
233    freq_t fin;
234    int clkid;
235    int div;
236    clkid = exynos_clk_get_priv_id(clk);
237    /* The DIV register has an additional 2 word offset */
238    clkid += 16;
239    div = exynos_cmu_get_div(_clk_regs, clkid, 1);
240    fin = clk_get_freq(clk->parent);
241    return fin / (div + 1);
242}
243
244static freq_t
245_peric_clk_set_freq(clk_t* clk, freq_t hz)
246{
247    freq_t fin;
248    int clkid;
249    int div;
250    fin = clk_get_freq(clk->parent);
251    div = fin / hz;
252    clkid = exynos_clk_get_priv_id(clk);
253    /* The DIV register has an additional 2 word offset */
254    clkid += 16;
255    exynos_cmu_set_div(_clk_regs, clkid, 1, div);
256    return clk_get_freq(clk);
257}
258
259static void
260_peric_clk_recal(clk_t* clk)
261{
262    assert(!"Not implemented");
263}
264
265static clk_t*
266_peric_clk_init(clk_t* clk)
267{
268    /* MUX -> DIVuartx -> DIVuartpre */
269    clk_t* parent;
270    int clkid;
271    int src;
272    clkid = exynos_clk_get_priv_id(clk);
273    src = exynos_cmu_get_src(_clk_regs, clkid);
274    assert(src < ARRAY_SIZE(clk_src_peri_blk) && src >= 0);
275    assert(clk_src_peri_blk[src] != -1);
276    parent = clk_get_clock(clk->clk_sys, clk_src_peri_blk[src]);
277    assert(parent);
278    clk_init(parent);
279    clk_register_child(parent, clk);
280    return clk;
281}
282
283static struct clock uart0_clk = { CLK_OPS(UART0, peric_clk, CLKID_UART0) };
284static struct clock uart1_clk = { CLK_OPS(UART1, peric_clk, CLKID_UART1) };
285static struct clock uart2_clk = { CLK_OPS(UART2, peric_clk, CLKID_UART2) };
286static struct clock uart3_clk = { CLK_OPS(UART3, peric_clk, CLKID_UART3) };
287static struct clock pwm_clk   = { CLK_OPS(PWM  , peric_clk, CLKID_PWM  ) };
288
289static int
290exynos5_gate_enable(clock_sys_t* clock_sys, enum clock_gate gate, enum clock_gate_mode mode)
291{
292    return -1;
293}
294
295static int
296clock_sys_common_init(clock_sys_t* clock_sys)
297{
298    clock_sys->priv = (void*)&_clk_regs;
299    clock_sys->get_clock = &ps_get_clock;
300    clock_sys->gate_enable = &exynos5_gate_enable;
301    return 0;
302}
303
304int
305exynos5_clock_sys_init(void* cpu, void* core, void* acp, void* isp, void* top,
306                       void* lex, void* r0x,  void* r1x, void* cdrex, void* mem,
307                       clock_sys_t* clock_sys)
308{
309    if (cpu) {
310        _clk_regs[CLKREGS_CPU]   = cpu;
311    }
312    if (core) {
313        _clk_regs[CLKREGS_CORE]  = core;
314    }
315    if (acp) {
316        _clk_regs[CLKREGS_ACP]   = acp;
317    }
318    if (isp) {
319        _clk_regs[CLKREGS_ISP]   = isp;
320    }
321    if (top) {
322        _clk_regs[CLKREGS_TOP]   = top;
323    }
324    if (lex) {
325        _clk_regs[CLKREGS_LEX]   = lex;
326    }
327    if (r0x) {
328        _clk_regs[CLKREGS_R0X]   = r0x;
329    }
330    if (r1x) {
331        _clk_regs[CLKREGS_R1X]   = r1x;
332    }
333    if (cdrex) {
334        _clk_regs[CLKREGS_CDREX] = cdrex;
335    }
336    if (mem) {
337        _clk_regs[CLKREGS_MEM] = mem;
338    }
339    return clock_sys_common_init(clock_sys);
340}
341
342int
343clock_sys_init(ps_io_ops_t* o, clock_sys_t* clock_sys)
344{
345    MAP_IF_NULL(o, EXYNOS5_CMU_CPU,   _clk_regs[CLKREGS_CPU]);
346    MAP_IF_NULL(o, EXYNOS5_CMU_CORE,  _clk_regs[CLKREGS_CORE]);
347    MAP_IF_NULL(o, EXYNOS5_CMU_ACP,   _clk_regs[CLKREGS_ACP]);
348    MAP_IF_NULL(o, EXYNOS5_CMU_ISP,   _clk_regs[CLKREGS_ISP]);
349    MAP_IF_NULL(o, EXYNOS5_CMU_TOP,   _clk_regs[CLKREGS_TOP]);
350    MAP_IF_NULL(o, EXYNOS5_CMU_LEX,   _clk_regs[CLKREGS_LEX]);
351    MAP_IF_NULL(o, EXYNOS5_CMU_R0X,   _clk_regs[CLKREGS_R0X]);
352    MAP_IF_NULL(o, EXYNOS5_CMU_R1X,   _clk_regs[CLKREGS_R1X]);
353    MAP_IF_NULL(o, EXYNOS5_CMU_CDREX, _clk_regs[CLKREGS_CDREX]);
354    return clock_sys_common_init(clock_sys);
355}
356
357void
358clk_print_clock_tree(clock_sys_t* sys)
359{
360    (void)sys;
361    clk_t* clk = ps_clocks[CLK_MASTER];
362    clk_print_tree(clk, "");
363}
364
365clk_t* ps_clocks[] = {
366    [CLK_MASTER  ]   = &master_clk,
367    [CLK_SPI0    ]   = &spi0_clk,
368    [CLK_SPI1    ]   = &spi1_clk,
369    [CLK_SPI2    ]   = &spi2_clk,
370    [CLK_SPI0_ISP]   = &spi0_isp_clk,
371    [CLK_SPI1_ISP]   = &spi1_isp_clk,
372    [CLK_UART0   ]   = &uart0_clk,
373    [CLK_UART1   ]   = &uart1_clk,
374    [CLK_UART2   ]   = &uart2_clk,
375    [CLK_UART3   ]   = &uart3_clk,
376    [CLK_PWM     ]   = &pwm_clk,
377    [CLK_SCLKMPLL]   = &sclkmpll_clk,
378    [CLK_SCLKCPLL]   = &sclkcpll_clk,
379    [CLK_SCLKEPLL]   = &sclkepll_clk,
380    [CLK_SCLKVPLL]   = &sclkvpll_clk,
381#if !defined(CONFIG_PLAT_EXYNOS5422)
382    [CLK_SCLKBPLL]   = &sclkbpll_clk,
383    [CLK_SCLKGPLL]   = &sclkgpll_clk,
384#endif
385};
386
387/* These frequencies are NOT the recommended
388 * frequencies. They are to be used when we
389 * need to make assumptions about what u-boot
390 * has left us with. */
391freq_t ps_freq_default[] = {
392    [CLK_MASTER  ]   =    24 * MHZ,
393    [CLK_SCLKVPLL]   =    24 * MHZ,
394    [CLK_SCLKGPLL]   =  1056 * MHZ,
395    [CLK_SCLKBPLL]   =   800 * MHZ,
396    [CLK_PWM     ]   =    24 * MHZ,
397    [CLK_SCLKCPLL]   =   640 * MHZ,
398    [CLK_UART3   ]   =    64 * MHZ,
399    [CLK_UART2   ]   =    64 * MHZ,
400    [CLK_UART1   ]   =    64 * MHZ,
401    [CLK_UART0   ]   =    64 * MHZ,
402    [CLK_SPI1_ISP]   =    24 * MHZ,
403    [CLK_SPI0_ISP]   =    24 * MHZ,
404    [CLK_SCLKMPLL]   =   532 * MHZ,
405    [CLK_SPI1    ]   = 53200 * KHZ,
406    [CLK_SCLKEPLL]   =    24 * MHZ,
407    [CLK_SPI2    ]   =     6 * MHZ,
408    [CLK_SPI0    ]   =     6 * MHZ,
409};
410