exynos_mipi_dsi_common.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /*
  2. * Copyright (C) 2012 Samsung Electronics
  3. *
  4. * Author: InKi Dae <inki.dae@samsung.com>
  5. * Author: Donghwa Lee <dh09.lee@samsung.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <common.h>
  23. #include <lcd.h>
  24. #include <linux/err.h>
  25. #include <asm/arch/dsim.h>
  26. #include <asm/arch/mipi_dsim.h>
  27. #include "exynos_mipi_dsi_lowlevel.h"
  28. #define MHZ (1000 * 1000)
  29. #define FIN_HZ (24 * MHZ)
  30. #define DFIN_PLL_MIN_HZ (6 * MHZ)
  31. #define DFIN_PLL_MAX_HZ (12 * MHZ)
  32. #define DFVCO_MIN_HZ (500 * MHZ)
  33. #define DFVCO_MAX_HZ (1000 * MHZ)
  34. #define TRY_GET_FIFO_TIMEOUT (5000 * 2)
  35. /* MIPI-DSIM status types. */
  36. enum {
  37. DSIM_STATE_INIT, /* should be initialized. */
  38. DSIM_STATE_STOP, /* CPU and LCDC are LP mode. */
  39. DSIM_STATE_HSCLKEN, /* HS clock was enabled. */
  40. DSIM_STATE_ULPS
  41. };
  42. /* define DSI lane types. */
  43. enum {
  44. DSIM_LANE_CLOCK = (1 << 0),
  45. DSIM_LANE_DATA0 = (1 << 1),
  46. DSIM_LANE_DATA1 = (1 << 2),
  47. DSIM_LANE_DATA2 = (1 << 3),
  48. DSIM_LANE_DATA3 = (1 << 4)
  49. };
  50. static unsigned int dpll_table[15] = {
  51. 100, 120, 170, 220, 270,
  52. 320, 390, 450, 510, 560,
  53. 640, 690, 770, 870, 950
  54. };
  55. static void exynos_mipi_dsi_long_data_wr(struct mipi_dsim_device *dsim,
  56. unsigned int data0, unsigned int data1)
  57. {
  58. unsigned int data_cnt = 0, payload = 0;
  59. /* in case that data count is more then 4 */
  60. for (data_cnt = 0; data_cnt < data1; data_cnt += 4) {
  61. /*
  62. * after sending 4bytes per one time,
  63. * send remainder data less then 4.
  64. */
  65. if ((data1 - data_cnt) < 4) {
  66. if ((data1 - data_cnt) == 3) {
  67. payload = *(u8 *)(data0 + data_cnt) |
  68. (*(u8 *)(data0 + (data_cnt + 1))) << 8 |
  69. (*(u8 *)(data0 + (data_cnt + 2))) << 16;
  70. debug("count = 3 payload = %x, %x %x %x\n",
  71. payload, *(u8 *)(data0 + data_cnt),
  72. *(u8 *)(data0 + (data_cnt + 1)),
  73. *(u8 *)(data0 + (data_cnt + 2)));
  74. } else if ((data1 - data_cnt) == 2) {
  75. payload = *(u8 *)(data0 + data_cnt) |
  76. (*(u8 *)(data0 + (data_cnt + 1))) << 8;
  77. debug("count = 2 payload = %x, %x %x\n", payload,
  78. *(u8 *)(data0 + data_cnt),
  79. *(u8 *)(data0 + (data_cnt + 1)));
  80. } else if ((data1 - data_cnt) == 1) {
  81. payload = *(u8 *)(data0 + data_cnt);
  82. }
  83. } else {
  84. /* send 4bytes per one time. */
  85. payload = *(u8 *)(data0 + data_cnt) |
  86. (*(u8 *)(data0 + (data_cnt + 1))) << 8 |
  87. (*(u8 *)(data0 + (data_cnt + 2))) << 16 |
  88. (*(u8 *)(data0 + (data_cnt + 3))) << 24;
  89. debug("count = 4 payload = %x, %x %x %x %x\n",
  90. payload, *(u8 *)(data0 + data_cnt),
  91. *(u8 *)(data0 + (data_cnt + 1)),
  92. *(u8 *)(data0 + (data_cnt + 2)),
  93. *(u8 *)(data0 + (data_cnt + 3)));
  94. }
  95. exynos_mipi_dsi_wr_tx_data(dsim, payload);
  96. }
  97. }
  98. int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
  99. unsigned int data0, unsigned int data1)
  100. {
  101. unsigned int timeout = TRY_GET_FIFO_TIMEOUT;
  102. unsigned long delay_val, delay;
  103. unsigned int check_rx_ack = 0;
  104. if (dsim->state == DSIM_STATE_ULPS) {
  105. debug("state is ULPS.\n");
  106. return -EINVAL;
  107. }
  108. delay_val = MHZ / dsim->dsim_config->esc_clk;
  109. delay = 10 * delay_val;
  110. mdelay(delay);
  111. /* only if transfer mode is LPDT, wait SFR becomes empty. */
  112. if (dsim->state == DSIM_STATE_STOP) {
  113. while (!(exynos_mipi_dsi_get_fifo_state(dsim) &
  114. SFR_HEADER_EMPTY)) {
  115. if ((timeout--) > 0)
  116. mdelay(1);
  117. else {
  118. debug("SRF header fifo is not empty.\n");
  119. return -EINVAL;
  120. }
  121. }
  122. }
  123. switch (data_id) {
  124. /* short packet types of packet types for command. */
  125. case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
  126. case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
  127. case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
  128. case MIPI_DSI_DCS_SHORT_WRITE:
  129. case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
  130. case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
  131. debug("data0 = %x data1 = %x\n",
  132. data0, data1);
  133. exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0, data1);
  134. if (check_rx_ack) {
  135. /* process response func should be implemented */
  136. return 0;
  137. } else {
  138. return -EINVAL;
  139. }
  140. /* general command */
  141. case MIPI_DSI_COLOR_MODE_OFF:
  142. case MIPI_DSI_COLOR_MODE_ON:
  143. case MIPI_DSI_SHUTDOWN_PERIPHERAL:
  144. case MIPI_DSI_TURN_ON_PERIPHERAL:
  145. exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0, data1);
  146. if (check_rx_ack) {
  147. /* process response func should be implemented. */
  148. return 0;
  149. } else {
  150. return -EINVAL;
  151. }
  152. /* packet types for video data */
  153. case MIPI_DSI_V_SYNC_START:
  154. case MIPI_DSI_V_SYNC_END:
  155. case MIPI_DSI_H_SYNC_START:
  156. case MIPI_DSI_H_SYNC_END:
  157. case MIPI_DSI_END_OF_TRANSMISSION:
  158. return 0;
  159. /* short and response packet types for command */
  160. case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
  161. case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
  162. case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
  163. case MIPI_DSI_DCS_READ:
  164. exynos_mipi_dsi_clear_all_interrupt(dsim);
  165. exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0, data1);
  166. /* process response func should be implemented. */
  167. return 0;
  168. /* long packet type and null packet */
  169. case MIPI_DSI_NULL_PACKET:
  170. case MIPI_DSI_BLANKING_PACKET:
  171. return 0;
  172. case MIPI_DSI_GENERIC_LONG_WRITE:
  173. case MIPI_DSI_DCS_LONG_WRITE:
  174. {
  175. unsigned int data_cnt = 0, payload = 0;
  176. /* if data count is less then 4, then send 3bytes data. */
  177. if (data1 < 4) {
  178. payload = *(u8 *)(data0) |
  179. *(u8 *)(data0 + 1) << 8 |
  180. *(u8 *)(data0 + 2) << 16;
  181. exynos_mipi_dsi_wr_tx_data(dsim, payload);
  182. debug("count = %d payload = %x,%x %x %x\n",
  183. data1, payload,
  184. *(u8 *)(data0 + data_cnt),
  185. *(u8 *)(data0 + (data_cnt + 1)),
  186. *(u8 *)(data0 + (data_cnt + 2)));
  187. } else {
  188. /* in case that data count is more then 4 */
  189. exynos_mipi_dsi_long_data_wr(dsim, data0, data1);
  190. }
  191. /* put data into header fifo */
  192. exynos_mipi_dsi_wr_tx_header(dsim, data_id, data1 & 0xff,
  193. (data1 & 0xff00) >> 8);
  194. }
  195. if (check_rx_ack)
  196. /* process response func should be implemented. */
  197. return 0;
  198. else
  199. return -EINVAL;
  200. /* packet typo for video data */
  201. case MIPI_DSI_PACKED_PIXEL_STREAM_16:
  202. case MIPI_DSI_PACKED_PIXEL_STREAM_18:
  203. case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
  204. case MIPI_DSI_PACKED_PIXEL_STREAM_24:
  205. if (check_rx_ack) {
  206. /* process response func should be implemented. */
  207. return 0;
  208. } else {
  209. return -EINVAL;
  210. }
  211. default:
  212. debug("data id %x is not supported current DSI spec.\n",
  213. data_id);
  214. return -EINVAL;
  215. }
  216. return 0;
  217. }
  218. int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim, unsigned int enable)
  219. {
  220. int sw_timeout;
  221. if (enable) {
  222. sw_timeout = 1000;
  223. exynos_mipi_dsi_clear_interrupt(dsim);
  224. exynos_mipi_dsi_enable_pll(dsim, 1);
  225. while (1) {
  226. sw_timeout--;
  227. if (exynos_mipi_dsi_is_pll_stable(dsim))
  228. return 0;
  229. if (sw_timeout == 0)
  230. return -EINVAL;
  231. }
  232. } else
  233. exynos_mipi_dsi_enable_pll(dsim, 0);
  234. return 0;
  235. }
  236. unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
  237. unsigned int pre_divider, unsigned int main_divider,
  238. unsigned int scaler)
  239. {
  240. unsigned long dfin_pll, dfvco, dpll_out;
  241. unsigned int i, freq_band = 0xf;
  242. dfin_pll = (FIN_HZ / pre_divider);
  243. /******************************************************
  244. * Serial Clock(=ByteClk X 8) FreqBand[3:0] *
  245. ******************************************************
  246. * ~ 99.99 MHz 0000
  247. * 100 ~ 119.99 MHz 0001
  248. * 120 ~ 159.99 MHz 0010
  249. * 160 ~ 199.99 MHz 0011
  250. * 200 ~ 239.99 MHz 0100
  251. * 140 ~ 319.99 MHz 0101
  252. * 320 ~ 389.99 MHz 0110
  253. * 390 ~ 449.99 MHz 0111
  254. * 450 ~ 509.99 MHz 1000
  255. * 510 ~ 559.99 MHz 1001
  256. * 560 ~ 639.99 MHz 1010
  257. * 640 ~ 689.99 MHz 1011
  258. * 690 ~ 769.99 MHz 1100
  259. * 770 ~ 869.99 MHz 1101
  260. * 870 ~ 949.99 MHz 1110
  261. * 950 ~ 1000 MHz 1111
  262. ******************************************************/
  263. if (dfin_pll < DFIN_PLL_MIN_HZ || dfin_pll > DFIN_PLL_MAX_HZ) {
  264. debug("fin_pll range should be 6MHz ~ 12MHz\n");
  265. exynos_mipi_dsi_enable_afc(dsim, 0, 0);
  266. } else {
  267. if (dfin_pll < 7 * MHZ)
  268. exynos_mipi_dsi_enable_afc(dsim, 1, 0x1);
  269. else if (dfin_pll < 8 * MHZ)
  270. exynos_mipi_dsi_enable_afc(dsim, 1, 0x0);
  271. else if (dfin_pll < 9 * MHZ)
  272. exynos_mipi_dsi_enable_afc(dsim, 1, 0x3);
  273. else if (dfin_pll < 10 * MHZ)
  274. exynos_mipi_dsi_enable_afc(dsim, 1, 0x2);
  275. else if (dfin_pll < 11 * MHZ)
  276. exynos_mipi_dsi_enable_afc(dsim, 1, 0x5);
  277. else
  278. exynos_mipi_dsi_enable_afc(dsim, 1, 0x4);
  279. }
  280. dfvco = dfin_pll * main_divider;
  281. debug("dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
  282. dfvco, dfin_pll, main_divider);
  283. if (dfvco < DFVCO_MIN_HZ || dfvco > DFVCO_MAX_HZ)
  284. debug("fvco range should be 500MHz ~ 1000MHz\n");
  285. dpll_out = dfvco / (1 << scaler);
  286. debug("dpll_out = %lu, dfvco = %lu, scaler = %d\n",
  287. dpll_out, dfvco, scaler);
  288. for (i = 0; i < ARRAY_SIZE(dpll_table); i++) {
  289. if (dpll_out < dpll_table[i] * MHZ) {
  290. freq_band = i;
  291. break;
  292. }
  293. }
  294. debug("freq_band = %d\n", freq_band);
  295. exynos_mipi_dsi_pll_freq(dsim, pre_divider, main_divider, scaler);
  296. exynos_mipi_dsi_hs_zero_ctrl(dsim, 0);
  297. exynos_mipi_dsi_prep_ctrl(dsim, 0);
  298. /* Freq Band */
  299. exynos_mipi_dsi_pll_freq_band(dsim, freq_band);
  300. /* Stable time */
  301. exynos_mipi_dsi_pll_stable_time(dsim,
  302. dsim->dsim_config->pll_stable_time);
  303. /* Enable PLL */
  304. debug("FOUT of mipi dphy pll is %luMHz\n",
  305. (dpll_out / MHZ));
  306. return dpll_out;
  307. }
  308. int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
  309. unsigned int byte_clk_sel, unsigned int enable)
  310. {
  311. unsigned int esc_div;
  312. unsigned long esc_clk_error_rate;
  313. unsigned long hs_clk = 0, byte_clk = 0, escape_clk = 0;
  314. if (enable) {
  315. dsim->e_clk_src = byte_clk_sel;
  316. /* Escape mode clock and byte clock source */
  317. exynos_mipi_dsi_set_byte_clock_src(dsim, byte_clk_sel);
  318. /* DPHY, DSIM Link : D-PHY clock out */
  319. if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
  320. hs_clk = exynos_mipi_dsi_change_pll(dsim,
  321. dsim->dsim_config->p, dsim->dsim_config->m,
  322. dsim->dsim_config->s);
  323. if (hs_clk == 0) {
  324. debug("failed to get hs clock.\n");
  325. return -EINVAL;
  326. }
  327. byte_clk = hs_clk / 8;
  328. exynos_mipi_dsi_enable_pll_bypass(dsim, 0);
  329. exynos_mipi_dsi_pll_on(dsim, 1);
  330. /* DPHY : D-PHY clock out, DSIM link : external clock out */
  331. } else if (byte_clk_sel == DSIM_EXT_CLK_DIV8)
  332. debug("not support EXT CLK source for MIPI DSIM\n");
  333. else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS)
  334. debug("not support EXT CLK source for MIPI DSIM\n");
  335. /* escape clock divider */
  336. esc_div = byte_clk / (dsim->dsim_config->esc_clk);
  337. debug("esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
  338. esc_div, byte_clk, dsim->dsim_config->esc_clk);
  339. if ((byte_clk / esc_div) >= (20 * MHZ) ||
  340. (byte_clk / esc_div) > dsim->dsim_config->esc_clk)
  341. esc_div += 1;
  342. escape_clk = byte_clk / esc_div;
  343. debug("escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
  344. escape_clk, byte_clk, esc_div);
  345. /* enable escape clock. */
  346. exynos_mipi_dsi_enable_byte_clock(dsim, 1);
  347. /* enable byte clk and escape clock */
  348. exynos_mipi_dsi_set_esc_clk_prs(dsim, 1, esc_div);
  349. /* escape clock on lane */
  350. exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
  351. (DSIM_LANE_CLOCK | dsim->data_lane), 1);
  352. debug("byte clock is %luMHz\n",
  353. (byte_clk / MHZ));
  354. debug("escape clock that user's need is %lu\n",
  355. (dsim->dsim_config->esc_clk / MHZ));
  356. debug("escape clock divider is %x\n", esc_div);
  357. debug("escape clock is %luMHz\n",
  358. ((byte_clk / esc_div) / MHZ));
  359. if ((byte_clk / esc_div) > escape_clk) {
  360. esc_clk_error_rate = escape_clk /
  361. (byte_clk / esc_div);
  362. debug("error rate is %lu over.\n",
  363. (esc_clk_error_rate / 100));
  364. } else if ((byte_clk / esc_div) < (escape_clk)) {
  365. esc_clk_error_rate = (byte_clk / esc_div) /
  366. escape_clk;
  367. debug("error rate is %lu under.\n",
  368. (esc_clk_error_rate / 100));
  369. }
  370. } else {
  371. exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
  372. (DSIM_LANE_CLOCK | dsim->data_lane), 0);
  373. exynos_mipi_dsi_set_esc_clk_prs(dsim, 0, 0);
  374. /* disable escape clock. */
  375. exynos_mipi_dsi_enable_byte_clock(dsim, 0);
  376. if (byte_clk_sel == DSIM_PLL_OUT_DIV8)
  377. exynos_mipi_dsi_pll_on(dsim, 0);
  378. }
  379. return 0;
  380. }
  381. int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
  382. {
  383. dsim->state = DSIM_STATE_INIT;
  384. switch (dsim->dsim_config->e_no_data_lane) {
  385. case DSIM_DATA_LANE_1:
  386. dsim->data_lane = DSIM_LANE_DATA0;
  387. break;
  388. case DSIM_DATA_LANE_2:
  389. dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
  390. break;
  391. case DSIM_DATA_LANE_3:
  392. dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
  393. DSIM_LANE_DATA2;
  394. break;
  395. case DSIM_DATA_LANE_4:
  396. dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
  397. DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
  398. break;
  399. default:
  400. debug("data lane is invalid.\n");
  401. return -EINVAL;
  402. };
  403. exynos_mipi_dsi_sw_reset(dsim);
  404. exynos_mipi_dsi_dp_dn_swap(dsim, 0);
  405. return 0;
  406. }
  407. int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
  408. unsigned int enable)
  409. {
  410. /* enable only frame done interrupt */
  411. exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
  412. return 0;
  413. }
  414. static void convert_to_fb_videomode(struct fb_videomode *mode1,
  415. vidinfo_t *mode2)
  416. {
  417. mode1->xres = mode2->vl_width;
  418. mode1->yres = mode2->vl_height;
  419. mode1->upper_margin = mode2->vl_vfpd;
  420. mode1->lower_margin = mode2->vl_vbpd;
  421. mode1->left_margin = mode2->vl_hfpd;
  422. mode1->right_margin = mode2->vl_hbpd;
  423. mode1->vsync_len = mode2->vl_vspw;
  424. mode1->hsync_len = mode2->vl_hspw;
  425. }
  426. int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
  427. struct mipi_dsim_config *dsim_config)
  428. {
  429. struct exynos_platform_mipi_dsim *dsim_pd;
  430. struct fb_videomode lcd_video;
  431. vidinfo_t *vid;
  432. dsim_pd = (struct exynos_platform_mipi_dsim *)dsim->pd;
  433. vid = (vidinfo_t *)dsim_pd->lcd_panel_info;
  434. convert_to_fb_videomode(&lcd_video, vid);
  435. /* in case of VIDEO MODE (RGB INTERFACE), it sets polarities. */
  436. if (dsim->dsim_config->e_interface == (u32) DSIM_VIDEO) {
  437. if (dsim->dsim_config->auto_vertical_cnt == 0) {
  438. exynos_mipi_dsi_set_main_disp_vporch(dsim,
  439. vid->vl_cmd_allow_len,
  440. lcd_video.upper_margin,
  441. lcd_video.lower_margin);
  442. exynos_mipi_dsi_set_main_disp_hporch(dsim,
  443. lcd_video.left_margin,
  444. lcd_video.right_margin);
  445. exynos_mipi_dsi_set_main_disp_sync_area(dsim,
  446. lcd_video.vsync_len,
  447. lcd_video.hsync_len);
  448. }
  449. }
  450. exynos_mipi_dsi_set_main_disp_resol(dsim, lcd_video.xres,
  451. lcd_video.yres);
  452. exynos_mipi_dsi_display_config(dsim, dsim->dsim_config);
  453. debug("lcd panel ==> width = %d, height = %d\n",
  454. lcd_video.xres, lcd_video.yres);
  455. return 0;
  456. }
  457. int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim)
  458. {
  459. unsigned int time_out = 100;
  460. switch (dsim->state) {
  461. case DSIM_STATE_INIT:
  462. exynos_mipi_dsi_init_fifo_pointer(dsim, 0x1f);
  463. /* dsi configuration */
  464. exynos_mipi_dsi_init_config(dsim);
  465. exynos_mipi_dsi_enable_lane(dsim, DSIM_LANE_CLOCK, 1);
  466. exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 1);
  467. /* set clock configuration */
  468. exynos_mipi_dsi_set_clock(dsim,
  469. dsim->dsim_config->e_byte_clk, 1);
  470. /* check clock and data lane state are stop state */
  471. while (!(exynos_mipi_dsi_is_lane_state(dsim))) {
  472. time_out--;
  473. if (time_out == 0) {
  474. debug("DSI Master is not stop state.\n");
  475. debug("Check initialization process\n");
  476. return -EINVAL;
  477. }
  478. }
  479. dsim->state = DSIM_STATE_STOP;
  480. /* BTA sequence counters */
  481. exynos_mipi_dsi_set_stop_state_counter(dsim,
  482. dsim->dsim_config->stop_holding_cnt);
  483. exynos_mipi_dsi_set_bta_timeout(dsim,
  484. dsim->dsim_config->bta_timeout);
  485. exynos_mipi_dsi_set_lpdr_timeout(dsim,
  486. dsim->dsim_config->rx_timeout);
  487. return 0;
  488. default:
  489. debug("DSI Master is already init.\n");
  490. return 0;
  491. }
  492. return 0;
  493. }
  494. int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
  495. {
  496. if (dsim->state == DSIM_STATE_STOP) {
  497. if (dsim->e_clk_src != DSIM_EXT_CLK_BYPASS) {
  498. dsim->state = DSIM_STATE_HSCLKEN;
  499. /* set LCDC and CPU transfer mode to HS. */
  500. exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
  501. exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
  502. exynos_mipi_dsi_enable_hs_clock(dsim, 1);
  503. return 0;
  504. } else
  505. debug("clock source is external bypass.\n");
  506. } else
  507. debug("DSIM is not stop state.\n");
  508. return 0;
  509. }
  510. int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
  511. unsigned int mode)
  512. {
  513. if (mode) {
  514. if (dsim->state != DSIM_STATE_HSCLKEN) {
  515. debug("HS Clock lane is not enabled.\n");
  516. return -EINVAL;
  517. }
  518. exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
  519. } else {
  520. if (dsim->state == DSIM_STATE_INIT || dsim->state ==
  521. DSIM_STATE_ULPS) {
  522. debug("DSI Master is not STOP or HSDT state.\n");
  523. return -EINVAL;
  524. }
  525. exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
  526. }
  527. return 0;
  528. }
  529. int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
  530. {
  531. return _exynos_mipi_dsi_get_frame_done_status(dsim);
  532. }
  533. int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
  534. {
  535. _exynos_mipi_dsi_clear_frame_done(dsim);
  536. return 0;
  537. }