hal_ledc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. #include <hal_gpio.h>
  2. #include <hal_dma.h>
  3. #include <hal_clk.h>
  4. #include <hal_reset.h>
  5. #include <hal_cache.h>
  6. #include <sunxi_hal_ledc.h>
  7. #ifdef LEDC_DEBUG
  8. #define ledc_info(fmt, args...) printf("%s()%d - "fmt, __func__, __LINE__, ##args)
  9. #else
  10. #define ledc_info(fmt, args...)
  11. #endif
  12. static unsigned long base_addr = LEDC_BASE;
  13. struct sunxi_dma_chan *dma_chan;
  14. static int ledc_clk_init(void)
  15. {
  16. hal_clk_type_t clk_type = HAL_SUNXI_CCU;
  17. hal_clk_id_t mod_clk_id = CLK_LEDC;
  18. hal_clk_id_t bus_clk_id = CLK_BUS_LEDC;
  19. hal_clk_t mod_clk;
  20. hal_clk_t bus_clk;
  21. hal_reset_type_t reset_type = HAL_SUNXI_RESET;
  22. hal_reset_id_t reset_id = RST_BUS_LEDC;
  23. struct reset_control *reset;
  24. reset = hal_reset_control_get(reset_type, reset_id);
  25. if (hal_reset_control_deassert(reset))
  26. {
  27. ledc_info("ledc reset deassert failed!");
  28. return -1;
  29. }
  30. hal_reset_control_put(reset);
  31. mod_clk = hal_clock_get(clk_type, mod_clk_id);
  32. if (hal_clock_enable(mod_clk))
  33. {
  34. ledc_info("ledc clk enable mclk failed!");
  35. return -1;
  36. }
  37. bus_clk = hal_clock_get(clk_type, bus_clk_id);
  38. if (hal_clock_enable(bus_clk))
  39. {
  40. ledc_info("ledc clk enable mclk failed!");
  41. return -1;
  42. }
  43. return 0;
  44. }
  45. static int ledc_pinctrl_init(void)
  46. {
  47. if (hal_gpio_pinmux_set_function(LEDC_PIN, LEDC_PINMUXSEL))
  48. {
  49. ledc_info("ledc pin set default function failed!");
  50. return -1;
  51. }
  52. return 0;
  53. }
  54. static void ledc_dump_reg(void)
  55. {
  56. ledc_info("LEDC_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_CTRL_REG));
  57. ledc_info("LED_T01_TIMING_CTRL_REG = %0x\n", hal_readl(base_addr + LED_T01_TIMING_CTRL_REG));
  58. ledc_info("LEDC_DATA_FINISH_CNT_REG = %0x\n", hal_readl(base_addr + LEDC_DATA_FINISH_CNT_REG));
  59. ledc_info("LED_RST_TIMING_CTRL_REG = %0x\n", hal_readl(base_addr + LED_RST_TIMING_CTRL_REG));
  60. ledc_info("LEDC_WAIT_TIME0_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_WAIT_TIME0_CTRL_REG));
  61. ledc_info("LEDC_DATA_REG = %0x\n", hal_readl(base_addr + LEDC_DATA_REG));
  62. ledc_info("LEDC_DMA_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_DMA_CTRL_REG));
  63. ledc_info("LEDC_INTC_REG = %0x\n", hal_readl(base_addr + LEDC_INTC_REG));
  64. ledc_info("LEDC_INTS_REG = %0x\n", hal_readl(base_addr + LEDC_INTS_REG));
  65. ledc_info("LEDC_WAIT_TIME1_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_WAIT_TIME1_CTRL_REG));
  66. ledc_info("LEDC_FIFO_DATA0_REG = %0x\n", hal_readl(base_addr + LEDC_FIFO_DATA0_REG));
  67. }
  68. static void ledc_set_reset_ns(unsigned int reset_ns)
  69. {
  70. unsigned int n, reg_val;
  71. unsigned int mask = 0x1FFF;
  72. unsigned int min = LEDC_RESET_TIME_MIN_NS;
  73. unsigned int max = LEDC_RESET_TIME_MAX_NS;
  74. if (reset_ns < min || reset_ns > max) {
  75. ledc_info("invalid parameter, reset_ns should be %u-%u!\n", min, max);
  76. return;
  77. }
  78. n = (reset_ns - 42) / 42;
  79. reg_val = hal_readl(base_addr + LED_RST_TIMING_CTRL_REG);
  80. reg_val &= ~(mask << 16);
  81. reg_val |= (n << 16);
  82. hal_writel(reg_val, base_addr + LED_RST_TIMING_CTRL_REG);
  83. }
  84. static void ledc_set_t1h_ns(unsigned int t1h_ns)
  85. {
  86. unsigned int n, reg_val;
  87. unsigned int mask = 0x3F;
  88. unsigned int shift = 21;
  89. unsigned int min = LEDC_T1H_MIN_NS;
  90. unsigned int max = LEDC_T1H_MAX_NS;
  91. if (t1h_ns < min || t1h_ns > max) {
  92. ledc_info("invalid parameter, t1h_ns should be %u-%u!\n", min, max);
  93. return;
  94. }
  95. n = (t1h_ns - 42) / 42;
  96. reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG);
  97. reg_val &= ~(mask << shift);
  98. reg_val |= n << shift;
  99. hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG);
  100. }
  101. static void ledc_set_t1l_ns(unsigned int t1l_ns)
  102. {
  103. unsigned int n, reg_val;
  104. unsigned int mask = 0x1F;
  105. unsigned int shift = 16;
  106. unsigned int min = LEDC_T1L_MIN_NS;
  107. unsigned int max = LEDC_T1L_MAX_NS;
  108. if (t1l_ns < min || t1l_ns > max) {
  109. ledc_info("invalid parameter, t1l_ns should be %u-%u!\n", min, max);
  110. return;
  111. }
  112. n = (t1l_ns - 42) / 42;
  113. reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG);
  114. reg_val &= ~(mask << shift);
  115. reg_val |= n << shift;
  116. hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG);
  117. }
  118. static void ledc_set_t0h_ns(unsigned int t0h_ns)
  119. {
  120. unsigned int n, reg_val;
  121. unsigned int mask = 0x1F;
  122. unsigned int shift = 6;
  123. unsigned int min = LEDC_T0H_MIN_NS;
  124. unsigned int max = LEDC_T0H_MAX_NS;
  125. if (t0h_ns < min || t0h_ns > max) {
  126. ledc_info("invalid parameter, t0h_ns should be %u-%u!\n", min, max);
  127. return;
  128. }
  129. n = (t0h_ns - 42) / 42;
  130. reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG);
  131. reg_val &= ~(mask << shift);
  132. reg_val |= n << shift;
  133. hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG);
  134. }
  135. static void ledc_set_t0l_ns(unsigned int t0l_ns)
  136. {
  137. unsigned int n, reg_val;
  138. unsigned int min = LEDC_T0L_MIN_NS;
  139. unsigned int max = LEDC_T0L_MAX_NS;
  140. if (t0l_ns < min || t0l_ns > max) {
  141. ledc_info("invalid parameter, t0l_ns should be %u-%u!\n", min, max);
  142. return;
  143. }
  144. n = (t0l_ns - 42) / 42;
  145. reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG);
  146. reg_val &= ~0x3F;
  147. reg_val |= n;
  148. hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG);
  149. }
  150. static void ledc_set_wait_time0_ns(unsigned int wait_time0_ns)
  151. {
  152. unsigned int n, reg_val;
  153. unsigned int min = LEDC_WAIT_TIME0_MIN_NS;
  154. unsigned int max = LEDC_WAIT_TIME0_MAX_NS;
  155. if (wait_time0_ns < min || wait_time0_ns > max) {
  156. ledc_info("invalid parameter, wait_time0_ns should be %u-%u!\n", min, max);
  157. return;
  158. }
  159. n = (wait_time0_ns - 42) / 42;
  160. reg_val = (1 << 8) | n;
  161. hal_writel(reg_val, base_addr + LEDC_WAIT_TIME0_CTRL_REG);
  162. }
  163. static void ledc_set_wait_time1_ns(unsigned long long wait_time1_ns)
  164. {
  165. unsigned long long tmp, max = LEDC_WAIT_TIME1_MAX_NS;
  166. unsigned int min = LEDC_WAIT_TIME1_MIN_NS;
  167. unsigned int n, reg_val;
  168. if (wait_time1_ns < min || wait_time1_ns > max) {
  169. ledc_info("invalid parameter, wait_time1_ns should be %u-%llu!\n", min, max);
  170. return;
  171. }
  172. n = wait_time1_ns / 42;
  173. //tmp = wait_time1_ns;
  174. //n = div_u64(tmp, 42);
  175. n -= 1;
  176. reg_val = (1 << 31) | n;
  177. hal_writel(reg_val, base_addr + LEDC_WAIT_TIME1_CTRL_REG);
  178. }
  179. static void ledc_set_wait_data_time_ns(unsigned int wait_data_time_ns)
  180. {
  181. unsigned int mask = 0x1FFF;
  182. unsigned int shift = 16;
  183. unsigned int reg_val = 0;
  184. unsigned int n, min, max;
  185. min = LEDC_WAIT_DATA_TIME_MIN_NS;
  186. max = LEDC_WAIT_DATA_TIME_MAX_NS_IC;
  187. if (wait_data_time_ns < min || wait_data_time_ns > max) {
  188. ledc_info("invalid parameter, wait_data_time_ns should be %u-%u!\n",
  189. min, max);
  190. return;
  191. }
  192. n = (wait_data_time_ns - 42) / 42;
  193. reg_val &= ~(mask << shift);
  194. reg_val |= (n << shift);
  195. hal_writel(reg_val, base_addr + LEDC_DATA_FINISH_CNT_REG);
  196. }
  197. static void ledc_set_length(unsigned int length)
  198. {
  199. unsigned int reg_val;
  200. if (length == 0)
  201. return;
  202. reg_val = hal_readl(base_addr + LEDC_CTRL_REG);
  203. reg_val &= ~(0x1FFF << 16);
  204. reg_val |= length << 16;
  205. hal_writel(reg_val, base_addr + LEDC_CTRL_REG);
  206. reg_val = hal_readl(base_addr + LED_RST_TIMING_CTRL_REG);
  207. reg_val &= ~0x3FF;
  208. reg_val |= length - 1;
  209. hal_writel(reg_val, base_addr + LED_RST_TIMING_CTRL_REG);
  210. }
  211. static void ledc_set_output_mode(const char *str)
  212. {
  213. unsigned int val = 0;
  214. unsigned int mask = 0x7;
  215. unsigned int shift = 6;
  216. unsigned int reg_val ;
  217. if (str != NULL) {
  218. if (!strncmp(str, "GRB", 3))
  219. val = LEDC_OUTPUT_GRB;
  220. else if (!strncmp(str, "GBR", 3))
  221. val = LEDC_OUTPUT_GBR;
  222. else if (!strncmp(str, "RGB", 3))
  223. val = LEDC_OUTPUT_RGB;
  224. else if (!strncmp(str, "RBG", 3))
  225. val = LEDC_OUTPUT_RBG;
  226. else if (!strncmp(str, "BGR", 3))
  227. val = LEDC_OUTPUT_BGR;
  228. else if (!strncmp(str, "BRG", 3))
  229. val = LEDC_OUTPUT_BRG;
  230. else
  231. return;
  232. } else {
  233. }
  234. reg_val = hal_readl(base_addr + LEDC_CTRL_REG);
  235. reg_val &= ~(mask << shift);
  236. reg_val |= val;
  237. hal_writel(reg_val, base_addr + LEDC_CTRL_REG);
  238. }
  239. static void ledc_disable_irq(unsigned int mask)
  240. {
  241. unsigned int reg_val = 0;
  242. reg_val = hal_readl(base_addr + LEDC_INTC_REG);
  243. reg_val &= ~mask;
  244. hal_writel(reg_val, base_addr + LEDC_INTC_REG);
  245. }
  246. static void ledc_enable_irq(unsigned int mask)
  247. {
  248. unsigned int reg_val = 0;
  249. reg_val = hal_readl(base_addr + LEDC_INTC_REG);
  250. reg_val |= mask;
  251. hal_writel(reg_val, base_addr + LEDC_INTC_REG);
  252. }
  253. static void ledc_set_dma_mode(void)
  254. {
  255. unsigned int reg_val = 0;
  256. reg_val |= 1 << 5;
  257. hal_writel(reg_val, base_addr + LEDC_DMA_CTRL_REG);
  258. }
  259. static void ledc_set_cpu_mode(void)
  260. {
  261. unsigned int reg_val = 0;
  262. reg_val &= ~(1 << 5);
  263. hal_writel(reg_val, base_addr + LEDC_DMA_CTRL_REG);
  264. }
  265. static void ledc_clear_all_irq(void)
  266. {
  267. unsigned int reg_val;
  268. reg_val = hal_readl(base_addr + LEDC_INTS_REG);
  269. reg_val |= 0x1F;
  270. hal_writel(reg_val, base_addr + LEDC_INTS_REG);
  271. }
  272. static unsigned int ledc_get_irq_status(void)
  273. {
  274. return hal_readl(base_addr + LEDC_INTS_REG);
  275. }
  276. static void ledc_soft_reset(void)
  277. {
  278. unsigned int reg_val;
  279. reg_val = hal_readl(base_addr + LEDC_CTRL_REG);
  280. reg_val |= 1 << 1;
  281. hal_writel(reg_val, base_addr + LEDC_CTRL_REG);
  282. }
  283. static void ledc_reset_en(void)
  284. {
  285. unsigned int reg_val;
  286. reg_val = hal_readl(base_addr + LEDC_CTRL_REG);
  287. reg_val |= 1 << 10;
  288. hal_writel(reg_val, base_addr + LEDC_CTRL_REG);
  289. }
  290. static void ledc_set_data(unsigned int data)
  291. {
  292. hal_writel(data, base_addr + LEDC_DATA_REG);
  293. }
  294. static void ledc_enable(void)
  295. {
  296. unsigned int reg_val;
  297. reg_val = hal_readl(base_addr + LEDC_CTRL_REG);
  298. reg_val |= 1;
  299. hal_writel(reg_val, base_addr + LEDC_CTRL_REG);
  300. }
  301. static void hal_ledc_set_time(struct ledc_config *ledc)
  302. {
  303. ledc_set_reset_ns(ledc->reset_ns);
  304. ledc_set_t1h_ns(ledc->t1h_ns);
  305. ledc_set_t1l_ns(ledc->t1l_ns);
  306. ledc_set_t0h_ns(ledc->t0h_ns);
  307. ledc_set_t0l_ns(ledc->t0l_ns);
  308. ledc_set_wait_time0_ns(ledc->wait_time0_ns);
  309. ledc_set_wait_time1_ns(ledc->wait_time1_ns);
  310. ledc_set_wait_data_time_ns(ledc->wait_data_time_ns);
  311. }
  312. void hal_ledc_dma_callback(void *para)
  313. {
  314. printf("dma callback\n");
  315. }
  316. void hal_ledc_trans_data(struct ledc_config *ledc)
  317. {
  318. int i;
  319. unsigned long int size;
  320. unsigned int mask = 0;
  321. struct dma_slave_config slave_config;
  322. mask = LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN
  323. | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN;
  324. if (ledc->length <= SUNXI_LEDC_FIFO_DEPTH) {
  325. ledc_info("trans data by CPU mode\n");
  326. mask |= LEDC_FIFO_CPUREQ_INT_EN;
  327. ledc_reset_en();
  328. hal_ledc_set_time(ledc);
  329. ledc_set_output_mode(ledc->output_mode);
  330. ledc_set_cpu_mode();
  331. ledc_set_length(ledc->length);
  332. ledc_enable_irq(mask);
  333. for(i = 0; i < ledc->length; i++)
  334. ledc_set_data(ledc->data[i]);
  335. ledc_enable();
  336. } else {
  337. ledc_info("trans data by DMA mode\n");
  338. mask &= ~LEDC_FIFO_CPUREQ_INT_EN;
  339. ledc_reset_en();
  340. size = ledc->length * 4;
  341. hal_dcache_clean((unsigned long)ledc->data, sizeof(ledc->data));
  342. slave_config.direction = DMA_MEM_TO_DEV;
  343. slave_config.src_addr = (unsigned long)(ledc->data);
  344. slave_config.dst_addr = (uint32_t)(base_addr + LEDC_DATA_REG);
  345. slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  346. slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
  347. slave_config.src_maxburst = DMA_SLAVE_BURST_16;
  348. slave_config.dst_maxburst = DMA_SLAVE_BURST_16;
  349. slave_config.slave_id = sunxi_slave_id(DRQDST_LEDC, DRQSRC_SDRAM);
  350. hal_dma_slave_config(dma_chan, &slave_config);
  351. hal_dma_prep_device(dma_chan, slave_config.dst_addr, slave_config.src_addr, size, DMA_MEM_TO_DEV);
  352. //dma_chan->callback = ledc_dma_callback;
  353. hal_dma_start(dma_chan);
  354. hal_ledc_set_time(ledc);
  355. ledc_set_output_mode(ledc->output_mode);
  356. ledc_set_length(ledc->length);
  357. ledc_set_dma_mode();
  358. ledc_enable_irq(mask);
  359. ledc_enable();
  360. }
  361. }
  362. void hal_ledc_clear_all_irq(void)
  363. {
  364. ledc_clear_all_irq();
  365. }
  366. unsigned int hal_ledc_get_irq_status(void)
  367. {
  368. return ledc_get_irq_status();
  369. }
  370. void hal_ledc_reset(void)
  371. {
  372. ledc_disable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN
  373. | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN | LEDC_GLOBAL_INT_EN);
  374. if (dma_chan)
  375. {
  376. hal_dma_stop(dma_chan);
  377. }
  378. ledc_soft_reset();
  379. }
  380. void hal_ledc_deinit(void)
  381. {
  382. hal_dma_chan_free(dma_chan);
  383. hal_gpio_pinmux_set_function(GPIOE(2), 2);
  384. //clk_deinit
  385. }
  386. void hal_ledc_init(void)
  387. {
  388. int i;
  389. unsigned int reg_val = 0;
  390. if (ledc_clk_init())
  391. {
  392. ledc_info("ledc clk init failed \n");
  393. }
  394. if (ledc_pinctrl_init())
  395. {
  396. ledc_info("ledc pinctrl init failed \n");
  397. }
  398. hal_dma_chan_request(&dma_chan);
  399. }