1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2011-01-13     weety       first version
9  */
10 
11 #include <rtthread.h>
12 
13 /*
14 static rt_list_t clocks;
15 
16 struct clk {
17     char name[32];
18     rt_uint32_t rate_hz;
19     struct clk *parent;
20     rt_list_t  node;
21 };
22 
23 static struct clk clk32k = {
24     "clk32k",
25     AT91_SLOW_CLOCK,
26     RT_NULL,
27     {RT_NULL, RT_NULL},
28 };
29 
30 static struct clk main_clk = {
31     "main",
32     0,
33     RT_NULL,
34     {RT_NULL, RT_NULL},
35 };
36 
37 static struct clk plla = {
38     "plla",
39     0,
40     RT_NULL,
41     {RT_NULL, RT_NULL},
42 };
43 
44 static struct clk mck = {
45     "mck",
46     0,
47     RT_NULL,
48     {RT_NULL, RT_NULL},
49 };
50 
51 static struct clk uhpck = {
52     "uhpck",
53     0,
54     RT_NULL,
55     {RT_NULL, RT_NULL},
56 };
57 
58 static struct clk pllb = {
59     "pllb",
60     0,
61     &main_clk,
62     {RT_NULL, RT_NULL},
63 };
64 
65 static struct clk udpck = {
66     "udpck",
67     0,
68     &pllb,
69     {RT_NULL, RT_NULL},
70 };
71 
72 static struct clk *const standard_pmc_clocks[] = {
73     // four primary clocks
74     &clk32k,
75     &main_clk,
76     &plla,
77 
78     // MCK
79     &mck
80 };
81 
82 // clocks cannot be de-registered no refcounting necessary
83 struct clk *clk_get(const char *id)
84 {
85     struct clk *clk;
86     rt_list_t *list;
87 
88     for (list = (&clocks)->next; list != &clocks; list = list->next)
89     {
90         clk = (struct clk *)rt_list_entry(list, struct clk, node);
91         if (rt_strcmp(id, clk->name) == 0)
92             return clk;
93     }
94 
95     return RT_NULL;
96 }
97 
98 rt_uint32_t clk_get_rate(struct clk *clk)
99 {
100     rt_uint32_t rate;
101 
102     for (;;) {
103         rate = clk->rate_hz;
104         if (rate || !clk->parent)
105             break;
106         clk = clk->parent;
107     }
108     return rate;
109 }
110 
111 static rt_uint32_t at91_pll_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
112 {
113     unsigned mul, div;
114 
115     div = reg & 0xff;
116     mul = (reg >> 16) & 0x7ff;
117     if (div && mul) {
118         freq /= div;
119         freq *= mul + 1;
120     } else
121         freq = 0;
122 
123     return freq;
124 }
125 
126 static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq)
127 {
128     unsigned i, div = 0, mul = 0, diff = 1 << 30;
129     unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
130 
131     //PLL output max 240 MHz (or 180 MHz per errata)
132     if (out_freq > 240000000)
133         goto fail;
134 
135     for (i = 1; i < 256; i++) {
136         int diff1;
137         unsigned input, mul1;
138 
139         //
140         // PLL input between 1MHz and 32MHz per spec, but lower
141         // frequences seem necessary in some cases so allow 100K.
142         // Warning: some newer products need 2MHz min.
143         //
144         input = main_freq / i;
145         if (input < 100000)
146             continue;
147         if (input > 32000000)
148             continue;
149 
150         mul1 = out_freq / input;
151         if (mul1 > 2048)
152             continue;
153         if (mul1 < 2)
154             goto fail;
155 
156         diff1 = out_freq - input * mul1;
157         if (diff1 < 0)
158             diff1 = -diff1;
159         if (diff > diff1) {
160             diff = diff1;
161             div = i;
162             mul = mul1;
163             if (diff == 0)
164                 break;
165         }
166     }
167     if (i == 256 && diff > (out_freq >> 5))
168         goto fail;
169     return ret | ((mul - 1) << 16) | div;
170 fail:
171     return 0;
172 }
173 
174 static rt_uint32_t at91_usb_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
175 {
176     if (pll == &pllb && (reg & AT91_PMC_USB96M))
177         return freq / 2;
178     else
179         return freq;
180 }
181 
182 
183 // PLLB generated USB full speed clock init
184 static void at91_pllb_usbfs_clock_init(rt_uint32_t main_clock)
185 {
186     rt_uint32_t at91_pllb_usb_init;
187     //
188     // USB clock init:  choose 48 MHz PLLB value,
189     // disable 48MHz clock during usb peripheral suspend.
190     //
191     // REVISIT:  assumes MCK doesn't derive from PLLB!
192     //
193     uhpck.parent = &pllb;
194 
195     at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
196     pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
197 
198     at91_sys_write(AT91_CKGR_PLLBR, 0);
199 
200     udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
201     uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
202 }
203 
204 static struct clk *at91_css_to_clk(unsigned long css)
205 {
206     switch (css) {
207         case AT91_PMC_CSS_SLOW:
208             return &clk32k;
209         case AT91_PMC_CSS_MAIN:
210             return &main_clk;
211         case AT91_PMC_CSS_PLLA:
212             return &plla;
213         case AT91_PMC_CSS_PLLB:
214             return &pllb;
215     }
216 
217     return RT_NULL;
218 }
219 
220 #define false 0
221 #define true  1
222 int at91_clock_init(rt_uint32_t main_clock)
223 {
224     unsigned tmp, freq, mckr;
225     int i;
226     int pll_overclock = false;
227 
228     //
229     // When the bootloader initialized the main oscillator correctly,
230     // there's no problem using the cycle counter.  But if it didn't,
231     // or when using oscillator bypass mode, we must be told the speed
232      // of the main clock.
233     //
234     if (!main_clock) {
235         do {
236             tmp = at91_sys_read(AT91_CKGR_MCFR);
237         } while (!(tmp & AT91_PMC_MAINRDY));
238         main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
239     }
240     main_clk.rate_hz = main_clock;
241 
242     // report if PLLA is more than mildly overclocked
243     plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
244     if (plla.rate_hz > 209000000)
245         pll_overclock = true;
246     if (pll_overclock)
247         ;//rt_kprintf("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
248 
249     at91_pllb_usbfs_clock_init(main_clock);
250 
251     //
252      // MCK and CPU derive from one of those primary clocks.
253      // For now, assume this parentage won't change.
254      //
255     mckr = at91_sys_read(AT91_PMC_MCKR);
256     mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
257     freq = mck.parent->rate_hz;
258     freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2));               // prescale
259 
260     mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      // mdiv
261 
262     // Register the PMC's standard clocks
263     rt_list_init(&clocks);
264     for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
265         rt_list_insert_after(&clocks, &standard_pmc_clocks[i]->node);
266 
267     rt_list_insert_after(&clocks, &pllb.node);
268     rt_list_insert_after(&clocks, &uhpck.node);
269     rt_list_insert_after(&clocks, &udpck.node);
270 
271     // MCK and CPU clock are "always on"
272     //clk_enable(&mck);
273 
274     //rt_kprintf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
275     //  freq / 1000000, (unsigned) mck.rate_hz / 1000000,
276     //  (unsigned) main_clock / 1000000,
277     //  ((unsigned) main_clock % 1000000) / 1000); //cause blocked
278 
279     return 0;
280 }
281 */
282 
283  // @brief System Clock Configuration
284 
rt_hw_clock_init(void)285 void rt_hw_clock_init(void)
286 {
287     //at91_clock_init(18432000);
288 }
289 
290