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  * 2010-11-13     weety     first version
9  */
10 
11 #include <edma.h>
12 
13 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
14 
15 static rt_uint32_t commonrate;
16 static rt_uint32_t div_by_four;
17 static rt_uint32_t div_by_six;
18 static rt_uint32_t armrate;
19 static rt_uint32_t fixedrate;
20 static rt_uint32_t ddrrate;
21 static rt_uint32_t voicerate;
22 static rt_uint32_t mmcsdrate;
23 static rt_uint32_t vpssrate, vencrate_sd, vencrate_hd;
24 
25 
26 /* Four Transfer Controllers on DM365 */
27 static const rt_int8_t
28 dm365_queue_tc_mapping[][2] = {
29     /* {event queue no, TC no} */
30     {0, 0},
31     {1, 1},
32     {2, 2},
33     {3, 3},
34     {-1, -1},
35 };
36 
37 static const rt_int8_t
38 dm365_queue_priority_mapping[][2] = {
39     /* {event queue no, Priority} */
40     {0, 7},
41     {1, 7},
42     {2, 7},
43     {3, 0},
44     {-1, -1},
45 };
46 
47 static struct edma_soc_info edma_cc0_info = {
48     .n_channel      = 64,
49     .n_region       = 4,
50     .n_slot         = 256,
51     .n_tc           = 4,
52     .n_cc           = 1,
53     .queue_tc_mapping   = dm365_queue_tc_mapping,
54     .queue_priority_mapping = dm365_queue_priority_mapping,
55     .default_queue      = EVENTQ_3,
56 };
57 
58 static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
59     &edma_cc0_info,
60 };
61 
62 static rt_list_t clocks;
63 
64 struct clk {
65     char name[32];
66     rt_uint32_t *rate_hz;
67     struct clk *parent;
68     rt_list_t  node;
69 };
70 
71 static struct clk davinci_dm365_clks[] = {
72     {
73         .name = "ARMCLK",
74         .rate_hz = &armrate,
75     },
76     {
77         .name = "UART0",
78         .rate_hz = &fixedrate,
79     },
80     {
81         .name = "UART1",
82         .rate_hz = &commonrate,
83     },
84     {
85         .name = "HPI",
86         .rate_hz = &commonrate,
87     },
88     {
89         .name = "EMACCLK",
90         .rate_hz = &commonrate,
91     },
92     {
93         .name = "I2CCLK",
94         .rate_hz = &fixedrate,
95     },
96     {
97         .name = "McBSPCLK",
98         .rate_hz = &commonrate,
99     },
100     {
101         .name = "MMCSDCLK0",
102         .rate_hz = &mmcsdrate,
103     },
104     {
105         .name = "MMCSDCLK1",
106         .rate_hz = &mmcsdrate,
107     },
108     {
109         .name = "SPICLK",
110         .rate_hz = &commonrate,
111     },
112     {
113         .name = "gpio",
114         .rate_hz = &commonrate,
115     },
116     {
117         .name = "AEMIFCLK",
118         .rate_hz = &commonrate,
119     },
120     {
121         .name = "PWM0_CLK",
122         .rate_hz = &fixedrate,
123     },
124     {
125         .name = "PWM1_CLK",
126         .rate_hz = &fixedrate,
127     },
128     {
129         .name = "PWM2_CLK",
130         .rate_hz = &fixedrate,
131     },
132     {
133         .name = "PWM3_CLK",
134         .rate_hz = &fixedrate,
135     },
136     {
137         .name = "USBCLK",
138         .rate_hz = &fixedrate,
139     },
140     {
141         .name = "VOICECODEC_CLK",
142         .rate_hz = &voicerate,
143     },
144     {
145         .name = "RTC_CLK",
146         .rate_hz = &fixedrate,
147     },
148     {
149         .name = "KEYSCAN_CLK",
150         .rate_hz = &fixedrate,
151     },
152     {
153         .name = "ADCIF_CLK",
154         .rate_hz = &fixedrate,
155     },
156 };
157 
158 /* clocks cannot be de-registered no refcounting necessary */
clk_get(const char * id)159 struct clk *clk_get(const char *id)
160 {
161     struct clk *clk;
162     rt_list_t *list;
163 
164     for (list = (&clocks)->next; list != &clocks; list = list->next)
165     {
166         clk = (struct clk *)rt_list_entry(list, struct clk, node);
167         if (rt_strcmp(id, clk->name) == 0)
168             return clk;
169     }
170 
171     return RT_NULL;
172 }
173 
clk_get_rate(struct clk * clk)174 rt_uint32_t clk_get_rate(struct clk *clk)
175 {
176     rt_uint32_t flags;
177     rt_uint32_t *rate;
178 
179     for (;;) {
180         rate = clk->rate_hz;
181         if (rate || !clk->parent)
182             break;
183         clk = clk->parent;
184     }
185     return *rate;
186 }
187 
clk_register(struct clk * clk)188 void clk_register(struct clk *clk)
189 {
190     rt_list_insert_after(&clocks, &clk->node);
191 }
192 
davinci_register_clks(struct clk * clk_list,int num_clks)193 int davinci_register_clks(struct clk *clk_list, int num_clks)
194 {
195     struct clk *clkp;
196     int i;
197 
198     for (i = 0, clkp = clk_list; i < num_clks; i++, clkp++)
199     {
200         //rt_kprintf("1:%s\n", clkp->name);
201         clk_register(clkp);
202         //rt_kprintf("2:%s\n", clkp->name);
203     }
204 
205     return 0;
206 }
207 
208 /* PLL/Reset register offsets */
209 #define PLLM        0x110
210 #define PREDIV      0x114
211 #define PLLDIV2     0x11C
212 #define POSTDIV     0x128
213 #define PLLDIV4     0x160
214 #define PLLDIV5     0x164
215 #define PLLDIV6     0x168
216 #define PLLDIV7     0x16C
217 #define PLLDIV8     0x170
218 
219 
davinci_clk_init(void)220 int davinci_clk_init(void)
221 {
222     struct clk *clk_list;
223     int num_clks;
224     rt_uint32_t pll0_mult, pll1_mult;
225 
226     unsigned long prediv, postdiv;
227     unsigned long pll_rate;
228     unsigned long pll_div2, pll_div4, pll_div5,
229         pll_div6, pll_div7, pll_div8;
230 
231     rt_list_init(&clocks);
232 
233     //davinci_psc_register(davinci_psc_base, 1);
234 
235     pll0_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
236     pll1_mult = davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLM);
237 
238     commonrate = ((pll0_mult + 1) * 27000000) / 6;
239     armrate = ((pll0_mult + 1) * 27000000) / 2;
240 
241     fixedrate = 24000000;
242 
243     /* Read PLL0 configuration */
244     prediv = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PREDIV) &
245             0x1f) + 1;
246     postdiv = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + POSTDIV) &
247             0x1f) + 1;
248 
249     /* PLL0 dividers */
250     pll_div4 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV4) &
251             0x1f) + 1; /* EDMA, EMAC, config, common */
252     pll_div5 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV5) &
253             0x1f) + 1; /* VPSS */
254     pll_div6 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV6) &
255             0x1f) + 1; /* VENC */
256     pll_div7 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV7) &
257             0x1f) + 1; /* DDR */
258     pll_div8 = (davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLDIV8) &
259             0x1f) + 1; /* MMC/SD */
260 
261     pll_rate = ((fixedrate / prediv) * (2 * pll0_mult)) / postdiv;
262 
263     commonrate = pll_rate / pll_div4; /* 486/4 = 121.5MHz */
264     vpssrate = pll_rate / pll_div5; /* 486/2 = 243MHz */
265     vencrate_sd = pll_rate / pll_div6; /* 486/18 =  27MHz */
266     ddrrate = pll_rate / pll_div7; /* 486/2 = 243MHz */
267     mmcsdrate = pll_rate / pll_div8; /* 486/4 =  121.5MHz */
268 
269     rt_kprintf(
270         "PLL0: fixedrate: %d, commonrate: %d, vpssrate: %d\n",
271         fixedrate, commonrate, vpssrate);
272     rt_kprintf(
273         "PLL0: vencrate_sd: %d, ddrrate: %d mmcsdrate: %d\n",
274         vencrate_sd, (ddrrate/2), mmcsdrate);
275 
276     /* Read PLL1 configuration */
277     prediv = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PREDIV) &
278             0x1f) + 1;
279     postdiv = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + POSTDIV) &
280             0x1f) + 1;
281     pll_rate = ((fixedrate / prediv) * (2 * pll1_mult)) / postdiv;
282 
283     /* PLL1 dividers */
284     pll_div2 = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLDIV2) &
285             0x1f) + 1; /* ARM */
286     pll_div4 = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLDIV4) &
287             0x1f) + 1; /* VOICE */
288     pll_div5 = (davinci_readl(DAVINCI_PLL_CNTRL1_BASE + PLLDIV5) &
289             0x1f) + 1; /* VENC */
290 
291     armrate = pll_rate / pll_div2; /* 594/2 = 297MHz */
292     voicerate = pll_rate / pll_div4; /* 594/6 = 99MHz */
293     vencrate_hd = pll_rate / pll_div5; /* 594/8 = 74.25MHz */
294 
295     rt_kprintf(
296         "PLL1: armrate: %d, voicerate: %d, vencrate_hd: %d\n",
297         armrate, voicerate, vencrate_hd);
298 
299     clk_list = davinci_dm365_clks;
300     num_clks = ARRAY_SIZE(davinci_dm365_clks);
301 
302     return davinci_register_clks(clk_list, num_clks);
303 }
304 
platform_init(void)305 int platform_init(void)
306 {
307     edma_init(dm365_edma_info);
308 }
309 
310 INIT_BOARD_EXPORT(platform_init);
311 
312 /* Reset board using the watchdog timer */
reset_system(void)313 void reset_system(void)
314 {
315     rt_uint32_t tgcr, wdtcr;
316     rt_uint32_t base = DAVINCI_WDOG_BASE;
317 
318     /* Disable, internal clock source */
319     davinci_writel(0, base + TCR);
320 
321     /* Reset timer, set mode to 64-bit watchdog, and unreset */
322     davinci_writel(0, base + TGCR);
323     tgcr =  (TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT) |
324         (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
325         (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
326     davinci_writel(tgcr, base + TGCR);
327 
328     /* Clear counter and period regs */
329     davinci_writel(0, base + TIM12);
330     davinci_writel(0, base + TIM34);
331     davinci_writel(0, base + PRD12);
332     davinci_writel(0, base + PRD34);
333 
334     /* Enable periodic mode */
335     davinci_writel(TCR_ENAMODE_PERIODIC << ENAMODE12_SHIFT, base + TCR);
336 
337     /* Put watchdog in pre-active state */
338     wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
339         (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
340     davinci_writel(wdtcr, base + WDTCR);
341 
342     /* Put watchdog in active state */
343     wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
344         (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
345     davinci_writel(wdtcr, base + WDTCR);
346 
347     /*
348      * Write an invalid value to the WDKEY field to trigger
349      * a watchdog reset.
350      */
351     wdtcr = 0xDEADBEEF;
352     davinci_writel(wdtcr, base + WDTCR);
353 }
354 
355 
356