dsi_phy_timing_calc.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "dsi-phy-timing:" fmt
  6. #include "dsi_phy_timing_calc.h"
  7. static const u32 bits_per_pixel[DSI_PIXEL_FORMAT_MAX] = {
  8. 16, 18, 18, 24, 3, 8, 12 };
  9. static int dsi_phy_cmn_validate_and_set(struct timing_entry *t,
  10. char const *t_name)
  11. {
  12. if (t->rec & 0xffffff00) {
  13. /* Output value can only be 8 bits */
  14. pr_err("Incorrect %s rec value - %d\n", t_name, t->rec);
  15. return -EINVAL;
  16. }
  17. t->reg_value = t->rec;
  18. return 0;
  19. }
  20. /**
  21. * calc_clk_prepare - calculates prepare timing params for clk lane.
  22. */
  23. static int calc_clk_prepare(struct dsi_phy_hw *phy,
  24. struct phy_clk_params *clk_params,
  25. struct phy_timing_desc *desc,
  26. s32 *actual_frac,
  27. s64 *actual_intermediate)
  28. {
  29. u64 multiplier = BIT(20);
  30. struct timing_entry *t = &desc->clk_prepare;
  31. int rc = 0;
  32. u64 dividend, temp, temp_multiple;
  33. s32 frac = 0;
  34. s64 intermediate;
  35. s64 clk_prep_actual;
  36. dividend = ((t->rec_max - t->rec_min) *
  37. clk_params->clk_prep_buf * multiplier);
  38. temp = roundup(div_s64(dividend, 100), multiplier);
  39. temp += (t->rec_min * multiplier);
  40. t->rec = div_s64(temp, multiplier);
  41. rc = dsi_phy_cmn_validate_and_set(t, "clk_prepare");
  42. if (rc)
  43. goto error;
  44. /* calculate theoretical value */
  45. temp_multiple = 8 * t->reg_value * clk_params->tlpx_numer_ns
  46. * multiplier;
  47. intermediate = div_s64(temp_multiple, clk_params->bitclk_mbps);
  48. div_s64_rem(temp_multiple, clk_params->bitclk_mbps, &frac);
  49. clk_prep_actual = div_s64((intermediate + frac), multiplier);
  50. pr_debug("CLK_PREPARE:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d\n",
  51. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max);
  52. pr_debug(" reg_value=%d, actual=%lld\n", t->reg_value, clk_prep_actual);
  53. *actual_frac = frac;
  54. *actual_intermediate = intermediate;
  55. error:
  56. return rc;
  57. }
  58. /**
  59. * calc_clk_zero - calculates zero timing params for clk lane.
  60. */
  61. static int calc_clk_zero(struct dsi_phy_hw *phy,
  62. struct phy_clk_params *clk_params,
  63. struct phy_timing_desc *desc,
  64. s32 actual_frac, s64 actual_intermediate)
  65. {
  66. u64 const multiplier = BIT(20);
  67. int rc = 0;
  68. struct timing_entry *t = &desc->clk_zero;
  69. s64 mipi_min, rec_temp1;
  70. struct phy_timing_ops *ops = phy->ops.timing_ops;
  71. mipi_min = ((300 * multiplier) - (actual_intermediate + actual_frac));
  72. t->mipi_min = div_s64(mipi_min, multiplier);
  73. rec_temp1 = div_s64((mipi_min * clk_params->bitclk_mbps),
  74. clk_params->tlpx_numer_ns);
  75. if (ops->calc_clk_zero) {
  76. t->rec_min = ops->calc_clk_zero(rec_temp1, multiplier);
  77. } else {
  78. rc = -EINVAL;
  79. goto error;
  80. }
  81. t->rec_max = ((t->rec_min > 255) ? 511 : 255);
  82. t->rec = DIV_ROUND_UP((((t->rec_max - t->rec_min) *
  83. clk_params->clk_zero_buf) + (t->rec_min * 100)), 100);
  84. rc = dsi_phy_cmn_validate_and_set(t, "clk_zero");
  85. if (rc)
  86. goto error;
  87. pr_debug("CLK_ZERO:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  88. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  89. t->reg_value);
  90. error:
  91. return rc;
  92. }
  93. /**
  94. * calc_clk_trail - calculates prepare trail params for clk lane.
  95. */
  96. static int calc_clk_trail(struct dsi_phy_hw *phy,
  97. struct phy_clk_params *clk_params,
  98. struct phy_timing_desc *desc,
  99. s64 *teot_clk_lane)
  100. {
  101. u64 const multiplier = BIT(20);
  102. int rc = 0;
  103. struct timing_entry *t = &desc->clk_trail;
  104. u64 temp_multiple;
  105. s32 frac;
  106. s64 mipi_max_tr, rec_temp1, mipi_max;
  107. s64 teot_clk_lane1;
  108. struct phy_timing_ops *ops = phy->ops.timing_ops;
  109. temp_multiple = div_s64(
  110. (12 * multiplier * clk_params->tlpx_numer_ns),
  111. clk_params->bitclk_mbps);
  112. div_s64_rem(temp_multiple, multiplier, &frac);
  113. mipi_max_tr = ((105 * multiplier) +
  114. (temp_multiple + frac));
  115. teot_clk_lane1 = div_s64(mipi_max_tr, multiplier);
  116. mipi_max = (mipi_max_tr - (clk_params->treot_ns * multiplier));
  117. t->mipi_max = div_s64(mipi_max, multiplier);
  118. temp_multiple = div_s64(
  119. (t->mipi_min * multiplier * clk_params->bitclk_mbps),
  120. clk_params->tlpx_numer_ns);
  121. div_s64_rem(temp_multiple, multiplier, &frac);
  122. if (ops->calc_clk_trail_rec_min) {
  123. t->rec_min = ops->calc_clk_trail_rec_min(temp_multiple,
  124. frac, multiplier);
  125. } else {
  126. rc = -EINVAL;
  127. goto error;
  128. }
  129. /* recommended max */
  130. rec_temp1 = div_s64((mipi_max * clk_params->bitclk_mbps),
  131. clk_params->tlpx_numer_ns);
  132. if (ops->calc_clk_trail_rec_max) {
  133. t->rec_max = ops->calc_clk_trail_rec_max(rec_temp1, multiplier);
  134. } else {
  135. rc = -EINVAL;
  136. goto error;
  137. }
  138. t->rec = DIV_ROUND_UP(
  139. (((t->rec_max - t->rec_min) * clk_params->clk_trail_buf) +
  140. (t->rec_min * 100)), 100);
  141. rc = dsi_phy_cmn_validate_and_set(t, "clk_trail");
  142. if (rc)
  143. goto error;
  144. *teot_clk_lane = teot_clk_lane1;
  145. pr_debug("CLK_TRAIL:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  146. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  147. t->reg_value);
  148. error:
  149. return rc;
  150. }
  151. /**
  152. * calc_hs_prepare - calculates prepare timing params for data lanes in HS.
  153. */
  154. static int calc_hs_prepare(struct dsi_phy_hw *phy,
  155. struct phy_clk_params *clk_params,
  156. struct phy_timing_desc *desc,
  157. u64 *temp_mul)
  158. {
  159. u64 multiplier = BIT(20);
  160. int rc = 0;
  161. struct timing_entry *t = &desc->hs_prepare;
  162. u64 temp_multiple, dividend, temp;
  163. s32 frac;
  164. s64 rec_temp1, rec_temp2, mipi_max, mipi_min;
  165. u32 low_clk_multiplier = 0;
  166. if (clk_params->bitclk_mbps <= 120)
  167. low_clk_multiplier = 2;
  168. /* mipi min */
  169. temp_multiple = div_s64((4 * multiplier * clk_params->tlpx_numer_ns),
  170. clk_params->bitclk_mbps);
  171. div_s64_rem(temp_multiple, multiplier, &frac);
  172. mipi_min = (40 * multiplier) + (temp_multiple + frac);
  173. t->mipi_min = div_s64(mipi_min, multiplier);
  174. /* mipi_max */
  175. temp_multiple = div_s64(
  176. (6 * multiplier * clk_params->tlpx_numer_ns),
  177. clk_params->bitclk_mbps);
  178. div_s64_rem(temp_multiple, multiplier, &frac);
  179. mipi_max = (85 * multiplier) + temp_multiple;
  180. t->mipi_max = div_s64(mipi_max, multiplier);
  181. /* recommended min */
  182. temp_multiple = div_s64((mipi_min * clk_params->bitclk_mbps),
  183. clk_params->tlpx_numer_ns);
  184. temp_multiple -= (low_clk_multiplier * multiplier);
  185. div_s64_rem(temp_multiple, multiplier, &frac);
  186. rec_temp1 = roundup(((temp_multiple + frac) / 8), multiplier);
  187. t->rec_min = div_s64(rec_temp1, multiplier);
  188. /* recommended max */
  189. temp_multiple = div_s64((mipi_max * clk_params->bitclk_mbps),
  190. clk_params->tlpx_numer_ns);
  191. temp_multiple -= (low_clk_multiplier * multiplier);
  192. div_s64_rem(temp_multiple, multiplier, &frac);
  193. rec_temp2 = rounddown((temp_multiple / 8), multiplier);
  194. t->rec_max = div_s64(rec_temp2, multiplier);
  195. /* register value */
  196. dividend = ((rec_temp2 - rec_temp1) * clk_params->hs_prep_buf);
  197. temp = roundup(div_u64(dividend, 100), multiplier);
  198. t->rec = div_s64((temp + rec_temp1), multiplier);
  199. rc = dsi_phy_cmn_validate_and_set(t, "hs_prepare");
  200. if (rc)
  201. goto error;
  202. temp_multiple = div_s64(
  203. (8 * (temp + rec_temp1) * clk_params->tlpx_numer_ns),
  204. clk_params->bitclk_mbps);
  205. *temp_mul = temp_multiple;
  206. pr_debug("HS_PREP:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  207. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  208. t->reg_value);
  209. error:
  210. return rc;
  211. }
  212. /**
  213. * calc_hs_zero - calculates zero timing params for data lanes in HS.
  214. */
  215. static int calc_hs_zero(struct dsi_phy_hw *phy,
  216. struct phy_clk_params *clk_params,
  217. struct phy_timing_desc *desc,
  218. u64 temp_multiple)
  219. {
  220. u64 const multiplier = BIT(20);
  221. int rc = 0;
  222. struct timing_entry *t = &desc->hs_zero;
  223. s64 rec_temp1, mipi_min;
  224. struct phy_timing_ops *ops = phy->ops.timing_ops;
  225. mipi_min = div_s64((10 * clk_params->tlpx_numer_ns * multiplier),
  226. clk_params->bitclk_mbps);
  227. rec_temp1 = (145 * multiplier) + mipi_min - temp_multiple;
  228. t->mipi_min = div_s64(rec_temp1, multiplier);
  229. /* recommended min */
  230. rec_temp1 = div_s64((rec_temp1 * clk_params->bitclk_mbps),
  231. clk_params->tlpx_numer_ns);
  232. if (ops->calc_hs_zero) {
  233. t->rec_min = ops->calc_hs_zero(rec_temp1, multiplier);
  234. } else {
  235. rc = -EINVAL;
  236. goto error;
  237. }
  238. t->rec_max = ((t->rec_min > 255) ? 511 : 255);
  239. t->rec = DIV_ROUND_UP(
  240. (((t->rec_max - t->rec_min) * clk_params->hs_zero_buf) +
  241. (t->rec_min * 100)),
  242. 100);
  243. rc = dsi_phy_cmn_validate_and_set(t, "hs_zero");
  244. if (rc)
  245. goto error;
  246. pr_debug("HS_ZERO:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  247. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  248. t->reg_value);
  249. error:
  250. return rc;
  251. }
  252. /**
  253. * calc_hs_trail - calculates trail timing params for data lanes in HS.
  254. */
  255. static int calc_hs_trail(struct dsi_phy_hw *phy,
  256. struct phy_clk_params *clk_params,
  257. struct phy_timing_desc *desc,
  258. u64 teot_clk_lane)
  259. {
  260. int rc = 0;
  261. struct timing_entry *t = &desc->hs_trail;
  262. s64 rec_temp1;
  263. struct phy_timing_ops *ops = phy->ops.timing_ops;
  264. t->mipi_min = 60 +
  265. mult_frac(clk_params->tlpx_numer_ns, 4,
  266. clk_params->bitclk_mbps);
  267. t->mipi_max = teot_clk_lane - clk_params->treot_ns;
  268. if (ops->calc_hs_trail) {
  269. ops->calc_hs_trail(clk_params, desc);
  270. } else {
  271. rc = -EINVAL;
  272. goto error;
  273. }
  274. rec_temp1 = DIV_ROUND_UP(
  275. ((t->rec_max - t->rec_min) * clk_params->hs_trail_buf),
  276. 100);
  277. t->rec = rec_temp1 + t->rec_min;
  278. rc = dsi_phy_cmn_validate_and_set(t, "hs_trail");
  279. if (rc)
  280. goto error;
  281. pr_debug("HS_TRAIL:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  282. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  283. t->reg_value);
  284. error:
  285. return rc;
  286. }
  287. /**
  288. * calc_hs_rqst - calculates rqst timing params for data lanes in HS.
  289. */
  290. static int calc_hs_rqst(struct dsi_phy_hw *phy,
  291. struct phy_clk_params *clk_params,
  292. struct phy_timing_desc *desc)
  293. {
  294. int rc = 0;
  295. struct timing_entry *t = &desc->hs_rqst;
  296. t->rec = DIV_ROUND_UP(
  297. ((t->mipi_min * clk_params->bitclk_mbps) -
  298. (8 * clk_params->tlpx_numer_ns)),
  299. (8 * clk_params->tlpx_numer_ns));
  300. rc = dsi_phy_cmn_validate_and_set(t, "hs_rqst");
  301. if (rc)
  302. goto error;
  303. pr_debug("HS_RQST:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  304. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  305. t->reg_value);
  306. error:
  307. return rc;
  308. }
  309. /**
  310. * calc_hs_exit - calculates exit timing params for data lanes in HS.
  311. */
  312. static int calc_hs_exit(struct dsi_phy_hw *phy,
  313. struct phy_clk_params *clk_params,
  314. struct phy_timing_desc *desc)
  315. {
  316. int rc = 0;
  317. struct timing_entry *t = &desc->hs_exit;
  318. t->rec_min = (DIV_ROUND_UP(
  319. (t->mipi_min * clk_params->bitclk_mbps),
  320. (8 * clk_params->tlpx_numer_ns)) - 1);
  321. t->rec = DIV_ROUND_UP(
  322. (((t->rec_max - t->rec_min) * clk_params->hs_exit_buf) +
  323. (t->rec_min * 100)), 100);
  324. rc = dsi_phy_cmn_validate_and_set(t, "hs_exit");
  325. if (rc)
  326. goto error;
  327. pr_debug("HS_EXIT:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  328. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  329. t->reg_value);
  330. error:
  331. return rc;
  332. }
  333. /**
  334. * calc_hs_rqst_clk - calculates rqst timing params for clock lane..
  335. */
  336. static int calc_hs_rqst_clk(struct dsi_phy_hw *phy,
  337. struct phy_clk_params *clk_params,
  338. struct phy_timing_desc *desc)
  339. {
  340. int rc = 0;
  341. struct timing_entry *t = &desc->hs_rqst_clk;
  342. t->rec = DIV_ROUND_UP(
  343. ((t->mipi_min * clk_params->bitclk_mbps) -
  344. (8 * clk_params->tlpx_numer_ns)),
  345. (8 * clk_params->tlpx_numer_ns));
  346. rc = dsi_phy_cmn_validate_and_set(t, "hs_rqst_clk");
  347. if (rc)
  348. goto error;
  349. pr_debug("HS_RQST_CLK:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  350. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  351. t->reg_value);
  352. error:
  353. return rc;
  354. }
  355. /**
  356. * cal_clk_pulse_time - calculates clk pulse time in nsec
  357. */
  358. static s64 cal_clk_pulse_time(u32 inp1, u32 inp2, u32 bitclk_mbps)
  359. {
  360. u64 const multiplier = BIT(20);
  361. u64 clk_multiple;
  362. s32 frac;
  363. s64 temp, result;
  364. clk_multiple = div_s64((inp1 * multiplier * 1000), bitclk_mbps);
  365. div_s64_rem(clk_multiple, multiplier, &frac);
  366. temp = (inp2 * multiplier) + (clk_multiple + frac);
  367. result = div_s64(temp, multiplier);
  368. return result;
  369. }
  370. /**
  371. * calc_clk_post - calculates clk_post timing params for data lanes in HS.
  372. */
  373. static int calc_clk_post(struct dsi_phy_hw *phy,
  374. struct phy_clk_params *clk_params,
  375. struct phy_timing_desc *desc)
  376. {
  377. int rc = 0;
  378. struct timing_entry *t = &desc->clk_post;
  379. s64 rec_cal1, rec_cal2;
  380. u32 input1;
  381. /* mipi min */
  382. t->mipi_min = cal_clk_pulse_time(52, 60, clk_params->bitclk_mbps);
  383. /* recommended min
  384. * = roundup((mipi_min_ns + t_hs_trail_ns)/(16*bit_clk_ns), 0) - 1
  385. */
  386. rec_cal1 = cal_clk_pulse_time(16, 0, clk_params->bitclk_mbps);
  387. input1 = (desc->hs_trail.reg_value + 1) * 8;
  388. rec_cal2 = cal_clk_pulse_time(input1, 0, clk_params->bitclk_mbps);
  389. rec_cal2 += t->mipi_min;
  390. t->rec_min = div_s64(rec_cal2, rec_cal1) - 1;
  391. /* recommended max */
  392. t->rec_max = 255;
  393. /* register value */
  394. rec_cal1 = (t->rec_max - t->rec_min);
  395. rec_cal2 = clk_params->clk_post_buf/100;
  396. t->rec = rec_cal1 * rec_cal2 + t->rec_min;
  397. rc = dsi_phy_cmn_validate_and_set(t, "clk_post");
  398. if (rc)
  399. goto error;
  400. pr_debug("CLK_POST:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  401. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  402. t->reg_value);
  403. error:
  404. return rc;
  405. }
  406. /**
  407. * calc_clk_pre - calculates clk_pre timing params for data lanes in HS.
  408. */
  409. static int calc_clk_pre(struct dsi_phy_hw *phy,
  410. struct phy_clk_params *clk_params,
  411. struct phy_timing_desc *desc)
  412. {
  413. int rc = 0;
  414. struct timing_entry *t = &desc->clk_pre;
  415. s64 rec_temp1;
  416. s64 clk_prepare, clk_zero, clk_16;
  417. u32 input1;
  418. s64 rec_cal1, rec_cal2;
  419. /* mipi min */
  420. t->mipi_min = cal_clk_pulse_time(8, 0, clk_params->bitclk_mbps);
  421. /* recommended min
  422. * val1 = (tlpx_ns + clk_prepare_ns + clk_zero_ns + hs_rqst_ns)
  423. * val2 = (16 * bit_clk_ns)
  424. * final = roundup(val1/val2, 0) - 1
  425. */
  426. input1 = desc->clk_prepare.reg_value * 8;
  427. clk_prepare = cal_clk_pulse_time(input1, 0, clk_params->bitclk_mbps);
  428. input1 = (desc->clk_zero.reg_value + 1) * 8;
  429. clk_zero = cal_clk_pulse_time(input1, 0, clk_params->bitclk_mbps);
  430. clk_16 = cal_clk_pulse_time(16, 0, clk_params->bitclk_mbps);
  431. rec_temp1 = 52 + clk_prepare + clk_zero + 54;
  432. t->rec_min = div_s64(rec_temp1, clk_16) - 1;
  433. /* recommended max */
  434. t->rec_max = 255;
  435. /* register value */
  436. rec_cal1 = (t->rec_max - t->rec_min);
  437. rec_cal2 = clk_params->clk_pre_buf/100;
  438. t->rec = rec_cal1 * rec_cal2 + t->rec_min;
  439. rc = dsi_phy_cmn_validate_and_set(t, "clk_pre");
  440. if (rc)
  441. goto error;
  442. pr_debug("CLK_PRE:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  443. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  444. t->reg_value);
  445. error:
  446. return rc;
  447. }
  448. /**
  449. * dsi_phy_calc_timing_params - calculates timing paramets for a given bit clock
  450. */
  451. static int dsi_phy_cmn_calc_timing_params(struct dsi_phy_hw *phy,
  452. struct phy_clk_params *clk_params, struct phy_timing_desc *desc)
  453. {
  454. int rc = 0;
  455. s32 actual_frac = 0;
  456. s64 actual_intermediate = 0;
  457. u64 temp_multiple;
  458. s64 teot_clk_lane;
  459. rc = calc_clk_prepare(phy, clk_params, desc, &actual_frac,
  460. &actual_intermediate);
  461. if (rc) {
  462. pr_err("clk_prepare calculations failed, rc=%d\n", rc);
  463. goto error;
  464. }
  465. rc = calc_clk_zero(phy, clk_params, desc,
  466. actual_frac, actual_intermediate);
  467. if (rc) {
  468. pr_err("clk_zero calculations failed, rc=%d\n", rc);
  469. goto error;
  470. }
  471. rc = calc_clk_trail(phy, clk_params, desc, &teot_clk_lane);
  472. if (rc) {
  473. pr_err("clk_trail calculations failed, rc=%d\n", rc);
  474. goto error;
  475. }
  476. rc = calc_hs_prepare(phy, clk_params, desc, &temp_multiple);
  477. if (rc) {
  478. pr_err("hs_prepare calculations failed, rc=%d\n", rc);
  479. goto error;
  480. }
  481. rc = calc_hs_zero(phy, clk_params, desc, temp_multiple);
  482. if (rc) {
  483. pr_err("hs_zero calculations failed, rc=%d\n", rc);
  484. goto error;
  485. }
  486. rc = calc_hs_trail(phy, clk_params, desc, teot_clk_lane);
  487. if (rc) {
  488. pr_err("hs_trail calculations failed, rc=%d\n", rc);
  489. goto error;
  490. }
  491. rc = calc_hs_rqst(phy, clk_params, desc);
  492. if (rc) {
  493. pr_err("hs_rqst calculations failed, rc=%d\n", rc);
  494. goto error;
  495. }
  496. rc = calc_hs_exit(phy, clk_params, desc);
  497. if (rc) {
  498. pr_err("hs_exit calculations failed, rc=%d\n", rc);
  499. goto error;
  500. }
  501. rc = calc_hs_rqst_clk(phy, clk_params, desc);
  502. if (rc) {
  503. pr_err("hs_rqst_clk calculations failed, rc=%d\n", rc);
  504. goto error;
  505. }
  506. rc = calc_clk_post(phy, clk_params, desc);
  507. if (rc) {
  508. pr_err("clk_post calculations failed, rc=%d\n", rc);
  509. goto error;
  510. }
  511. rc = calc_clk_pre(phy, clk_params, desc);
  512. if (rc) {
  513. pr_err("clk_pre calculations failed, rc=%d\n", rc);
  514. goto error;
  515. }
  516. error:
  517. return rc;
  518. }
  519. /**
  520. * calculate_timing_params() - calculates timing parameters.
  521. * @phy: Pointer to DSI PHY hardware object.
  522. * @mode: Mode information for which timing has to be calculated.
  523. * @config: DSI host configuration for this mode.
  524. * @timing: Timing parameters for each lane which will be returned.
  525. * @use_mode_bit_clk: Boolean to indicate whether reacalculate dsi
  526. * bit clk or use the existing bit clk(for dynamic clk case).
  527. */
  528. int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
  529. struct dsi_mode_info *mode,
  530. struct dsi_host_common_cfg *host,
  531. struct dsi_phy_per_lane_cfgs *timing,
  532. bool use_mode_bit_clk)
  533. {
  534. /* constants */
  535. u32 const esc_clk_mhz = 192; /* TODO: esc clock is hardcoded */
  536. u32 const esc_clk_mmss_cc_prediv = 10;
  537. u32 const tlpx_numer = 1000;
  538. u32 const tr_eot = 20;
  539. u32 const clk_prepare_spec_min = 38;
  540. u32 const clk_prepare_spec_max = 95;
  541. u32 const clk_trail_spec_min = 60;
  542. u32 const hs_exit_spec_min = 100;
  543. u32 const hs_exit_reco_max = 255;
  544. u32 const hs_rqst_spec_min = 50;
  545. /* local vars */
  546. int rc = 0;
  547. u32 h_total, v_total;
  548. u32 inter_num;
  549. u32 num_of_lanes = 0;
  550. u32 bpp;
  551. u64 x, y;
  552. struct phy_timing_desc desc;
  553. struct phy_clk_params clk_params = {0};
  554. struct phy_timing_ops *ops = phy->ops.timing_ops;
  555. memset(&desc, 0x0, sizeof(desc));
  556. h_total = DSI_H_TOTAL_DSC(mode);
  557. v_total = DSI_V_TOTAL(mode);
  558. bpp = bits_per_pixel[host->dst_format];
  559. inter_num = bpp * mode->refresh_rate;
  560. if (host->data_lanes & DSI_DATA_LANE_0)
  561. num_of_lanes++;
  562. if (host->data_lanes & DSI_DATA_LANE_1)
  563. num_of_lanes++;
  564. if (host->data_lanes & DSI_DATA_LANE_2)
  565. num_of_lanes++;
  566. if (host->data_lanes & DSI_DATA_LANE_3)
  567. num_of_lanes++;
  568. if (use_mode_bit_clk)
  569. x = mode->clk_rate_hz;
  570. else
  571. x = mult_frac(v_total * h_total, inter_num, num_of_lanes);
  572. y = rounddown(x, 1);
  573. clk_params.bitclk_mbps = rounddown(DIV_ROUND_UP_ULL(y, 1000000), 1);
  574. clk_params.escclk_numer = esc_clk_mhz;
  575. clk_params.escclk_denom = esc_clk_mmss_cc_prediv;
  576. clk_params.tlpx_numer_ns = tlpx_numer;
  577. clk_params.treot_ns = tr_eot;
  578. /* Setup default parameters */
  579. desc.clk_prepare.mipi_min = clk_prepare_spec_min;
  580. desc.clk_prepare.mipi_max = clk_prepare_spec_max;
  581. desc.clk_trail.mipi_min = clk_trail_spec_min;
  582. desc.hs_exit.mipi_min = hs_exit_spec_min;
  583. desc.hs_exit.rec_max = hs_exit_reco_max;
  584. desc.hs_rqst.mipi_min = hs_rqst_spec_min;
  585. desc.hs_rqst_clk.mipi_min = hs_rqst_spec_min;
  586. if (ops->get_default_phy_params) {
  587. ops->get_default_phy_params(&clk_params);
  588. } else {
  589. rc = -EINVAL;
  590. goto error;
  591. }
  592. desc.clk_prepare.rec_min = DIV_ROUND_UP(
  593. (desc.clk_prepare.mipi_min * clk_params.bitclk_mbps),
  594. (8 * clk_params.tlpx_numer_ns)
  595. );
  596. desc.clk_prepare.rec_max = rounddown(
  597. mult_frac((desc.clk_prepare.mipi_max * clk_params.bitclk_mbps),
  598. 1, (8 * clk_params.tlpx_numer_ns)),
  599. 1);
  600. pr_debug("BIT CLOCK = %d, tlpx_numer_ns=%d, treot_ns=%d\n",
  601. clk_params.bitclk_mbps, clk_params.tlpx_numer_ns,
  602. clk_params.treot_ns);
  603. rc = dsi_phy_cmn_calc_timing_params(phy, &clk_params, &desc);
  604. if (rc) {
  605. pr_err("Timing calc failed, rc=%d\n", rc);
  606. goto error;
  607. }
  608. if (ops->update_timing_params) {
  609. ops->update_timing_params(timing, &desc);
  610. } else {
  611. rc = -EINVAL;
  612. goto error;
  613. }
  614. error:
  615. return rc;
  616. }
  617. int dsi_phy_timing_calc_init(struct dsi_phy_hw *phy,
  618. enum dsi_phy_version version)
  619. {
  620. struct phy_timing_ops *ops = NULL;
  621. if (version == DSI_PHY_VERSION_UNKNOWN ||
  622. version >= DSI_PHY_VERSION_MAX || !phy) {
  623. pr_err("Unsupported version: %d\n", version);
  624. return -ENOTSUPP;
  625. }
  626. ops = kzalloc(sizeof(struct phy_timing_ops), GFP_KERNEL);
  627. if (!ops)
  628. return -EINVAL;
  629. phy->ops.timing_ops = ops;
  630. switch (version) {
  631. case DSI_PHY_VERSION_2_0:
  632. ops->get_default_phy_params =
  633. dsi_phy_hw_v2_0_get_default_phy_params;
  634. ops->calc_clk_zero =
  635. dsi_phy_hw_v2_0_calc_clk_zero;
  636. ops->calc_clk_trail_rec_min =
  637. dsi_phy_hw_v2_0_calc_clk_trail_rec_min;
  638. ops->calc_clk_trail_rec_max =
  639. dsi_phy_hw_v2_0_calc_clk_trail_rec_max;
  640. ops->calc_hs_zero =
  641. dsi_phy_hw_v2_0_calc_hs_zero;
  642. ops->calc_hs_trail =
  643. dsi_phy_hw_v2_0_calc_hs_trail;
  644. ops->update_timing_params =
  645. dsi_phy_hw_v2_0_update_timing_params;
  646. break;
  647. case DSI_PHY_VERSION_3_0:
  648. ops->get_default_phy_params =
  649. dsi_phy_hw_v3_0_get_default_phy_params;
  650. ops->calc_clk_zero =
  651. dsi_phy_hw_v3_0_calc_clk_zero;
  652. ops->calc_clk_trail_rec_min =
  653. dsi_phy_hw_v3_0_calc_clk_trail_rec_min;
  654. ops->calc_clk_trail_rec_max =
  655. dsi_phy_hw_v3_0_calc_clk_trail_rec_max;
  656. ops->calc_hs_zero =
  657. dsi_phy_hw_v3_0_calc_hs_zero;
  658. ops->calc_hs_trail =
  659. dsi_phy_hw_v3_0_calc_hs_trail;
  660. ops->update_timing_params =
  661. dsi_phy_hw_v3_0_update_timing_params;
  662. break;
  663. case DSI_PHY_VERSION_4_0:
  664. case DSI_PHY_VERSION_4_1:
  665. ops->get_default_phy_params =
  666. dsi_phy_hw_v4_0_get_default_phy_params;
  667. ops->calc_clk_zero =
  668. dsi_phy_hw_v4_0_calc_clk_zero;
  669. ops->calc_clk_trail_rec_min =
  670. dsi_phy_hw_v4_0_calc_clk_trail_rec_min;
  671. ops->calc_clk_trail_rec_max =
  672. dsi_phy_hw_v4_0_calc_clk_trail_rec_max;
  673. ops->calc_hs_zero =
  674. dsi_phy_hw_v4_0_calc_hs_zero;
  675. ops->calc_hs_trail =
  676. dsi_phy_hw_v4_0_calc_hs_trail;
  677. ops->update_timing_params =
  678. dsi_phy_hw_v4_0_update_timing_params;
  679. break;
  680. case DSI_PHY_VERSION_0_0_HPM:
  681. case DSI_PHY_VERSION_0_0_LPM:
  682. case DSI_PHY_VERSION_1_0:
  683. default:
  684. kfree(ops);
  685. return -ENOTSUPP;
  686. }
  687. return 0;
  688. }