dm365.c 8.6 KB

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