dsi_phy.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. * Copyright (c) 2015, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include "dsi.h"
  14. #include "dsi.xml.h"
  15. #define dsi_phy_read(offset) msm_readl((offset))
  16. #define dsi_phy_write(offset, data) msm_writel((data), (offset))
  17. struct dsi_dphy_timing {
  18. u32 clk_pre;
  19. u32 clk_post;
  20. u32 clk_zero;
  21. u32 clk_trail;
  22. u32 clk_prepare;
  23. u32 hs_exit;
  24. u32 hs_zero;
  25. u32 hs_prepare;
  26. u32 hs_trail;
  27. u32 hs_rqst;
  28. u32 ta_go;
  29. u32 ta_sure;
  30. u32 ta_get;
  31. };
  32. struct msm_dsi_phy {
  33. void __iomem *base;
  34. void __iomem *reg_base;
  35. int id;
  36. struct dsi_dphy_timing timing;
  37. int (*enable)(struct msm_dsi_phy *phy, bool is_dual_panel,
  38. const unsigned long bit_rate, const unsigned long esc_rate);
  39. int (*disable)(struct msm_dsi_phy *phy);
  40. };
  41. #define S_DIV_ROUND_UP(n, d) \
  42. (((n) >= 0) ? (((n) + (d) - 1) / (d)) : (((n) - (d) + 1) / (d)))
  43. static inline s32 linear_inter(s32 tmax, s32 tmin, s32 percent,
  44. s32 min_result, bool even)
  45. {
  46. s32 v;
  47. v = (tmax - tmin) * percent;
  48. v = S_DIV_ROUND_UP(v, 100) + tmin;
  49. if (even && (v & 0x1))
  50. return max_t(s32, min_result, v - 1);
  51. else
  52. return max_t(s32, min_result, v);
  53. }
  54. static void dsi_dphy_timing_calc_clk_zero(struct dsi_dphy_timing *timing,
  55. s32 ui, s32 coeff, s32 pcnt)
  56. {
  57. s32 tmax, tmin, clk_z;
  58. s32 temp;
  59. /* reset */
  60. temp = 300 * coeff - ((timing->clk_prepare >> 1) + 1) * 2 * ui;
  61. tmin = S_DIV_ROUND_UP(temp, ui) - 2;
  62. if (tmin > 255) {
  63. tmax = 511;
  64. clk_z = linear_inter(2 * tmin, tmin, pcnt, 0, true);
  65. } else {
  66. tmax = 255;
  67. clk_z = linear_inter(tmax, tmin, pcnt, 0, true);
  68. }
  69. /* adjust */
  70. temp = (timing->hs_rqst + timing->clk_prepare + clk_z) & 0x7;
  71. timing->clk_zero = clk_z + 8 - temp;
  72. }
  73. static int dsi_dphy_timing_calc(struct dsi_dphy_timing *timing,
  74. const unsigned long bit_rate, const unsigned long esc_rate)
  75. {
  76. s32 ui, lpx;
  77. s32 tmax, tmin;
  78. s32 pcnt0 = 10;
  79. s32 pcnt1 = (bit_rate > 1200000000) ? 15 : 10;
  80. s32 pcnt2 = 10;
  81. s32 pcnt3 = (bit_rate > 180000000) ? 10 : 40;
  82. s32 coeff = 1000; /* Precision, should avoid overflow */
  83. s32 temp;
  84. if (!bit_rate || !esc_rate)
  85. return -EINVAL;
  86. ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
  87. lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
  88. tmax = S_DIV_ROUND_UP(95 * coeff, ui) - 2;
  89. tmin = S_DIV_ROUND_UP(38 * coeff, ui) - 2;
  90. timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, true);
  91. temp = lpx / ui;
  92. if (temp & 0x1)
  93. timing->hs_rqst = temp;
  94. else
  95. timing->hs_rqst = max_t(s32, 0, temp - 2);
  96. /* Calculate clk_zero after clk_prepare and hs_rqst */
  97. dsi_dphy_timing_calc_clk_zero(timing, ui, coeff, pcnt2);
  98. temp = 105 * coeff + 12 * ui - 20 * coeff;
  99. tmax = S_DIV_ROUND_UP(temp, ui) - 2;
  100. tmin = S_DIV_ROUND_UP(60 * coeff, ui) - 2;
  101. timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, true);
  102. temp = 85 * coeff + 6 * ui;
  103. tmax = S_DIV_ROUND_UP(temp, ui) - 2;
  104. temp = 40 * coeff + 4 * ui;
  105. tmin = S_DIV_ROUND_UP(temp, ui) - 2;
  106. timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, true);
  107. tmax = 255;
  108. temp = ((timing->hs_prepare >> 1) + 1) * 2 * ui + 2 * ui;
  109. temp = 145 * coeff + 10 * ui - temp;
  110. tmin = S_DIV_ROUND_UP(temp, ui) - 2;
  111. timing->hs_zero = linear_inter(tmax, tmin, pcnt2, 24, true);
  112. temp = 105 * coeff + 12 * ui - 20 * coeff;
  113. tmax = S_DIV_ROUND_UP(temp, ui) - 2;
  114. temp = 60 * coeff + 4 * ui;
  115. tmin = DIV_ROUND_UP(temp, ui) - 2;
  116. timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, true);
  117. tmax = 255;
  118. tmin = S_DIV_ROUND_UP(100 * coeff, ui) - 2;
  119. timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, true);
  120. tmax = 63;
  121. temp = ((timing->hs_exit >> 1) + 1) * 2 * ui;
  122. temp = 60 * coeff + 52 * ui - 24 * ui - temp;
  123. tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
  124. timing->clk_post = linear_inter(tmax, tmin, pcnt2, 0, false);
  125. tmax = 63;
  126. temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui;
  127. temp += ((timing->clk_zero >> 1) + 1) * 2 * ui;
  128. temp += 8 * ui + lpx;
  129. tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
  130. if (tmin > tmax) {
  131. temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false) >> 1;
  132. timing->clk_pre = temp >> 1;
  133. temp = (2 * tmax - tmin) * pcnt2;
  134. } else {
  135. timing->clk_pre = linear_inter(tmax, tmin, pcnt2, 0, false);
  136. }
  137. timing->ta_go = 3;
  138. timing->ta_sure = 0;
  139. timing->ta_get = 4;
  140. DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
  141. timing->clk_pre, timing->clk_post, timing->clk_zero,
  142. timing->clk_trail, timing->clk_prepare, timing->hs_exit,
  143. timing->hs_zero, timing->hs_prepare, timing->hs_trail,
  144. timing->hs_rqst);
  145. return 0;
  146. }
  147. static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
  148. {
  149. void __iomem *base = phy->reg_base;
  150. if (!enable) {
  151. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
  152. return;
  153. }
  154. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
  155. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
  156. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
  157. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
  158. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x3);
  159. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
  160. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
  161. dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
  162. }
  163. static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel,
  164. const unsigned long bit_rate, const unsigned long esc_rate)
  165. {
  166. struct dsi_dphy_timing *timing = &phy->timing;
  167. int i;
  168. void __iomem *base = phy->base;
  169. DBG("");
  170. if (dsi_dphy_timing_calc(timing, bit_rate, esc_rate)) {
  171. pr_err("%s: D-PHY timing calculation failed\n", __func__);
  172. return -EINVAL;
  173. }
  174. dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_0, 0xff);
  175. dsi_28nm_phy_regulator_ctrl(phy, true);
  176. dsi_phy_write(base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
  177. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_0,
  178. DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
  179. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_1,
  180. DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
  181. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_2,
  182. DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
  183. if (timing->clk_zero & BIT(8))
  184. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_3,
  185. DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8);
  186. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_4,
  187. DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
  188. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_5,
  189. DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
  190. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_6,
  191. DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
  192. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_7,
  193. DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
  194. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_8,
  195. DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
  196. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_9,
  197. DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
  198. DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
  199. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_10,
  200. DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
  201. dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_11,
  202. DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
  203. dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
  204. dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
  205. dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_1, 0x6);
  206. for (i = 0; i < 4; i++) {
  207. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_0(i), 0);
  208. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_1(i), 0);
  209. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_2(i), 0);
  210. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_3(i), 0);
  211. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i), 0);
  212. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i), 0);
  213. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i), 0x1);
  214. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i), 0x97);
  215. }
  216. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(0), 0);
  217. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(1), 0x5);
  218. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(2), 0xa);
  219. dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(3), 0xf);
  220. dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_1, 0xc0);
  221. dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR0, 0x1);
  222. dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR1, 0xbb);
  223. dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
  224. if (is_dual_panel && (phy->id != DSI_CLOCK_MASTER))
  225. dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, 0x00);
  226. else
  227. dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, 0x01);
  228. return 0;
  229. }
  230. static int dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
  231. {
  232. dsi_phy_write(phy->base + REG_DSI_28nm_PHY_CTRL_0, 0);
  233. dsi_28nm_phy_regulator_ctrl(phy, false);
  234. /*
  235. * Wait for the registers writes to complete in order to
  236. * ensure that the phy is completely disabled
  237. */
  238. wmb();
  239. return 0;
  240. }
  241. #define dsi_phy_func_init(name) \
  242. do { \
  243. phy->enable = dsi_##name##_phy_enable; \
  244. phy->disable = dsi_##name##_phy_disable; \
  245. } while (0)
  246. struct msm_dsi_phy *msm_dsi_phy_init(struct platform_device *pdev,
  247. enum msm_dsi_phy_type type, int id)
  248. {
  249. struct msm_dsi_phy *phy;
  250. phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
  251. if (!phy)
  252. return NULL;
  253. phy->base = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
  254. if (IS_ERR_OR_NULL(phy->base)) {
  255. pr_err("%s: failed to map phy base\n", __func__);
  256. return NULL;
  257. }
  258. phy->reg_base = msm_ioremap(pdev, "dsi_phy_regulator", "DSI_PHY_REG");
  259. if (IS_ERR_OR_NULL(phy->reg_base)) {
  260. pr_err("%s: failed to map phy regulator base\n", __func__);
  261. return NULL;
  262. }
  263. switch (type) {
  264. case MSM_DSI_PHY_28NM:
  265. dsi_phy_func_init(28nm);
  266. break;
  267. default:
  268. pr_err("%s: unsupported type, %d\n", __func__, type);
  269. return NULL;
  270. }
  271. phy->id = id;
  272. return phy;
  273. }
  274. int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel,
  275. const unsigned long bit_rate, const unsigned long esc_rate)
  276. {
  277. if (!phy || !phy->enable)
  278. return -EINVAL;
  279. return phy->enable(phy, is_dual_panel, bit_rate, esc_rate);
  280. }
  281. int msm_dsi_phy_disable(struct msm_dsi_phy *phy)
  282. {
  283. if (!phy || !phy->disable)
  284. return -EINVAL;
  285. return phy->disable(phy);
  286. }
  287. void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy,
  288. u32 *clk_pre, u32 *clk_post)
  289. {
  290. if (!phy)
  291. return;
  292. if (clk_pre)
  293. *clk_pre = phy->timing.clk_pre;
  294. if (clk_post)
  295. *clk_post = phy->timing.clk_post;
  296. }