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