msm_dss_io_7x27a.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/clk.h>
  14. #include "msm_fb.h"
  15. #include "mipi_dsi.h"
  16. /* multimedia sub system sfpb */
  17. char *mmss_sfpb_base;
  18. void __iomem *periph_base;
  19. static struct dsi_clk_desc dsicore_clk;
  20. static struct dsi_clk_desc dsi_pclk;
  21. static struct clk *dsi_byte_div_clk;
  22. static struct clk *dsi_esc_clk;
  23. static struct clk *dsi_pixel_clk;
  24. static struct clk *dsi_clk;
  25. static struct clk *dsi_ref_clk;
  26. static struct clk *mdp_dsi_pclk;
  27. static struct clk *ahb_m_clk;
  28. static struct clk *ahb_s_clk;
  29. static struct clk *ebi1_dsi_clk;
  30. int mipi_dsi_clk_on;
  31. int mipi_dsi_clk_init(struct platform_device *pdev)
  32. {
  33. struct device *dev = &pdev->dev;
  34. dsi_esc_clk = clk_get(dev, "esc_clk");
  35. if (IS_ERR_OR_NULL(dsi_esc_clk)) {
  36. printk(KERN_ERR "can't find dsi_esc_clk\n");
  37. dsi_esc_clk = NULL;
  38. goto mipi_dsi_clk_err;
  39. }
  40. dsi_byte_div_clk = clk_get(dev, "byte_clk");
  41. if (IS_ERR_OR_NULL(dsi_byte_div_clk)) {
  42. pr_err("can't find dsi_byte_div_clk\n");
  43. dsi_byte_div_clk = NULL;
  44. goto mipi_dsi_clk_err;
  45. }
  46. dsi_pixel_clk = clk_get(dev, "pixel_clk");
  47. if (IS_ERR_OR_NULL(dsi_pixel_clk)) {
  48. pr_err("can't find dsi_pixel_clk\n");
  49. dsi_pixel_clk = NULL;
  50. goto mipi_dsi_clk_err;
  51. }
  52. dsi_clk = clk_get(dev, "core_clk");
  53. if (IS_ERR_OR_NULL(dsi_clk)) {
  54. pr_err("can't find dsi_clk\n");
  55. dsi_clk = NULL;
  56. goto mipi_dsi_clk_err;
  57. }
  58. dsi_ref_clk = clk_get(dev, "ref_clk");
  59. if (IS_ERR_OR_NULL(dsi_ref_clk)) {
  60. pr_err("can't find dsi_ref_clk\n");
  61. dsi_ref_clk = NULL;
  62. goto mipi_dsi_clk_err;
  63. }
  64. mdp_dsi_pclk = clk_get(dev, "mdp_clk");
  65. if (IS_ERR_OR_NULL(mdp_dsi_pclk)) {
  66. pr_err("can't find mdp_dsi_pclk\n");
  67. mdp_dsi_pclk = NULL;
  68. goto mipi_dsi_clk_err;
  69. }
  70. ahb_m_clk = clk_get(dev, "master_iface_clk");
  71. if (IS_ERR_OR_NULL(ahb_m_clk)) {
  72. pr_err("can't find ahb_m_clk\n");
  73. ahb_m_clk = NULL;
  74. goto mipi_dsi_clk_err;
  75. }
  76. ahb_s_clk = clk_get(dev, "slave_iface_clk");
  77. if (IS_ERR_OR_NULL(ahb_s_clk)) {
  78. pr_err("can't find ahb_s_clk\n");
  79. ahb_s_clk = NULL;
  80. goto mipi_dsi_clk_err;
  81. }
  82. ebi1_dsi_clk = clk_get(dev, "mem_clk");
  83. if (IS_ERR_OR_NULL(ebi1_dsi_clk)) {
  84. pr_err("can't find ebi1_dsi_clk\n");
  85. ebi1_dsi_clk = NULL;
  86. goto mipi_dsi_clk_err;
  87. }
  88. return 0;
  89. mipi_dsi_clk_err:
  90. mipi_dsi_clk_deinit(NULL);
  91. return -EPERM;
  92. }
  93. void mipi_dsi_clk_deinit(struct device *dev)
  94. {
  95. if (mdp_dsi_pclk)
  96. clk_put(mdp_dsi_pclk);
  97. if (ahb_m_clk)
  98. clk_put(ahb_m_clk);
  99. if (ahb_s_clk)
  100. clk_put(ahb_s_clk);
  101. if (dsi_ref_clk)
  102. clk_put(dsi_ref_clk);
  103. if (dsi_byte_div_clk)
  104. clk_put(dsi_byte_div_clk);
  105. if (dsi_esc_clk)
  106. clk_put(dsi_esc_clk);
  107. if (ebi1_dsi_clk)
  108. clk_put(ebi1_dsi_clk);
  109. }
  110. static void mipi_dsi_clk_ctrl(struct dsi_clk_desc *clk, int clk_en)
  111. {
  112. uint32 data;
  113. if (clk_en) {
  114. data = (clk->pre_div_func) << 24 |
  115. (clk->m) << 16 | (clk->n) << 8 |
  116. ((clk->d) * 2);
  117. clk_set_rate(dsi_clk, data);
  118. clk_enable(dsi_clk);
  119. } else
  120. clk_disable(dsi_clk);
  121. }
  122. static void mipi_dsi_pclk_ctrl(struct dsi_clk_desc *clk, int clk_en)
  123. {
  124. uint32 data;
  125. if (clk_en) {
  126. data = (clk->pre_div_func) << 24 | (clk->m) << 16
  127. | (clk->n) << 8 | ((clk->d) * 2);
  128. if ((clk_set_rate(dsi_pixel_clk, data)) < 0)
  129. pr_err("%s: pixel clk set rate failed\n", __func__);
  130. if (clk_enable(dsi_pixel_clk))
  131. pr_err("%s clk enable failed\n", __func__);
  132. } else {
  133. clk_disable(dsi_pixel_clk);
  134. }
  135. }
  136. static void mipi_dsi_calibration(void)
  137. {
  138. MIPI_OUTP(MIPI_DSI_BASE + 0xf8, 0x00a105a1); /* cal_hw_ctrl */
  139. }
  140. #define PREF_DIV_RATIO 19
  141. struct dsiphy_pll_divider_config pll_divider_config;
  142. int mipi_dsi_clk_div_config(uint8 bpp, uint8 lanes,
  143. uint32 *expected_dsi_pclk)
  144. {
  145. u32 fb_divider, rate, vco;
  146. u32 div_ratio = 0;
  147. struct dsi_clk_mnd_table const *mnd_entry = mnd_table;
  148. if (pll_divider_config.clk_rate == 0)
  149. pll_divider_config.clk_rate = 454000000;
  150. rate = pll_divider_config.clk_rate / 1000000; /* In Mhz */
  151. if (rate < 125) {
  152. vco = rate * 8;
  153. div_ratio = 8;
  154. } else if (rate < 250) {
  155. vco = rate * 4;
  156. div_ratio = 4;
  157. } else if (rate < 500) {
  158. vco = rate * 2;
  159. div_ratio = 2;
  160. } else {
  161. vco = rate * 1;
  162. div_ratio = 1;
  163. }
  164. /* find the mnd settings from mnd_table entry */
  165. for (; mnd_entry != mnd_table + ARRAY_SIZE(mnd_table); ++mnd_entry) {
  166. if (((mnd_entry->lanes) == lanes) &&
  167. ((mnd_entry->bpp) == bpp))
  168. break;
  169. }
  170. if (mnd_entry == mnd_table + ARRAY_SIZE(mnd_table)) {
  171. pr_err("%s: requested Lanes, %u & BPP, %u, not supported\n",
  172. __func__, lanes, bpp);
  173. return -EINVAL;
  174. }
  175. fb_divider = ((vco * PREF_DIV_RATIO) / 27);
  176. pll_divider_config.fb_divider = fb_divider;
  177. pll_divider_config.ref_divider_ratio = PREF_DIV_RATIO;
  178. pll_divider_config.bit_clk_divider = div_ratio;
  179. pll_divider_config.byte_clk_divider =
  180. pll_divider_config.bit_clk_divider * 8;
  181. pll_divider_config.dsi_clk_divider =
  182. (mnd_entry->dsiclk_div) * div_ratio;
  183. if ((mnd_entry->dsiclk_d == 0)
  184. || (mnd_entry->dsiclk_m == 1)) {
  185. dsicore_clk.mnd_mode = 0;
  186. dsicore_clk.src = 0x3;
  187. dsicore_clk.pre_div_func = (mnd_entry->dsiclk_n - 1);
  188. } else {
  189. dsicore_clk.mnd_mode = 2;
  190. dsicore_clk.src = 0x3;
  191. dsicore_clk.m = mnd_entry->dsiclk_m;
  192. dsicore_clk.n = mnd_entry->dsiclk_n;
  193. dsicore_clk.d = mnd_entry->dsiclk_d;
  194. }
  195. if ((mnd_entry->pclk_d == 0)
  196. || (mnd_entry->pclk_m == 1)) {
  197. dsi_pclk.mnd_mode = 0;
  198. dsi_pclk.src = 0x3;
  199. dsi_pclk.pre_div_func = (mnd_entry->pclk_n - 1);
  200. *expected_dsi_pclk = ((vco * 1000000) /
  201. ((pll_divider_config.dsi_clk_divider)
  202. * (mnd_entry->pclk_n)));
  203. } else {
  204. dsi_pclk.mnd_mode = 2;
  205. dsi_pclk.src = 0x3;
  206. dsi_pclk.m = mnd_entry->pclk_m;
  207. dsi_pclk.n = mnd_entry->pclk_n;
  208. dsi_pclk.d = mnd_entry->pclk_d;
  209. *expected_dsi_pclk = ((vco * 1000000 * dsi_pclk.m) /
  210. ((pll_divider_config.dsi_clk_divider)
  211. * (mnd_entry->pclk_n)));
  212. }
  213. dsicore_clk.m = 1;
  214. dsicore_clk.n = 1;
  215. dsicore_clk.d = 2;
  216. dsicore_clk.pre_div_func = 0;
  217. dsi_pclk.m = 1;
  218. dsi_pclk.n = 3;
  219. dsi_pclk.d = 2;
  220. dsi_pclk.pre_div_func = 0;
  221. return 0;
  222. }
  223. void mipi_dsi_phy_init(int panel_ndx, struct msm_panel_info const *panel_info,
  224. int target_type)
  225. {
  226. struct mipi_dsi_phy_ctrl *pd;
  227. int i, off;
  228. MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0001);/* start phy sw reset */
  229. wmb();
  230. usleep(1000);
  231. MIPI_OUTP(MIPI_DSI_BASE + 0x128, 0x0000);/* end phy w reset */
  232. wmb();
  233. usleep(1000);
  234. MIPI_OUTP(MIPI_DSI_BASE + 0x2cc, 0x0003);/* regulator_ctrl_0 */
  235. MIPI_OUTP(MIPI_DSI_BASE + 0x2d0, 0x0001);/* regulator_ctrl_1 */
  236. MIPI_OUTP(MIPI_DSI_BASE + 0x2d4, 0x0001);/* regulator_ctrl_2 */
  237. MIPI_OUTP(MIPI_DSI_BASE + 0x2d8, 0x0000);/* regulator_ctrl_3 */
  238. #ifdef DSI_POWER
  239. MIPI_OUTP(MIPI_DSI_BASE + 0x2dc, 0x0100);/* regulator_ctrl_4 */
  240. #endif
  241. pd = (panel_info->mipi).dsi_phy_db;
  242. off = 0x02cc; /* regulator ctrl 0 */
  243. for (i = 0; i < 4; i++) {
  244. MIPI_OUTP(MIPI_DSI_BASE + off, pd->regulator[i]);
  245. wmb();
  246. off += 4;
  247. }
  248. off = 0x0260; /* phy timig ctrl 0 */
  249. for (i = 0; i < 11; i++) {
  250. MIPI_OUTP(MIPI_DSI_BASE + off, pd->timing[i]);
  251. wmb();
  252. off += 4;
  253. }
  254. off = 0x0290; /* ctrl 0 */
  255. for (i = 0; i < 4; i++) {
  256. MIPI_OUTP(MIPI_DSI_BASE + off, pd->ctrl[i]);
  257. wmb();
  258. off += 4;
  259. }
  260. off = 0x02a0; /* strength 0 */
  261. for (i = 0; i < 4; i++) {
  262. MIPI_OUTP(MIPI_DSI_BASE + off, pd->strength[i]);
  263. wmb();
  264. off += 4;
  265. }
  266. mipi_dsi_calibration();
  267. off = 0x0204; /* pll ctrl 1, skip 0 */
  268. for (i = 1; i < 21; i++) {
  269. MIPI_OUTP(MIPI_DSI_BASE + off, pd->pll[i]);
  270. wmb();
  271. off += 4;
  272. }
  273. MIPI_OUTP(MIPI_DSI_BASE + 0x100, 0x67);
  274. /* pll ctrl 0 */
  275. MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pd->pll[0]);
  276. wmb();
  277. }
  278. void cont_splash_clk_ctrl(int enable)
  279. {
  280. static int cont_splash_clks_enabled;
  281. if (enable && !cont_splash_clks_enabled) {
  282. clk_prepare_enable(dsi_ref_clk);
  283. clk_prepare_enable(mdp_dsi_pclk);
  284. clk_prepare_enable(dsi_byte_div_clk);
  285. clk_prepare_enable(dsi_esc_clk);
  286. clk_prepare_enable(dsi_pixel_clk);
  287. clk_prepare_enable(dsi_clk);
  288. cont_splash_clks_enabled = 1;
  289. } else if (!enable && cont_splash_clks_enabled) {
  290. clk_disable_unprepare(dsi_clk);
  291. clk_disable_unprepare(dsi_pixel_clk);
  292. clk_disable_unprepare(dsi_esc_clk);
  293. clk_disable_unprepare(dsi_byte_div_clk);
  294. clk_disable_unprepare(mdp_dsi_pclk);
  295. clk_disable_unprepare(dsi_ref_clk);
  296. cont_splash_clks_enabled = 0;
  297. }
  298. }
  299. void mipi_dsi_prepare_clocks(void)
  300. {
  301. clk_prepare(dsi_ref_clk);
  302. clk_prepare(ahb_m_clk);
  303. clk_prepare(ahb_s_clk);
  304. clk_prepare(ebi1_dsi_clk);
  305. clk_prepare(mdp_dsi_pclk);
  306. clk_prepare(dsi_byte_div_clk);
  307. clk_prepare(dsi_esc_clk);
  308. clk_prepare(dsi_clk);
  309. clk_prepare(dsi_pixel_clk);
  310. }
  311. void mipi_dsi_unprepare_clocks(void)
  312. {
  313. clk_unprepare(dsi_esc_clk);
  314. clk_unprepare(dsi_byte_div_clk);
  315. clk_unprepare(mdp_dsi_pclk);
  316. clk_unprepare(ebi1_dsi_clk);
  317. clk_unprepare(ahb_m_clk);
  318. clk_unprepare(ahb_s_clk);
  319. clk_unprepare(dsi_ref_clk);
  320. clk_unprepare(dsi_clk);
  321. clk_unprepare(dsi_pixel_clk);
  322. }
  323. void mipi_dsi_ahb_ctrl(u32 enable)
  324. {
  325. static int ahb_ctrl_done;
  326. if (enable) {
  327. if (ahb_ctrl_done) {
  328. pr_info("%s: ahb clks already ON\n", __func__);
  329. return;
  330. }
  331. clk_enable(dsi_ref_clk);
  332. clk_enable(ahb_m_clk);
  333. clk_enable(ahb_s_clk);
  334. ahb_ctrl_done = 1;
  335. } else {
  336. if (ahb_ctrl_done == 0) {
  337. pr_info("%s: ahb clks already OFF\n", __func__);
  338. return;
  339. }
  340. clk_disable(ahb_m_clk);
  341. clk_disable(ahb_s_clk);
  342. clk_disable(dsi_ref_clk);
  343. ahb_ctrl_done = 0;
  344. }
  345. }
  346. void mipi_dsi_clk_enable(void)
  347. {
  348. unsigned data = 0;
  349. uint32 pll_ctrl;
  350. if (mipi_dsi_clk_on) {
  351. pr_info("%s: mipi_dsi_clks already ON\n", __func__);
  352. return;
  353. }
  354. if (clk_set_rate(ebi1_dsi_clk, 65000000)) /* 65 MHz */
  355. pr_err("%s: ebi1_dsi_clk set rate failed\n", __func__);
  356. clk_enable(ebi1_dsi_clk);
  357. pll_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0200);
  358. MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
  359. mb();
  360. clk_set_rate(dsi_byte_div_clk, data);
  361. clk_set_rate(dsi_esc_clk, data);
  362. clk_enable(mdp_dsi_pclk);
  363. clk_enable(dsi_byte_div_clk);
  364. clk_enable(dsi_esc_clk);
  365. mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
  366. mipi_dsi_clk_ctrl(&dsicore_clk, 1);
  367. mipi_dsi_clk_on = 1;
  368. }
  369. void mipi_dsi_clk_disable(void)
  370. {
  371. if (mipi_dsi_clk_on == 0) {
  372. pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
  373. return;
  374. }
  375. mipi_dsi_pclk_ctrl(&dsi_pclk, 0);
  376. mipi_dsi_clk_ctrl(&dsicore_clk, 0);
  377. clk_disable(dsi_esc_clk);
  378. clk_disable(dsi_byte_div_clk);
  379. clk_disable(mdp_dsi_pclk);
  380. /* DSIPHY_PLL_CTRL_0, disable dsi pll */
  381. MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
  382. if (clk_set_rate(ebi1_dsi_clk, 0))
  383. pr_err("%s: ebi1_dsi_clk set rate failed\n", __func__);
  384. clk_disable(ebi1_dsi_clk);
  385. mipi_dsi_clk_on = 0;
  386. }
  387. void mipi_dsi_phy_ctrl(int on)
  388. {
  389. if (on) {
  390. /* DSIPHY_PLL_CTRL_5 */
  391. MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x050);
  392. /* DSIPHY_TPA_CTRL_1 */
  393. MIPI_OUTP(MIPI_DSI_BASE + 0x0258, 0x00f);
  394. /* DSIPHY_TPA_CTRL_2 */
  395. MIPI_OUTP(MIPI_DSI_BASE + 0x025c, 0x000);
  396. } else {
  397. /* DSIPHY_PLL_CTRL_5 */
  398. MIPI_OUTP(MIPI_DSI_BASE + 0x0214, 0x05f);
  399. /* DSIPHY_TPA_CTRL_1 */
  400. MIPI_OUTP(MIPI_DSI_BASE + 0x0258, 0x08f);
  401. /* DSIPHY_TPA_CTRL_2 */
  402. MIPI_OUTP(MIPI_DSI_BASE + 0x025c, 0x001);
  403. /* DSIPHY_REGULATOR_CTRL_0 */
  404. MIPI_OUTP(MIPI_DSI_BASE + 0x02cc, 0x02);
  405. /* DSIPHY_CTRL_0 */
  406. MIPI_OUTP(MIPI_DSI_BASE + 0x0290, 0x00);
  407. /* DSIPHY_CTRL_1 */
  408. MIPI_OUTP(MIPI_DSI_BASE + 0x0294, 0x7f);
  409. /* disable dsi clk */
  410. MIPI_OUTP(MIPI_DSI_BASE + 0x0118, 0);
  411. }
  412. }
  413. #ifdef CONFIG_FB_MSM_MDP303
  414. void update_lane_config(struct msm_panel_info *pinfo)
  415. {
  416. struct mipi_dsi_phy_ctrl *pd;
  417. pd = (pinfo->mipi).dsi_phy_db;
  418. pinfo->mipi.data_lane1 = FALSE;
  419. pd->pll[10] |= 0x08;
  420. pinfo->yres = 320;
  421. pinfo->lcdc.h_back_porch = 15;
  422. pinfo->lcdc.h_front_porch = 21;
  423. pinfo->lcdc.h_pulse_width = 5;
  424. pinfo->lcdc.v_back_porch = 50;
  425. pinfo->lcdc.v_front_porch = 101;
  426. pinfo->lcdc.v_pulse_width = 50;
  427. }
  428. #endif