exynos_mipi_dsi_lowlevel.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
  2. *
  3. * Samsung SoC MIPI-DSI lowlevel driver.
  4. *
  5. * Copyright (c) 2012 Samsung Electronics Co., Ltd
  6. *
  7. * InKi Dae, <inki.dae@samsung.com>
  8. * Donghwa Lee, <dh09.lee@samsung.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/kernel.h>
  16. #include <linux/errno.h>
  17. #include <linux/mutex.h>
  18. #include <linux/wait.h>
  19. #include <linux/delay.h>
  20. #include <linux/fs.h>
  21. #include <linux/mm.h>
  22. #include <linux/ctype.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/io.h>
  25. #include <video/exynos_mipi_dsim.h>
  26. #include "exynos_mipi_dsi_regs.h"
  27. #include "exynos_mipi_dsi_lowlevel.h"
  28. void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
  29. {
  30. unsigned int reg;
  31. reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
  32. reg |= DSIM_FUNCRST;
  33. writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
  34. }
  35. void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim)
  36. {
  37. unsigned int reg;
  38. reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
  39. reg |= DSIM_SWRST;
  40. writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
  41. }
  42. void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim)
  43. {
  44. unsigned int reg;
  45. reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
  46. reg |= INTSRC_SW_RST_RELEASE;
  47. writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
  48. }
  49. int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim)
  50. {
  51. return (readl(dsim->reg_base + EXYNOS_DSIM_INTSRC)) &
  52. INTSRC_SW_RST_RELEASE;
  53. }
  54. unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim)
  55. {
  56. unsigned int reg;
  57. reg = readl(dsim->reg_base + EXYNOS_DSIM_INTMSK);
  58. return reg;
  59. }
  60. void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
  61. unsigned int mode, unsigned int mask)
  62. {
  63. unsigned int reg = 0;
  64. if (mask)
  65. reg |= mode;
  66. else
  67. reg &= ~mode;
  68. writel(reg, dsim->reg_base + EXYNOS_DSIM_INTMSK);
  69. }
  70. void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
  71. unsigned int cfg)
  72. {
  73. unsigned int reg;
  74. reg = readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
  75. writel(reg & ~(cfg), dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
  76. mdelay(10);
  77. reg |= cfg;
  78. writel(reg, dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
  79. }
  80. /*
  81. * this function set PLL P, M and S value in D-PHY
  82. */
  83. void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
  84. unsigned int value)
  85. {
  86. writel(DSIM_AFC_CTL(value), dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
  87. }
  88. void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
  89. unsigned int enable)
  90. {
  91. unsigned int reg;
  92. reg = readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL);
  93. reg &= ~DSIM_MAIN_STAND_BY;
  94. if (enable)
  95. reg |= DSIM_MAIN_STAND_BY;
  96. writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
  97. }
  98. void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
  99. unsigned int width_resol, unsigned int height_resol)
  100. {
  101. unsigned int reg;
  102. /* standby should be set after configuration so set to not ready*/
  103. reg = (readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL)) &
  104. ~(DSIM_MAIN_STAND_BY);
  105. writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
  106. reg &= ~((0x7ff << 16) | (0x7ff << 0));
  107. reg |= DSIM_MAIN_VRESOL(height_resol) | DSIM_MAIN_HRESOL(width_resol);
  108. reg |= DSIM_MAIN_STAND_BY;
  109. writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
  110. }
  111. void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
  112. unsigned int cmd_allow, unsigned int vfront, unsigned int vback)
  113. {
  114. unsigned int reg;
  115. reg = (readl(dsim->reg_base + EXYNOS_DSIM_MVPORCH)) &
  116. ~((DSIM_CMD_ALLOW_MASK) | (DSIM_STABLE_VFP_MASK) |
  117. (DSIM_MAIN_VBP_MASK));
  118. reg |= (DSIM_CMD_ALLOW_SHIFT(cmd_allow & 0xf) |
  119. DSIM_STABLE_VFP_SHIFT(vfront & 0x7ff) |
  120. DSIM_MAIN_VBP_SHIFT(vback & 0x7ff));
  121. writel(reg, dsim->reg_base + EXYNOS_DSIM_MVPORCH);
  122. }
  123. void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
  124. unsigned int front, unsigned int back)
  125. {
  126. unsigned int reg;
  127. reg = (readl(dsim->reg_base + EXYNOS_DSIM_MHPORCH)) &
  128. ~((DSIM_MAIN_HFP_MASK) | (DSIM_MAIN_HBP_MASK));
  129. reg |= DSIM_MAIN_HFP_SHIFT(front) | DSIM_MAIN_HBP_SHIFT(back);
  130. writel(reg, dsim->reg_base + EXYNOS_DSIM_MHPORCH);
  131. }
  132. void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
  133. unsigned int vert, unsigned int hori)
  134. {
  135. unsigned int reg;
  136. reg = (readl(dsim->reg_base + EXYNOS_DSIM_MSYNC)) &
  137. ~((DSIM_MAIN_VSA_MASK) | (DSIM_MAIN_HSA_MASK));
  138. reg |= (DSIM_MAIN_VSA_SHIFT(vert & 0x3ff) |
  139. DSIM_MAIN_HSA_SHIFT(hori));
  140. writel(reg, dsim->reg_base + EXYNOS_DSIM_MSYNC);
  141. }
  142. void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
  143. unsigned int vert, unsigned int hori)
  144. {
  145. unsigned int reg;
  146. reg = (readl(dsim->reg_base + EXYNOS_DSIM_SDRESOL)) &
  147. ~(DSIM_SUB_STANDY_MASK);
  148. writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
  149. reg &= ~(DSIM_SUB_VRESOL_MASK) | ~(DSIM_SUB_HRESOL_MASK);
  150. reg |= (DSIM_SUB_VRESOL_SHIFT(vert & 0x7ff) |
  151. DSIM_SUB_HRESOL_SHIFT(hori & 0x7ff));
  152. writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
  153. reg |= DSIM_SUB_STANDY_SHIFT(1);
  154. writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
  155. }
  156. void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim)
  157. {
  158. struct mipi_dsim_config *dsim_config = dsim->dsim_config;
  159. unsigned int cfg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
  160. ~((1 << 28) | (0x1f << 20) | (0x3 << 5));
  161. cfg = ((DSIM_AUTO_FLUSH(dsim_config->auto_flush)) |
  162. (DSIM_EOT_DISABLE(dsim_config->eot_disable)) |
  163. (DSIM_AUTO_MODE_SHIFT(dsim_config->auto_vertical_cnt)) |
  164. (DSIM_HSE_MODE_SHIFT(dsim_config->hse)) |
  165. (DSIM_HFP_MODE_SHIFT(dsim_config->hfp)) |
  166. (DSIM_HBP_MODE_SHIFT(dsim_config->hbp)) |
  167. (DSIM_HSA_MODE_SHIFT(dsim_config->hsa)) |
  168. (DSIM_NUM_OF_DATALANE_SHIFT(dsim_config->e_no_data_lane)));
  169. writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
  170. }
  171. void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
  172. struct mipi_dsim_config *dsim_config)
  173. {
  174. u32 reg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
  175. ~((0x3 << 26) | (1 << 25) | (0x3 << 18) | (0x7 << 12) |
  176. (0x3 << 16) | (0x7 << 8));
  177. if (dsim_config->e_interface == DSIM_VIDEO)
  178. reg |= (1 << 25);
  179. else if (dsim_config->e_interface == DSIM_COMMAND)
  180. reg &= ~(1 << 25);
  181. else {
  182. dev_err(dsim->dev, "unknown lcd type.\n");
  183. return;
  184. }
  185. /* main lcd */
  186. reg |= ((u8) (dsim_config->e_burst_mode) & 0x3) << 26 |
  187. ((u8) (dsim_config->e_virtual_ch) & 0x3) << 18 |
  188. ((u8) (dsim_config->e_pixel_format) & 0x7) << 12;
  189. writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
  190. }
  191. void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
  192. unsigned int enable)
  193. {
  194. unsigned int reg;
  195. reg = readl(dsim->reg_base + EXYNOS_DSIM_CONFIG);
  196. if (enable)
  197. reg |= DSIM_LANE_ENx(lane);
  198. else
  199. reg &= ~DSIM_LANE_ENx(lane);
  200. writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
  201. }
  202. void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
  203. unsigned int count)
  204. {
  205. unsigned int cfg;
  206. /* get the data lane number. */
  207. cfg = DSIM_NUM_OF_DATALANE_SHIFT(count);
  208. writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
  209. }
  210. void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
  211. unsigned int afc_code)
  212. {
  213. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
  214. if (enable) {
  215. reg |= (1 << 14);
  216. reg &= ~(0x7 << 5);
  217. reg |= (afc_code & 0x7) << 5;
  218. } else
  219. reg &= ~(1 << 14);
  220. writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
  221. }
  222. void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
  223. unsigned int enable)
  224. {
  225. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
  226. ~(DSIM_PLL_BYPASS_SHIFT(0x1));
  227. reg |= DSIM_PLL_BYPASS_SHIFT(enable);
  228. writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  229. }
  230. void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
  231. unsigned int m, unsigned int s)
  232. {
  233. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  234. reg |= ((p & 0x3f) << 13) | ((m & 0x1ff) << 4) | ((s & 0x7) << 1);
  235. writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  236. }
  237. void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
  238. unsigned int freq_band)
  239. {
  240. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
  241. ~(DSIM_FREQ_BAND_SHIFT(0x1f));
  242. reg |= DSIM_FREQ_BAND_SHIFT(freq_band & 0x1f);
  243. writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  244. }
  245. void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
  246. unsigned int pre_divider, unsigned int main_divider,
  247. unsigned int scaler)
  248. {
  249. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
  250. ~(0x7ffff << 1);
  251. reg |= (pre_divider & 0x3f) << 13 | (main_divider & 0x1ff) << 4 |
  252. (scaler & 0x7) << 1;
  253. writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  254. }
  255. void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
  256. unsigned int lock_time)
  257. {
  258. writel(lock_time, dsim->reg_base + EXYNOS_DSIM_PLLTMR);
  259. }
  260. void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim, unsigned int enable)
  261. {
  262. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
  263. ~(DSIM_PLL_EN_SHIFT(0x1));
  264. reg |= DSIM_PLL_EN_SHIFT(enable & 0x1);
  265. writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  266. }
  267. void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
  268. unsigned int src)
  269. {
  270. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
  271. ~(DSIM_BYTE_CLK_SRC_SHIFT(0x3));
  272. reg |= (DSIM_BYTE_CLK_SRC_SHIFT(src));
  273. writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  274. }
  275. void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
  276. unsigned int enable)
  277. {
  278. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
  279. ~(DSIM_BYTE_CLKEN_SHIFT(0x1));
  280. reg |= DSIM_BYTE_CLKEN_SHIFT(enable);
  281. writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  282. }
  283. void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
  284. unsigned int enable, unsigned int prs_val)
  285. {
  286. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
  287. ~(DSIM_ESC_CLKEN_SHIFT(0x1) | 0xffff);
  288. reg |= DSIM_ESC_CLKEN_SHIFT(enable);
  289. if (enable)
  290. reg |= prs_val;
  291. writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  292. }
  293. void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
  294. unsigned int lane_sel, unsigned int enable)
  295. {
  296. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  297. if (enable)
  298. reg |= DSIM_LANE_ESC_CLKEN(lane_sel);
  299. else
  300. reg &= ~DSIM_LANE_ESC_CLKEN(lane_sel);
  301. writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  302. }
  303. void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
  304. unsigned int enable)
  305. {
  306. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
  307. ~(DSIM_FORCE_STOP_STATE_SHIFT(0x1));
  308. reg |= (DSIM_FORCE_STOP_STATE_SHIFT(enable & 0x1));
  309. writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
  310. }
  311. unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim)
  312. {
  313. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
  314. /**
  315. * check clock and data lane states.
  316. * if MIPI-DSI controller was enabled at bootloader then
  317. * TX_READY_HS_CLK is enabled otherwise STOP_STATE_CLK.
  318. * so it should be checked for two case.
  319. */
  320. if ((reg & DSIM_STOP_STATE_DAT(0xf)) &&
  321. ((reg & DSIM_STOP_STATE_CLK) ||
  322. (reg & DSIM_TX_READY_HS_CLK)))
  323. return 1;
  324. return 0;
  325. }
  326. void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
  327. unsigned int cnt_val)
  328. {
  329. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
  330. ~(DSIM_STOP_STATE_CNT_SHIFT(0x7ff));
  331. reg |= (DSIM_STOP_STATE_CNT_SHIFT(cnt_val & 0x7ff));
  332. writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
  333. }
  334. void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
  335. unsigned int timeout)
  336. {
  337. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
  338. ~(DSIM_BTA_TOUT_SHIFT(0xff));
  339. reg |= (DSIM_BTA_TOUT_SHIFT(timeout));
  340. writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
  341. }
  342. void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
  343. unsigned int timeout)
  344. {
  345. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
  346. ~(DSIM_LPDR_TOUT_SHIFT(0xffff));
  347. reg |= (DSIM_LPDR_TOUT_SHIFT(timeout));
  348. writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
  349. }
  350. void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
  351. unsigned int lp)
  352. {
  353. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
  354. reg &= ~DSIM_CMD_LPDT_LP;
  355. if (lp)
  356. reg |= DSIM_CMD_LPDT_LP;
  357. writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
  358. }
  359. void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
  360. unsigned int lp)
  361. {
  362. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
  363. reg &= ~DSIM_TX_LPDT_LP;
  364. if (lp)
  365. reg |= DSIM_TX_LPDT_LP;
  366. writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
  367. }
  368. void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
  369. unsigned int enable)
  370. {
  371. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
  372. ~(DSIM_TX_REQUEST_HSCLK_SHIFT(0x1));
  373. reg |= DSIM_TX_REQUEST_HSCLK_SHIFT(enable);
  374. writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
  375. }
  376. void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
  377. unsigned int swap_en)
  378. {
  379. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
  380. reg &= ~(0x3 << 0);
  381. reg |= (swap_en & 0x3) << 0;
  382. writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
  383. }
  384. void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
  385. unsigned int hs_zero)
  386. {
  387. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
  388. ~(0xf << 28);
  389. reg |= ((hs_zero & 0xf) << 28);
  390. writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  391. }
  392. void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep)
  393. {
  394. unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
  395. ~(0x7 << 20);
  396. reg |= ((prep & 0x7) << 20);
  397. writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
  398. }
  399. unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim)
  400. {
  401. return readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
  402. }
  403. void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
  404. unsigned int src)
  405. {
  406. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
  407. reg |= src;
  408. writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
  409. }
  410. void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
  411. unsigned int src, unsigned int enable)
  412. {
  413. unsigned int reg = 0;
  414. if (enable)
  415. reg |= src;
  416. else
  417. reg &= ~src;
  418. writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
  419. }
  420. unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim)
  421. {
  422. unsigned int reg;
  423. reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
  424. return reg & (1 << 31) ? 1 : 0;
  425. }
  426. unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim)
  427. {
  428. return readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL) & ~(0x1f);
  429. }
  430. void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
  431. unsigned int di, unsigned int data0, unsigned int data1)
  432. {
  433. unsigned int reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);
  434. writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
  435. }
  436. void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
  437. unsigned int di, unsigned int data0)
  438. {
  439. unsigned int reg = (data0 << 8) | (di << 0);
  440. writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
  441. }
  442. unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim)
  443. {
  444. return readl(dsim->reg_base + EXYNOS_DSIM_RXFIFO);
  445. }
  446. unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
  447. {
  448. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
  449. return (reg & INTSRC_FRAME_DONE) ? 1 : 0;
  450. }
  451. void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
  452. {
  453. unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
  454. writel(reg | INTSRC_FRAME_DONE, dsim->reg_base +
  455. EXYNOS_DSIM_INTSRC);
  456. }
  457. void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
  458. unsigned int tx_data)
  459. {
  460. writel(tx_data, dsim->reg_base + EXYNOS_DSIM_PAYLOAD);
  461. }