mt_pwm_hal.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. /*******************************************************************************
  2. * mt_pwm.c PWM Drvier
  3. *
  4. * Copyright (c) 2012, Media Teck.inc
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public Licence,
  8. * version 2, as publish by the Free Software Foundation.
  9. *
  10. * This program is distributed and in hope it will be useful, but WITHOUT
  11. * ANY WARRNTY; without even the implied warranty of MERCHANTABITLITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. */
  15. #include <linux/types.h>
  16. #include <mach/mt_pwm_hal_pub.h>
  17. #include <mach/mt_pwm_hal.h>
  18. #include <mach/mt_pwm_prv.h>
  19. #if !defined(CONFIG_MTK_CLKMGR)
  20. #include <linux/clk.h>
  21. #else
  22. #include <mach/mt_clkmgr.h>
  23. #endif
  24. /**********************************
  25. * Global data
  26. ***********************************/
  27. enum {
  28. PWM_CON,
  29. PWM_HDURATION,
  30. PWM_LDURATION,
  31. PWM_GDURATION,
  32. PWM_BUF0_BASE_ADDR,
  33. PWM_BUF0_SIZE,
  34. PWM_BUF1_BASE_ADDR,
  35. PWM_BUF1_SIZE,
  36. PWM_SEND_DATA0,
  37. PWM_SEND_DATA1,
  38. PWM_WAVE_NUM,
  39. PWM_DATA_WIDTH,
  40. PWM_THRESH,
  41. PWM_SEND_WAVENUM,
  42. PWM_VALID
  43. } PWM_REG_OFF;
  44. #if defined(CONFIG_MTK_CLKMGR)
  45. int pwm_power_id[] = {
  46. MT_CG_PERI_PWM1,
  47. MT_CG_PERI_PWM2,
  48. MT_CG_PERI_PWM3,
  49. MT_CG_PERI_PWM4,
  50. MT_CG_PERI_PWM5,
  51. MT_CG_PERI_PWM
  52. };
  53. #define PWM_CG 5
  54. #endif
  55. #ifdef CONFIG_OF
  56. unsigned long PWM_register[PWM_NUM] = {};
  57. #else
  58. unsigned long PWM_register[PWM_NUM] = {
  59. (PWM_BASE+0x0010), /* PWM1 register base, 15 registers */
  60. (PWM_BASE+0x0050), /* PWM2 register base 15 registers */
  61. (PWM_BASE+0x0090), /* PWM3 register base 15 registers */
  62. (PWM_BASE+0x00d0), /* PWM4 register base 13 registers */
  63. (PWM_BASE+0x0110), /* PWM5 register base 13 registers */
  64. };
  65. #endif
  66. /**************************************************************/
  67. #if !defined(CONFIG_MTK_CLKMGR)
  68. enum {
  69. PWM1_CLK,
  70. PWM2_CLK,
  71. PWM3_CLK,
  72. PWM4_CLK,
  73. PWM5_CLK,
  74. PWM_CLK,
  75. PWM_CLK_NUM,
  76. };
  77. const char *pwm_clk_name[] = {
  78. "PWM1-main", "PWM2-main", "PWM3-main", "PWM4-main", "PWM5-main", "PWM-main"
  79. };
  80. struct clk *pwm_clk[PWM_CLK_NUM];
  81. void mt_pwm_power_on_hal(u32 pwm_no, bool pmic_pad, unsigned long *power_flag)
  82. {
  83. int clk_en_ret;
  84. /*Set pwm_main , pwm_hclk_main(for memory and random mode) */
  85. if (0 == (*power_flag)) {
  86. pr_warn("[PWM][CCF]enable clk PWM_CLK:%p\n", pwm_clk[PWM_CLK]);
  87. clk_en_ret = clk_prepare_enable(pwm_clk[PWM_CLK]);
  88. if (clk_en_ret) {
  89. pr_err("[PWM][CCF]enable clk PWM_CLK failed. ret:%d, clk_pwm_main:%p\n",
  90. clk_en_ret, pwm_clk[PWM_CLK]);
  91. } else
  92. set_bit(PWM_CLK, power_flag);
  93. }
  94. /* Set pwm_no clk */
  95. if (!test_bit(pwm_no, power_flag)) {
  96. pr_warn("[PWM][CCF]enable clk_pwm%d :%p\n", pwm_no, pwm_clk[pwm_no]);
  97. clk_en_ret = clk_prepare_enable(pwm_clk[pwm_no]);
  98. if (clk_en_ret) {
  99. pr_err("[PWM][CCF]enable clk_pwm_main failed. ret:%d, clk_pwm%d :%p\n",
  100. clk_en_ret, pwm_no, pwm_clk[pwm_no]);
  101. } else
  102. set_bit(pwm_no, power_flag);
  103. }
  104. }
  105. void mt_pwm_power_off_hal(u32 pwm_no, bool pmic_pad, unsigned long *power_flag)
  106. {
  107. if (test_bit(pwm_no, power_flag)) {
  108. pr_debug("[PWM][CCF]disable clk_pwm%d :%p\n", pwm_no, pwm_clk[pwm_no]);
  109. clk_disable_unprepare(pwm_clk[pwm_no]);
  110. clear_bit(pwm_no, power_flag);
  111. }
  112. /*Disable PWM-main, PWM-HCLK-main */
  113. pr_debug("[PWM][CCF]disable clk_pwm :%p\n", pwm_clk[PWM_CLK]);
  114. if (test_bit(PWM_CLK, power_flag)) {
  115. clk_disable_unprepare(pwm_clk[PWM_CLK]);
  116. clear_bit(PWM_CLK, power_flag);
  117. }
  118. }
  119. #else
  120. void mt_pwm_power_on_hal(u32 pwm_no, bool pmic_pad, unsigned long *power_flag)
  121. {
  122. if (0 == (*power_flag)) {
  123. PWMDBG("enable_clock: main\n");
  124. enable_clock(pwm_power_id[PWM_CG], "PWM");
  125. set_bit(PWM_CG, power_flag);
  126. }
  127. if (!test_bit(pwm_no, power_flag)) {
  128. PWMDBG("enable_clock: %d\n", pwm_no);
  129. enable_clock(pwm_power_id[pwm_no], "PWM");
  130. set_bit(pwm_no, power_flag);
  131. PWMDBG("enable_clock PWM%d\n", pwm_no+1);
  132. }
  133. }
  134. void mt_pwm_power_off_hal(u32 pwm_no, bool pmic_pad, unsigned long *power_flag)
  135. {
  136. if (test_bit(pwm_no, power_flag)) {
  137. PWMDBG("disable_clock: %d\n", pwm_no);
  138. disable_clock(pwm_power_id[pwm_no], "PWM");
  139. clear_bit(pwm_no, power_flag);
  140. PWMDBG("disable_clock PWM%d\n", pwm_no+1);
  141. }
  142. if (BIT(PWM_CG) == (*power_flag)) {
  143. PWMDBG("disable_clock: main\n");
  144. disable_clock(pwm_power_id[PWM_CG], "PWM");
  145. clear_bit(PWM_CG, power_flag);
  146. }
  147. }
  148. #endif
  149. void mt_pwm_init_power_flag(unsigned long *power_flag)
  150. {
  151. #ifdef CONFIG_OF
  152. PWM_register[PWM1] = (unsigned long)pwm_base + 0x0010;
  153. PWM_register[PWM2] = (unsigned long)pwm_base + 0x0050;
  154. PWM_register[PWM3] = (unsigned long)pwm_base + 0x0090;
  155. PWM_register[PWM4] = (unsigned long)pwm_base + 0x00d0;
  156. PWM_register[PWM5] = (unsigned long)pwm_base + 0x0110;
  157. #endif
  158. }
  159. s32 mt_pwm_sel_pmic_hal(u32 pwm_no)
  160. {
  161. PWMDBG("mt_pwm_sel_pmic\n");
  162. return -EINVALID;
  163. }
  164. s32 mt_pwm_sel_ap_hal(u32 pwm_no)
  165. {
  166. PWMDBG("mt_pwm_sel_ap\n");
  167. return -EINVALID;
  168. }
  169. void mt_set_pwm_enable_hal(u32 pwm_no)
  170. {
  171. SETREG32(PWM_ENABLE, 1 << pwm_no);
  172. }
  173. void mt_set_pwm_disable_hal(u32 pwm_no)
  174. {
  175. CLRREG32(PWM_ENABLE, 1 << pwm_no);
  176. }
  177. void mt_set_pwm_enable_seqmode_hal(void)
  178. {
  179. }
  180. void mt_set_pwm_disable_seqmode_hal(void)
  181. {
  182. }
  183. s32 mt_set_pwm_test_sel_hal(u32 val)
  184. {
  185. return 0;
  186. }
  187. void mt_set_pwm_clk_hal(u32 pwm_no, u32 clksrc, u32 div)
  188. {
  189. unsigned long reg_con;
  190. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  191. MASKREG32(reg_con, PWM_CON_CLKDIV_MASK, div);
  192. if ((clksrc & 0x80000000) != 0) {
  193. clksrc &= ~(0x80000000);
  194. if (clksrc == CLK_BLOCK_BY_1625_OR_32K) { /* old mode: 26M/1625 = 16KHz */
  195. CLRREG32(reg_con, 1 << PWM_CON_CLKSEL_OLD_OFFSET); /* bit 4: 0 */
  196. SETREG32(reg_con, 1 << PWM_CON_CLKSEL_OFFSET); /* bit 3: 1 */
  197. } else { /* old mode 32k clk */
  198. SETREG32(reg_con, 1 << PWM_CON_CLKSEL_OLD_OFFSET);
  199. SETREG32(reg_con, 1 << PWM_CON_CLKSEL_OFFSET);
  200. }
  201. } else {
  202. CLRREG32(reg_con, 1 << PWM_CON_CLKSEL_OLD_OFFSET);
  203. if (clksrc == CLK_BLOCK)
  204. CLRREG32(reg_con, 1 << PWM_CON_CLKSEL_OFFSET);
  205. else if (clksrc == CLK_BLOCK_BY_1625_OR_32K)
  206. SETREG32(reg_con, 1 << PWM_CON_CLKSEL_OFFSET);
  207. }
  208. }
  209. s32 mt_get_pwm_clk_hal(u32 pwm_no)
  210. {
  211. s32 clk, clksrc, clkdiv;
  212. unsigned long reg_con, reg_val, reg_en;
  213. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  214. reg_val = INREG32(reg_con);
  215. reg_en = INREG32(PWM_ENABLE);
  216. if (((reg_val & PWM_CON_CLKSEL_MASK) >> PWM_CON_CLKSEL_OFFSET) == 1)
  217. if (((reg_en & PWM_CON_OLD_MODE_MASK) >> PWM_CON_OLD_MODE_OFFSET) == 1)
  218. clksrc = 32 * 1024;
  219. else
  220. clksrc = BLOCK_CLK;
  221. else
  222. clksrc = BLOCK_CLK / 1625;
  223. clkdiv = 2 << (reg_val & PWM_CON_CLKDIV_MASK);
  224. if (clkdiv <= 0) {
  225. PWMDBG("clkdiv less zero, not valid\n");
  226. return -ERROR;
  227. }
  228. clk = clksrc / clkdiv;
  229. PWMDBG("CLK is :%d\n", clk);
  230. return clk;
  231. }
  232. s32 mt_set_pwm_con_datasrc_hal(u32 pwm_no, u32 val)
  233. {
  234. unsigned long reg_con;
  235. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  236. if (val == PWM_FIFO)
  237. CLRREG32(reg_con, 1 << PWM_CON_SRCSEL_OFFSET);
  238. else if (val == MEMORY)
  239. SETREG32(reg_con, 1 << PWM_CON_SRCSEL_OFFSET);
  240. else
  241. return 1;
  242. return 0;
  243. }
  244. s32 mt_set_pwm_con_mode_hal(u32 pwm_no, u32 val)
  245. {
  246. unsigned long reg_con;
  247. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  248. if (val == PERIOD)
  249. CLRREG32(reg_con, 1 << PWM_CON_MODE_OFFSET);
  250. else if (val == RAND)
  251. SETREG32(reg_con, 1 << PWM_CON_MODE_OFFSET);
  252. else
  253. return 1;
  254. return 0;
  255. }
  256. s32 mt_set_pwm_con_idleval_hal(u32 pwm_no, uint16_t val)
  257. {
  258. unsigned long reg_con;
  259. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  260. if (val == IDLE_TRUE)
  261. SETREG32(reg_con, 1 << PWM_CON_IDLE_VALUE_OFFSET);
  262. else if (val == IDLE_FALSE)
  263. CLRREG32(reg_con, 1 << PWM_CON_IDLE_VALUE_OFFSET);
  264. else
  265. return 1;
  266. return 0;
  267. }
  268. s32 mt_set_pwm_con_guardval_hal(u32 pwm_no, uint16_t val)
  269. {
  270. unsigned long reg_con;
  271. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  272. if (val == GUARD_TRUE)
  273. SETREG32(reg_con, 1 << PWM_CON_GUARD_VALUE_OFFSET);
  274. else if (val == GUARD_FALSE)
  275. CLRREG32(reg_con, 1 << PWM_CON_GUARD_VALUE_OFFSET);
  276. else
  277. return 1;
  278. return 0;
  279. }
  280. void mt_set_pwm_con_stpbit_hal(u32 pwm_no, u32 stpbit, u32 srcsel)
  281. {
  282. unsigned long reg_con;
  283. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  284. if (srcsel == PWM_FIFO)
  285. MASKREG32(reg_con, PWM_CON_STOP_BITS_MASK, stpbit << PWM_CON_STOP_BITS_OFFSET);
  286. if (srcsel == MEMORY)
  287. MASKREG32(reg_con, PWM_CON_STOP_BITS_MASK & (0x1f << PWM_CON_STOP_BITS_OFFSET),
  288. stpbit << PWM_CON_STOP_BITS_OFFSET);
  289. }
  290. s32 mt_set_pwm_con_oldmode_hal(u32 pwm_no, u32 val)
  291. {
  292. unsigned long reg_con;
  293. reg_con = PWM_register[pwm_no] + 4 * PWM_CON;
  294. if (val == OLDMODE_DISABLE)
  295. CLRREG32(reg_con, 1 << PWM_CON_OLD_MODE_OFFSET);
  296. else if (val == OLDMODE_ENABLE)
  297. SETREG32(reg_con, 1 << PWM_CON_OLD_MODE_OFFSET);
  298. else
  299. return 1;
  300. return 0;
  301. }
  302. void mt_set_pwm_HiDur_hal(u32 pwm_no, uint16_t DurVal)
  303. { /* only low 16 bits are valid */
  304. unsigned long reg_HiDur;
  305. reg_HiDur = PWM_register[pwm_no] + 4 * PWM_HDURATION;
  306. OUTREG32(reg_HiDur, DurVal);
  307. }
  308. void mt_set_pwm_LowDur_hal(u32 pwm_no, uint16_t DurVal)
  309. {
  310. unsigned long reg_LowDur;
  311. reg_LowDur = PWM_register[pwm_no] + 4 * PWM_LDURATION;
  312. OUTREG32(reg_LowDur, DurVal);
  313. }
  314. void mt_set_pwm_GuardDur_hal(u32 pwm_no, uint16_t DurVal)
  315. {
  316. unsigned long reg_GuardDur;
  317. reg_GuardDur = PWM_register[pwm_no] + 4 * PWM_GDURATION;
  318. OUTREG32(reg_GuardDur, DurVal);
  319. }
  320. void mt_set_pwm_send_data0_hal(u32 pwm_no, u32 data)
  321. {
  322. unsigned long reg_data0;
  323. reg_data0 = PWM_register[pwm_no] + 4 * PWM_SEND_DATA0;
  324. OUTREG32(reg_data0, data);
  325. }
  326. void mt_set_pwm_send_data1_hal(u32 pwm_no, u32 data)
  327. {
  328. unsigned long reg_data1;
  329. reg_data1 = PWM_register[pwm_no] + 4 * PWM_SEND_DATA1;
  330. OUTREG32(reg_data1, data);
  331. }
  332. void mt_set_pwm_wave_num_hal(u32 pwm_no, uint16_t num)
  333. {
  334. unsigned long reg_wave_num;
  335. reg_wave_num = PWM_register[pwm_no] + 4 * PWM_WAVE_NUM;
  336. OUTREG32(reg_wave_num, num);
  337. }
  338. void mt_set_pwm_data_width_hal(u32 pwm_no, uint16_t width)
  339. {
  340. unsigned long reg_data_width;
  341. reg_data_width = PWM_register[pwm_no] + 4 * PWM_DATA_WIDTH;
  342. OUTREG32(reg_data_width, width);
  343. }
  344. void mt_set_pwm_thresh_hal(u32 pwm_no, uint16_t thresh)
  345. {
  346. unsigned long reg_thresh;
  347. reg_thresh = PWM_register[pwm_no] + 4 * PWM_THRESH;
  348. OUTREG32(reg_thresh, thresh);
  349. }
  350. s32 mt_get_pwm_send_wavenum_hal(u32 pwm_no)
  351. {
  352. unsigned long reg_send_wavenum;
  353. reg_send_wavenum = PWM_register[pwm_no] + 4 * PWM_SEND_WAVENUM;
  354. return INREG32(reg_send_wavenum);
  355. }
  356. void mt_set_intr_enable_hal(u32 pwm_intr_enable_bit)
  357. {
  358. SETREG32(PWM_INT_ENABLE, 1 << pwm_intr_enable_bit);
  359. }
  360. s32 mt_get_intr_status_hal(u32 pwm_intr_status_bit)
  361. {
  362. int ret;
  363. ret = INREG32(PWM_INT_STATUS);
  364. ret = (ret >> pwm_intr_status_bit) & 0x01;
  365. return ret;
  366. }
  367. void mt_set_intr_ack_hal(u32 pwm_intr_ack_bit)
  368. {
  369. SETREG32(PWM_INT_ACK, 1 << pwm_intr_ack_bit);
  370. }
  371. void mt_set_pwm_buf0_addr_hal(u32 pwm_no, u32 *addr)
  372. {
  373. unsigned long reg_buff0_addr;
  374. reg_buff0_addr = PWM_register[pwm_no] + 4 * PWM_BUF0_BASE_ADDR;
  375. /*OUTREG32(reg_buff0_addr, addr);*/
  376. OUTREG32_DMA(reg_buff0_addr, addr);
  377. }
  378. void mt_set_pwm_buf0_size_hal(u32 pwm_no, uint16_t size)
  379. {
  380. unsigned long reg_buff0_size;
  381. reg_buff0_size = PWM_register[pwm_no] + 4 * PWM_BUF0_SIZE;
  382. OUTREG32(reg_buff0_size, size);
  383. }
  384. void mt_pwm_dump_regs_hal(void)
  385. {
  386. int i;
  387. unsigned long reg_val;
  388. reg_val = INREG32(PWM_ENABLE);
  389. PWMMSG("\r\n[PWM_ENABLE is:%lx]\n\r ", reg_val);
  390. reg_val = INREG32(PWM_CK_26M_SEL);
  391. PWMMSG("\r\n[PWM_26M_SEL is:%lx]\n\r ", reg_val);
  392. /*PWMDBG("peri pdn0 clock: 0x%x\n", INREG32(INFRA_PDN_STA0));*/
  393. for (i = PWM1; i < PWM_NUM; i++) {
  394. reg_val = INREG32(PWM_register[i] + 4 * PWM_CON);
  395. PWMMSG("\r\n[PWM%d_CON is:%lx]\r\n", i + 1, reg_val);
  396. reg_val = INREG32(PWM_register[i] + 4 * PWM_HDURATION);
  397. PWMMSG("[PWM%d_HDURATION is:%lx]\r\n", i + 1, reg_val);
  398. reg_val = INREG32(PWM_register[i] + 4 * PWM_LDURATION);
  399. PWMMSG("[PWM%d_LDURATION is:%lx]\r\n", i + 1, reg_val);
  400. reg_val = INREG32(PWM_register[i] + 4 * PWM_GDURATION);
  401. PWMMSG("[PWM%d_GDURATION is:%lx]\r\n", i + 1, reg_val);
  402. reg_val = INREG32(PWM_register[i] + 4 * PWM_BUF0_BASE_ADDR);
  403. PWMMSG("\r\n[PWM%d_BUF0_BASE_ADDR is:%lx]\r\n", i, reg_val);
  404. reg_val = INREG32(PWM_register[i] + 4 * PWM_BUF0_SIZE);
  405. PWMMSG("\r\n[PWM%d_BUF0_SIZE is:%lx]\r\n", i, reg_val);
  406. reg_val = INREG32(PWM_register[i] + 4 * PWM_BUF1_BASE_ADDR);
  407. PWMMSG("\r\n[PWM%d_BUF1_BASE_ADDR is:%lx]\r\n", i, reg_val);
  408. reg_val = INREG32(PWM_register[i] + 4 * PWM_BUF1_SIZE);
  409. PWMMSG("\r\n[PWM%d_BUF1_SIZE is:%lx]\r\n", i + 1, reg_val);
  410. reg_val = INREG32(PWM_register[i] + 4 * PWM_SEND_DATA0);
  411. PWMMSG("[PWM%d_SEND_DATA0 is:%lx]\r\n", i + 1, reg_val);
  412. reg_val = INREG32(PWM_register[i] + 4 * PWM_SEND_DATA1);
  413. PWMMSG("[PWM%d_PWM_SEND_DATA1 is:%lx]\r\n", i + 1, reg_val);
  414. reg_val = INREG32(PWM_register[i] + 4 * PWM_WAVE_NUM);
  415. PWMMSG("[PWM%d_WAVE_NUM is:%lx]\r\n", i + 1, reg_val);
  416. reg_val = INREG32(PWM_register[i] + 4 * PWM_DATA_WIDTH);
  417. PWMMSG("[PWM%d_WIDTH is:%lx]\r\n", i + 1, reg_val);
  418. reg_val = INREG32(PWM_register[i] + 4 * PWM_THRESH);
  419. PWMMSG("[PWM%d_THRESH is:%lx]\r\n", i + 1, reg_val);
  420. reg_val = INREG32(PWM_register[i] + 4 * PWM_SEND_WAVENUM);
  421. PWMMSG("[PWM%d_SEND_WAVENUM is:%lx]\r\n", i + 1, reg_val);
  422. }
  423. }
  424. void pwm_debug_store_hal(void)
  425. {
  426. /* dump clock status */
  427. /*PWMDBG("peri pdn0 clock: 0x%x\n", INREG32(INFRA_PDN_STA0));*/
  428. }
  429. void pwm_debug_show_hal(void)
  430. {
  431. mt_pwm_dump_regs_hal();
  432. }
  433. /*----------3dLCM support-----------*/
  434. /*
  435. base pwm2, select pwm3&4&5 same as pwm2 or inversion of pwm2
  436. */
  437. void mt_set_pwm_3dlcm_enable_hal(u8 enable)
  438. {
  439. SETREG32(PWM_3DLCM, 1 << PWM_3DLCM_ENABLE_OFFSET);
  440. }
  441. /*
  442. set "pwm_no" inversion of pwm base or not
  443. */
  444. void mt_set_pwm_3dlcm_inv_hal(u32 pwm_no, u8 inv)
  445. {
  446. /*set "pwm_no" as auxiliary first */
  447. SETREG32(PWM_3DLCM, 1 << (pwm_no + 16));
  448. if (inv)
  449. SETREG32(PWM_3DLCM, 1 << (pwm_no + 1));
  450. else
  451. CLRREG32(PWM_3DLCM, 1 << (pwm_no + 1));
  452. }
  453. void mt_set_pwm_3dlcm_base_hal(u32 pwm_no)
  454. {
  455. CLRREG32(PWM_3DLCM, 0x7F << 8);
  456. SETREG32(PWM_3DLCM, 1 << (pwm_no + 8));
  457. }
  458. void mt_pwm_26M_clk_enable_hal(u32 enable)
  459. {
  460. unsigned long reg_con;
  461. /* select 66M or 26M */
  462. reg_con = (unsigned long)PWM_CK_26M_SEL;
  463. if (enable)
  464. SETREG32(reg_con, 1 << PWM_CK_26M_SEL_OFFSET);
  465. else
  466. CLRREG32(reg_con, 1 << PWM_CK_26M_SEL_OFFSET);
  467. }
  468. #if !defined(CONFIG_MTK_CLKMGR)
  469. int mt_get_pwm_clk_src(struct platform_device *pdev)
  470. {
  471. int i;
  472. for (i = PWM1_CLK; i < PWM_CLK_NUM; i++) {
  473. pwm_clk[i] = devm_clk_get(&pdev->dev, pwm_clk_name[i]);
  474. pr_err("[PWM] get %s clock, %p\n", pwm_clk_name[i], pwm_clk[i]);
  475. if (IS_ERR(pwm_clk[i])) {
  476. PWMDBG("cannot get %s clock\n", pwm_clk_name[i]);
  477. return PTR_ERR(pwm_clk[i]);
  478. }
  479. }
  480. return 0;
  481. }
  482. #endif