dsi_phy_timing_calc.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  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, 30 };
  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. DSI_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. t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
  37. (8 * clk_params->tlpx_numer_ns));
  38. t->rec_max = rounddown(
  39. mult_frac((t->mipi_max * clk_params->bitclk_mbps),
  40. 1, (8 * clk_params->tlpx_numer_ns)), 1);
  41. dividend = ((t->rec_max - t->rec_min) *
  42. clk_params->clk_prep_buf * multiplier);
  43. temp = roundup(div_s64(dividend, 100), multiplier);
  44. temp += (t->rec_min * multiplier);
  45. t->rec = div_s64(temp, multiplier);
  46. rc = dsi_phy_cmn_validate_and_set(t, "clk_prepare");
  47. if (rc)
  48. goto error;
  49. /* calculate theoretical value */
  50. temp_multiple = 8 * t->reg_value * clk_params->tlpx_numer_ns
  51. * multiplier;
  52. intermediate = div_s64(temp_multiple, clk_params->bitclk_mbps);
  53. div_s64_rem(temp_multiple, clk_params->bitclk_mbps, &frac);
  54. clk_prep_actual = div_s64((intermediate + frac), multiplier);
  55. DSI_PHY_DBG(phy, "CLK_PREPARE:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d\n",
  56. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max);
  57. DSI_PHY_DBG(phy, " reg_value=%d, actual=%lld\n", t->reg_value,
  58. clk_prep_actual);
  59. *actual_frac = frac;
  60. *actual_intermediate = intermediate;
  61. error:
  62. return rc;
  63. }
  64. /**
  65. * calc_clk_zero - calculates zero timing params for clk lane.
  66. */
  67. static int calc_clk_zero(struct dsi_phy_hw *phy,
  68. struct phy_clk_params *clk_params,
  69. struct phy_timing_desc *desc,
  70. s32 actual_frac, s64 actual_intermediate)
  71. {
  72. u64 const multiplier = BIT(20);
  73. int rc = 0;
  74. struct timing_entry *t = &desc->clk_zero;
  75. s64 mipi_min, rec_temp1;
  76. struct phy_timing_ops *ops = phy->ops.timing_ops;
  77. mipi_min = ((300 * multiplier) - (actual_intermediate + actual_frac));
  78. t->mipi_min = div_s64(mipi_min, multiplier);
  79. rec_temp1 = div_s64((mipi_min * clk_params->bitclk_mbps),
  80. clk_params->tlpx_numer_ns);
  81. if (ops->calc_clk_zero) {
  82. t->rec_min = ops->calc_clk_zero(rec_temp1, multiplier);
  83. } else {
  84. rc = -EINVAL;
  85. goto error;
  86. }
  87. t->rec_max = ((t->rec_min > 255) ? 511 : 255);
  88. t->rec = DIV_ROUND_UP((((t->rec_max - t->rec_min) *
  89. clk_params->clk_zero_buf) + (t->rec_min * 100)), 100);
  90. rc = dsi_phy_cmn_validate_and_set(t, "clk_zero");
  91. if (rc)
  92. goto error;
  93. DSI_PHY_DBG(phy, "CLK_ZERO:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  94. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  95. t->reg_value);
  96. error:
  97. return rc;
  98. }
  99. /**
  100. * calc_clk_trail - calculates prepare trail params for clk lane.
  101. */
  102. static int calc_clk_trail(struct dsi_phy_hw *phy,
  103. struct phy_clk_params *clk_params,
  104. struct phy_timing_desc *desc,
  105. s64 *teot_clk_lane)
  106. {
  107. u64 const multiplier = BIT(20);
  108. int rc = 0;
  109. struct timing_entry *t = &desc->clk_trail;
  110. u64 temp_multiple;
  111. s32 frac;
  112. s64 mipi_max_tr, rec_temp1, mipi_max;
  113. s64 teot_clk_lane1;
  114. struct phy_timing_ops *ops = phy->ops.timing_ops;
  115. temp_multiple = div_s64(
  116. (12 * multiplier * clk_params->tlpx_numer_ns),
  117. clk_params->bitclk_mbps);
  118. div_s64_rem(temp_multiple, multiplier, &frac);
  119. mipi_max_tr = ((105 * multiplier) +
  120. (temp_multiple + frac));
  121. teot_clk_lane1 = div_s64(mipi_max_tr, multiplier);
  122. mipi_max = (mipi_max_tr - (clk_params->treot_ns * multiplier));
  123. t->mipi_max = div_s64(mipi_max, multiplier);
  124. temp_multiple = div_s64(
  125. (t->mipi_min * multiplier * clk_params->bitclk_mbps),
  126. clk_params->tlpx_numer_ns);
  127. div_s64_rem(temp_multiple, multiplier, &frac);
  128. if (ops->calc_clk_trail_rec_min) {
  129. t->rec_min = ops->calc_clk_trail_rec_min(temp_multiple,
  130. frac, multiplier);
  131. } else {
  132. rc = -EINVAL;
  133. goto error;
  134. }
  135. /* recommended max */
  136. rec_temp1 = div_s64((mipi_max * clk_params->bitclk_mbps),
  137. clk_params->tlpx_numer_ns);
  138. if (ops->calc_clk_trail_rec_max) {
  139. t->rec_max = ops->calc_clk_trail_rec_max(rec_temp1, multiplier);
  140. } else {
  141. rc = -EINVAL;
  142. goto error;
  143. }
  144. t->rec = DIV_ROUND_UP(
  145. (((t->rec_max - t->rec_min) * clk_params->clk_trail_buf) +
  146. (t->rec_min * 100)), 100);
  147. rc = dsi_phy_cmn_validate_and_set(t, "clk_trail");
  148. if (rc)
  149. goto error;
  150. *teot_clk_lane = teot_clk_lane1;
  151. DSI_PHY_DBG(phy, "CLK_TRAIL:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  152. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  153. t->reg_value);
  154. error:
  155. return rc;
  156. }
  157. /**
  158. * calc_hs_prepare - calculates prepare timing params for data lanes in HS.
  159. */
  160. static int calc_hs_prepare(struct dsi_phy_hw *phy,
  161. struct phy_clk_params *clk_params,
  162. struct phy_timing_desc *desc,
  163. u64 *temp_mul)
  164. {
  165. u64 multiplier = BIT(20);
  166. int rc = 0;
  167. struct timing_entry *t = &desc->hs_prepare;
  168. u64 temp_multiple, dividend, temp;
  169. s32 frac;
  170. s64 rec_temp1, rec_temp2, mipi_max, mipi_min;
  171. u32 low_clk_multiplier = 0;
  172. if (clk_params->bitclk_mbps <= 120)
  173. low_clk_multiplier = 2;
  174. /* mipi min */
  175. temp_multiple = div_s64((4 * multiplier * clk_params->tlpx_numer_ns),
  176. clk_params->bitclk_mbps);
  177. div_s64_rem(temp_multiple, multiplier, &frac);
  178. mipi_min = (40 * multiplier) + (temp_multiple + frac);
  179. t->mipi_min = div_s64(mipi_min, multiplier);
  180. /* mipi_max */
  181. temp_multiple = div_s64(
  182. (6 * multiplier * clk_params->tlpx_numer_ns),
  183. clk_params->bitclk_mbps);
  184. div_s64_rem(temp_multiple, multiplier, &frac);
  185. mipi_max = (85 * multiplier) + temp_multiple;
  186. t->mipi_max = div_s64(mipi_max, multiplier);
  187. /* recommended min */
  188. temp_multiple = div_s64((mipi_min * clk_params->bitclk_mbps),
  189. clk_params->tlpx_numer_ns);
  190. temp_multiple -= (low_clk_multiplier * multiplier);
  191. div_s64_rem(temp_multiple, multiplier, &frac);
  192. rec_temp1 = roundup(((temp_multiple + frac) / 8), multiplier);
  193. t->rec_min = div_s64(rec_temp1, multiplier);
  194. /* recommended max */
  195. temp_multiple = div_s64((mipi_max * clk_params->bitclk_mbps),
  196. clk_params->tlpx_numer_ns);
  197. temp_multiple -= (low_clk_multiplier * multiplier);
  198. div_s64_rem(temp_multiple, multiplier, &frac);
  199. rec_temp2 = rounddown((temp_multiple / 8), multiplier);
  200. t->rec_max = div_s64(rec_temp2, multiplier);
  201. /* register value */
  202. dividend = ((rec_temp2 - rec_temp1) * clk_params->hs_prep_buf);
  203. temp = roundup(div_u64(dividend, 100), multiplier);
  204. t->rec = div_s64((temp + rec_temp1), multiplier);
  205. rc = dsi_phy_cmn_validate_and_set(t, "hs_prepare");
  206. if (rc)
  207. goto error;
  208. temp_multiple = div_s64(
  209. (8 * (temp + rec_temp1) * clk_params->tlpx_numer_ns),
  210. clk_params->bitclk_mbps);
  211. *temp_mul = temp_multiple;
  212. DSI_PHY_DBG(phy, "HS_PREP:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  213. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  214. t->reg_value);
  215. error:
  216. return rc;
  217. }
  218. /**
  219. * calc_hs_zero - calculates zero timing params for data lanes in HS.
  220. */
  221. static int calc_hs_zero(struct dsi_phy_hw *phy,
  222. struct phy_clk_params *clk_params,
  223. struct phy_timing_desc *desc,
  224. u64 temp_multiple)
  225. {
  226. u64 const multiplier = BIT(20);
  227. int rc = 0;
  228. struct timing_entry *t = &desc->hs_zero;
  229. s64 rec_temp1, mipi_min;
  230. struct phy_timing_ops *ops = phy->ops.timing_ops;
  231. mipi_min = div_s64((10 * clk_params->tlpx_numer_ns * multiplier),
  232. clk_params->bitclk_mbps);
  233. rec_temp1 = (145 * multiplier) + mipi_min - temp_multiple;
  234. t->mipi_min = div_s64(rec_temp1, multiplier);
  235. /* recommended min */
  236. rec_temp1 = div_s64((rec_temp1 * clk_params->bitclk_mbps),
  237. clk_params->tlpx_numer_ns);
  238. if (ops->calc_hs_zero) {
  239. t->rec_min = ops->calc_hs_zero(rec_temp1, multiplier);
  240. } else {
  241. rc = -EINVAL;
  242. goto error;
  243. }
  244. t->rec_max = ((t->rec_min > 255) ? 511 : 255);
  245. t->rec = DIV_ROUND_UP(
  246. (((t->rec_max - t->rec_min) * clk_params->hs_zero_buf) +
  247. (t->rec_min * 100)),
  248. 100);
  249. rc = dsi_phy_cmn_validate_and_set(t, "hs_zero");
  250. if (rc)
  251. goto error;
  252. DSI_PHY_DBG(phy, "HS_ZERO:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  253. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  254. t->reg_value);
  255. error:
  256. return rc;
  257. }
  258. /**
  259. * calc_hs_trail - calculates trail timing params for data lanes in HS.
  260. */
  261. static int calc_hs_trail(struct dsi_phy_hw *phy,
  262. struct phy_clk_params *clk_params,
  263. struct phy_timing_desc *desc,
  264. u64 teot_clk_lane)
  265. {
  266. int rc = 0;
  267. struct timing_entry *t = &desc->hs_trail;
  268. s64 rec_temp1;
  269. struct phy_timing_ops *ops = phy->ops.timing_ops;
  270. t->mipi_min = 60 +
  271. mult_frac(clk_params->tlpx_numer_ns, 4,
  272. clk_params->bitclk_mbps);
  273. t->mipi_max = teot_clk_lane - clk_params->treot_ns;
  274. if (ops->calc_hs_trail) {
  275. ops->calc_hs_trail(clk_params, desc);
  276. } else {
  277. rc = -EINVAL;
  278. goto error;
  279. }
  280. rec_temp1 = DIV_ROUND_UP(
  281. ((t->rec_max - t->rec_min) * clk_params->hs_trail_buf),
  282. 100);
  283. t->rec = rec_temp1 + t->rec_min;
  284. rc = dsi_phy_cmn_validate_and_set(t, "hs_trail");
  285. if (rc)
  286. goto error;
  287. DSI_PHY_DBG(phy, "HS_TRAIL:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  288. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  289. t->reg_value);
  290. error:
  291. return rc;
  292. }
  293. /**
  294. * calc_hs_rqst - calculates rqst timing params for data lanes in HS.
  295. */
  296. static int calc_hs_rqst(struct dsi_phy_hw *phy,
  297. struct phy_clk_params *clk_params,
  298. struct phy_timing_desc *desc)
  299. {
  300. int rc = 0;
  301. struct timing_entry *t = &desc->hs_rqst;
  302. t->rec = DIV_ROUND_UP(
  303. ((t->mipi_min * clk_params->bitclk_mbps) -
  304. (8 * clk_params->tlpx_numer_ns)),
  305. (8 * clk_params->tlpx_numer_ns));
  306. rc = dsi_phy_cmn_validate_and_set(t, "hs_rqst");
  307. if (rc)
  308. goto error;
  309. DSI_PHY_DBG(phy, "HS_RQST:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  310. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  311. t->reg_value);
  312. error:
  313. return rc;
  314. }
  315. /**
  316. * calc_hs_exit - calculates exit timing params for data lanes in HS.
  317. */
  318. static int calc_hs_exit(struct dsi_phy_hw *phy,
  319. struct phy_clk_params *clk_params,
  320. struct phy_timing_desc *desc)
  321. {
  322. int rc = 0;
  323. struct timing_entry *t = &desc->hs_exit;
  324. t->rec_min = (DIV_ROUND_UP(
  325. (t->mipi_min * clk_params->bitclk_mbps),
  326. (8 * clk_params->tlpx_numer_ns)) - 1);
  327. t->rec = DIV_ROUND_UP(
  328. (((t->rec_max - t->rec_min) * clk_params->hs_exit_buf) +
  329. (t->rec_min * 100)), 100);
  330. rc = dsi_phy_cmn_validate_and_set(t, "hs_exit");
  331. if (rc)
  332. goto error;
  333. DSI_PHY_DBG(phy, "HS_EXIT:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  334. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  335. t->reg_value);
  336. error:
  337. return rc;
  338. }
  339. /**
  340. * calc_hs_rqst_clk - calculates rqst timing params for clock lane..
  341. */
  342. static int calc_hs_rqst_clk(struct dsi_phy_hw *phy,
  343. struct phy_clk_params *clk_params,
  344. struct phy_timing_desc *desc)
  345. {
  346. int rc = 0;
  347. struct timing_entry *t = &desc->hs_rqst_clk;
  348. t->rec = DIV_ROUND_UP(
  349. ((t->mipi_min * clk_params->bitclk_mbps) -
  350. (8 * clk_params->tlpx_numer_ns)),
  351. (8 * clk_params->tlpx_numer_ns));
  352. rc = dsi_phy_cmn_validate_and_set(t, "hs_rqst_clk");
  353. if (rc)
  354. goto error;
  355. DSI_PHY_DBG(phy, "HS_RQST_CLK:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  356. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  357. t->reg_value);
  358. error:
  359. return rc;
  360. }
  361. /**
  362. * cal_clk_pulse_time - calculates clk pulse time in nsec
  363. */
  364. static s64 cal_clk_pulse_time(u32 inp1, u32 inp2, u32 bitclk_mbps)
  365. {
  366. u64 const multiplier = BIT(20);
  367. u64 clk_multiple;
  368. s32 frac;
  369. s64 temp, result;
  370. clk_multiple = div_s64((inp1 * multiplier * 1000), bitclk_mbps);
  371. div_s64_rem(clk_multiple, multiplier, &frac);
  372. temp = (inp2 * multiplier) + (clk_multiple + frac);
  373. result = div_s64(temp, multiplier);
  374. return result;
  375. }
  376. /**
  377. * calc_clk_post - calculates clk_post timing params for data lanes in HS.
  378. */
  379. static int calc_clk_post(struct dsi_phy_hw *phy,
  380. struct phy_clk_params *clk_params,
  381. struct phy_timing_desc *desc)
  382. {
  383. int rc = 0;
  384. struct timing_entry *t = &desc->clk_post;
  385. s64 rec_cal1, rec_cal2;
  386. u32 input1;
  387. /* mipi min */
  388. t->mipi_min = cal_clk_pulse_time(52, 60, clk_params->bitclk_mbps);
  389. /* recommended min
  390. * = roundup((mipi_min_ns + t_hs_trail_ns)/(16*bit_clk_ns), 0) - 1
  391. */
  392. rec_cal1 = cal_clk_pulse_time(16, 0, clk_params->bitclk_mbps);
  393. input1 = (desc->hs_trail.reg_value + 1) * 8;
  394. rec_cal2 = cal_clk_pulse_time(input1, 0, clk_params->bitclk_mbps);
  395. rec_cal2 += t->mipi_min;
  396. t->rec_min = div_s64(rec_cal2, rec_cal1) - 1;
  397. /* recommended max */
  398. t->rec_max = 255;
  399. /* register value */
  400. t->rec = DIV_ROUND_UP((((t->rec_max - t->rec_min) *
  401. clk_params->clk_post_buf) + (t->rec_min * 100)), 100);
  402. rc = dsi_phy_cmn_validate_and_set(t, "clk_post");
  403. if (rc)
  404. goto error;
  405. DSI_PHY_DBG(phy, "CLK_POST:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  406. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  407. t->reg_value);
  408. error:
  409. return rc;
  410. }
  411. /**
  412. * calc_clk_pre - calculates clk_pre timing params for data lanes in HS.
  413. */
  414. static int calc_clk_pre(struct dsi_phy_hw *phy,
  415. struct phy_clk_params *clk_params,
  416. struct phy_timing_desc *desc)
  417. {
  418. int rc = 0;
  419. struct timing_entry *t = &desc->clk_pre;
  420. s64 rec_temp1;
  421. s64 clk_prepare, clk_zero, clk_16;
  422. u32 input1;
  423. /* mipi min */
  424. t->mipi_min = cal_clk_pulse_time(8, 0, clk_params->bitclk_mbps);
  425. /* recommended min
  426. * val1 = (tlpx_ns + clk_prepare_ns + clk_zero_ns + hs_rqst_ns)
  427. * val2 = (16 * bit_clk_ns)
  428. * final = roundup(val1/val2, 0) - 1
  429. */
  430. input1 = desc->clk_prepare.reg_value * 8;
  431. clk_prepare = cal_clk_pulse_time(input1, 0, clk_params->bitclk_mbps);
  432. input1 = (desc->clk_zero.reg_value + 1) * 8;
  433. clk_zero = cal_clk_pulse_time(input1, 0, clk_params->bitclk_mbps);
  434. clk_16 = cal_clk_pulse_time(16, 0, clk_params->bitclk_mbps);
  435. rec_temp1 = 52 + clk_prepare + clk_zero + 54;
  436. t->rec_min = div_s64(rec_temp1, clk_16) - 1;
  437. /* recommended max */
  438. t->rec_max = 255;
  439. /* register value */
  440. t->rec =DIV_ROUND_UP((((t->rec_max - t->rec_min) *
  441. 125) + (t->rec_min * 100 * 100)), 100 * 100);
  442. rc = dsi_phy_cmn_validate_and_set(t, "clk_pre");
  443. if (rc)
  444. goto error;
  445. DSI_PHY_DBG(phy, "CLK_PRE:mipi_min=%d, mipi_max=%d, rec_min=%d, rec_max=%d, reg_val=%d\n",
  446. t->mipi_min, t->mipi_max, t->rec_min, t->rec_max,
  447. t->reg_value);
  448. error:
  449. return rc;
  450. }
  451. /**
  452. * dsi_phy_calc_timing_params - calculates timing paramets for a given bit clock
  453. */
  454. static int dsi_phy_cmn_calc_timing_params(struct dsi_phy_hw *phy,
  455. struct phy_clk_params *clk_params, struct phy_timing_desc *desc)
  456. {
  457. int rc = 0;
  458. s32 actual_frac = 0;
  459. s64 actual_intermediate = 0;
  460. u64 temp_multiple;
  461. s64 teot_clk_lane;
  462. rc = calc_clk_prepare(phy, clk_params, desc, &actual_frac,
  463. &actual_intermediate);
  464. if (rc) {
  465. DSI_PHY_ERR(phy, "clk_prepare calculations failed, rc=%d\n",
  466. rc);
  467. goto error;
  468. }
  469. rc = calc_clk_zero(phy, clk_params, desc,
  470. actual_frac, actual_intermediate);
  471. if (rc) {
  472. DSI_PHY_ERR(phy, "clk_zero calculations failed, rc=%d\n", rc);
  473. goto error;
  474. }
  475. rc = calc_clk_trail(phy, clk_params, desc, &teot_clk_lane);
  476. if (rc) {
  477. DSI_PHY_ERR(phy, "clk_trail calculations failed, rc=%d\n", rc);
  478. goto error;
  479. }
  480. rc = calc_hs_prepare(phy, clk_params, desc, &temp_multiple);
  481. if (rc) {
  482. DSI_PHY_ERR(phy, "hs_prepare calculations failed, rc=%d\n", rc);
  483. goto error;
  484. }
  485. rc = calc_hs_zero(phy, clk_params, desc, temp_multiple);
  486. if (rc) {
  487. DSI_PHY_ERR(phy, "hs_zero calculations failed, rc=%d\n", rc);
  488. goto error;
  489. }
  490. rc = calc_hs_trail(phy, clk_params, desc, teot_clk_lane);
  491. if (rc) {
  492. DSI_PHY_ERR(phy, "hs_trail calculations failed, rc=%d\n", rc);
  493. goto error;
  494. }
  495. rc = calc_hs_rqst(phy, clk_params, desc);
  496. if (rc) {
  497. DSI_PHY_ERR(phy, "hs_rqst calculations failed, rc=%d\n", rc);
  498. goto error;
  499. }
  500. rc = calc_hs_exit(phy, clk_params, desc);
  501. if (rc) {
  502. DSI_PHY_ERR(phy, "hs_exit calculations failed, rc=%d\n", rc);
  503. goto error;
  504. }
  505. rc = calc_hs_rqst_clk(phy, clk_params, desc);
  506. if (rc) {
  507. DSI_PHY_ERR(phy, "hs_rqst_clk calculations failed, rc=%d\n",
  508. rc);
  509. goto error;
  510. }
  511. rc = calc_clk_post(phy, clk_params, desc);
  512. if (rc) {
  513. DSI_PHY_ERR(phy, "clk_post calculations failed, rc=%d\n", rc);
  514. goto error;
  515. }
  516. rc = calc_clk_pre(phy, clk_params, desc);
  517. if (rc) {
  518. DSI_PHY_ERR(phy, "clk_pre calculations failed, rc=%d\n", rc);
  519. goto error;
  520. }
  521. error:
  522. return rc;
  523. }
  524. /**
  525. * calc_cphy_clk_prepare - calculates cphy_clk_prepare parameter for cphy.
  526. */
  527. static int calc_cphy_clk_prepare(struct dsi_phy_hw *phy,
  528. struct phy_clk_params *clk_params,
  529. struct phy_timing_desc *desc)
  530. {
  531. u64 multiplier = BIT(20);
  532. struct timing_entry *t = &desc->clk_prepare;
  533. int rc = 0;
  534. u64 dividend, temp;
  535. t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
  536. (7 * clk_params->tlpx_numer_ns));
  537. t->rec_max = rounddown(
  538. mult_frac((t->mipi_max * clk_params->bitclk_mbps),
  539. 1, (7 * clk_params->tlpx_numer_ns)), 1);
  540. dividend = ((t->rec_max - t->rec_min) *
  541. clk_params->clk_prep_buf * multiplier);
  542. temp = roundup(div_s64(dividend, 100), multiplier);
  543. temp += (t->rec_min * multiplier);
  544. t->rec = div_s64(temp, multiplier);
  545. rc = dsi_phy_cmn_validate_and_set(t, "cphy_clk_prepare");
  546. DSI_DEBUG("CPHY_CLK_PREPARE: rec_min=%d, rec_max=%d, reg_val=%d\n",
  547. t->rec_min, t->rec_max, t->reg_value);
  548. return rc;
  549. }
  550. /**
  551. * calc_cphy_clk_pre - calculates cphy_clk_pre parameter for cphy.
  552. */
  553. static int calc_cphy_clk_pre(struct dsi_phy_hw *phy,
  554. struct phy_clk_params *clk_params,
  555. struct phy_timing_desc *desc)
  556. {
  557. u64 multiplier = BIT(20);
  558. struct timing_entry *t = &desc->clk_pre;
  559. int rc = 0;
  560. u64 dividend, temp;
  561. t->mipi_min = min(300 - 38 - mult_frac(7, clk_params->tlpx_numer_ns,
  562. clk_params->bitclk_mbps),
  563. mult_frac(448, clk_params->tlpx_numer_ns,
  564. clk_params->bitclk_mbps));
  565. t->mipi_max = mult_frac(448, clk_params->tlpx_numer_ns,
  566. clk_params->bitclk_mbps);
  567. t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
  568. (7 * clk_params->tlpx_numer_ns));
  569. t->rec_max = rounddown(
  570. mult_frac((t->mipi_max * clk_params->bitclk_mbps),
  571. 1, (7 * clk_params->tlpx_numer_ns)), 1);
  572. dividend = ((t->rec_max - t->rec_min) * clk_params->clk_pre_buf
  573. * multiplier);
  574. temp = roundup(div_s64(dividend, 100), multiplier);
  575. temp += (t->rec_min * multiplier);
  576. t->rec = div_s64(temp, multiplier);
  577. rc = dsi_phy_cmn_validate_and_set(t, "cphy_clk_pre");
  578. DSI_DEBUG("CPHY_CLK_PRE: rec_min=%d, rec_max=%d, reg_val=%d\n",
  579. t->rec_min, t->rec_max, t->reg_value);
  580. return rc;
  581. }
  582. /**
  583. * calc_cphy_clk_post - calculates cphy_clk_post parameter for cphy.
  584. */
  585. static int calc_cphy_clk_post(struct dsi_phy_hw *phy,
  586. struct phy_clk_params *clk_params,
  587. struct phy_timing_desc *desc)
  588. {
  589. u64 multiplier = BIT(20);
  590. struct timing_entry *t = &desc->clk_post;
  591. int rc = 0;
  592. u64 dividend, temp;
  593. t->mipi_min = mult_frac(7, clk_params->tlpx_numer_ns,
  594. clk_params->bitclk_mbps);
  595. t->mipi_max = mult_frac(224, clk_params->tlpx_numer_ns,
  596. clk_params->bitclk_mbps);
  597. t->rec_min = DIV_ROUND_UP((t->mipi_min * clk_params->bitclk_mbps),
  598. (7 * clk_params->tlpx_numer_ns));
  599. t->rec_max = rounddown(
  600. mult_frac((t->mipi_max * clk_params->bitclk_mbps),
  601. 1, (7 * clk_params->tlpx_numer_ns)), 1);
  602. dividend = ((t->rec_max - t->rec_min) * clk_params->clk_post_buf
  603. * multiplier);
  604. temp = roundup(div_s64(dividend, 100), multiplier);
  605. temp += (t->rec_min * multiplier);
  606. t->rec = div_s64(temp, multiplier);
  607. rc = dsi_phy_cmn_validate_and_set(t, "cphy_clk_post");
  608. DSI_DEBUG("CPHY_CLK_POST: rec_min=%d, rec_max=%d, reg_val=%d\n",
  609. t->rec_min, t->rec_max, t->reg_value);
  610. return rc;
  611. }
  612. /**
  613. * calc_cphy_hs_rqst - calculates cphy_hs_rqst parameter for cphy.
  614. */
  615. static int calc_cphy_hs_rqst(struct dsi_phy_hw *phy,
  616. struct phy_clk_params *clk_params,
  617. struct phy_timing_desc *desc)
  618. {
  619. u64 multiplier = BIT(20);
  620. struct timing_entry *t = &desc->hs_rqst;
  621. int rc = 0;
  622. u64 dividend, temp;
  623. t->rec_min = DIV_ROUND_UP(
  624. ((t->mipi_min * clk_params->bitclk_mbps) -
  625. (7 * clk_params->tlpx_numer_ns)),
  626. (7 * clk_params->tlpx_numer_ns));
  627. dividend = ((t->rec_max - t->rec_min) *
  628. clk_params->hs_rqst_buf * multiplier);
  629. temp = roundup(div_s64(dividend, 100), multiplier);
  630. temp += t->rec_min * multiplier;
  631. t->rec = div_s64(temp, multiplier);
  632. rc = dsi_phy_cmn_validate_and_set(t, "cphy_hs_rqst");
  633. DSI_DEBUG("CPHY_HS_RQST: rec_min=%d, rec_max=%d, reg_val=%d\n",
  634. t->rec_min, t->rec_max, t->reg_value);
  635. return rc;
  636. }
  637. /**
  638. * calc_cphy_hs_exit - calculates cphy_hs_exit parameter for cphy.
  639. */
  640. static int calc_cphy_hs_exit(struct dsi_phy_hw *phy,
  641. struct phy_clk_params *clk_params,
  642. struct phy_timing_desc *desc)
  643. {
  644. int rc = 0;
  645. u64 multiplier = BIT(20);
  646. u64 dividend, temp;
  647. struct timing_entry *t = &desc->hs_exit;
  648. t->rec_min = (DIV_ROUND_UP(
  649. (t->mipi_min * clk_params->bitclk_mbps),
  650. (7 * clk_params->tlpx_numer_ns)) - 1);
  651. dividend = ((t->rec_max - t->rec_min) *
  652. clk_params->hs_exit_buf * multiplier);
  653. temp = roundup(div_s64(dividend, 100), multiplier);
  654. temp += t->rec_min * multiplier;
  655. t->rec = div_s64(temp, multiplier);
  656. rc = dsi_phy_cmn_validate_and_set(t, "cphy_hs_exit");
  657. DSI_DEBUG("CPHY_HS_EXIT: rec_min=%d, rec_max=%d, reg_val=%d\n",
  658. t->rec_min, t->rec_max, t->reg_value);
  659. return rc;
  660. }
  661. /**
  662. * dsi_phy_calc_cphy_timing_params - calculates cphy timing parameters
  663. * for a given bit clock
  664. */
  665. static int dsi_phy_cmn_calc_cphy_timing_params(struct dsi_phy_hw *phy,
  666. struct phy_clk_params *clk_params, struct phy_timing_desc *desc)
  667. {
  668. int rc = 0;
  669. rc = calc_cphy_clk_prepare(phy, clk_params, desc);
  670. if (rc) {
  671. DSI_ERR("clk_prepare calculations failed, rc=%d\n", rc);
  672. goto error;
  673. }
  674. rc = calc_cphy_clk_pre(phy, clk_params, desc);
  675. if (rc) {
  676. DSI_ERR("clk_pre calculations failed, rc=%d\n", rc);
  677. goto error;
  678. }
  679. rc = calc_cphy_clk_post(phy, clk_params, desc);
  680. if (rc) {
  681. DSI_ERR("clk_zero calculations failed, rc=%d\n", rc);
  682. goto error;
  683. }
  684. rc = calc_cphy_hs_rqst(phy, clk_params, desc);
  685. if (rc) {
  686. DSI_ERR("hs_rqst calculations failed, rc=%d\n", rc);
  687. goto error;
  688. }
  689. rc = calc_cphy_hs_exit(phy, clk_params, desc);
  690. if (rc) {
  691. DSI_ERR("hs_exit calculations failed, rc=%d\n", rc);
  692. goto error;
  693. }
  694. error:
  695. return rc;
  696. }
  697. /**
  698. * calculate_timing_params() - calculates timing parameters.
  699. * @phy: Pointer to DSI PHY hardware object.
  700. * @mode: Mode information for which timing has to be calculated.
  701. * @config: DSI host configuration for this mode.
  702. * @timing: Timing parameters for each lane which will be returned.
  703. * @use_mode_bit_clk: Boolean to indicate whether reacalculate dsi
  704. * bit clk or use the existing bit clk(for dynamic clk case).
  705. */
  706. int dsi_phy_hw_calculate_timing_params(struct dsi_phy_hw *phy,
  707. struct dsi_mode_info *mode,
  708. struct dsi_host_common_cfg *host,
  709. struct dsi_phy_per_lane_cfgs *timing,
  710. bool use_mode_bit_clk)
  711. {
  712. /* constants */
  713. u32 const esc_clk_mhz = 192; /* TODO: esc clock is hardcoded */
  714. u32 const esc_clk_mmss_cc_prediv = 10;
  715. u32 const tlpx_numer = 1000;
  716. u32 const tr_eot = 20;
  717. u32 const clk_prepare_spec_min = 38;
  718. u32 const clk_prepare_spec_max = 95;
  719. u32 const clk_trail_spec_min = 60;
  720. u32 const hs_exit_spec_min = 100;
  721. u32 const hs_exit_reco_max = 255;
  722. u32 const hs_rqst_spec_min = 50;
  723. u32 const hs_rqst_reco_max = 255;
  724. /* local vars */
  725. int rc = 0;
  726. u32 h_total, v_total;
  727. u32 inter_num;
  728. u32 num_of_lanes = 0;
  729. u32 bpp;
  730. u64 x, y;
  731. struct phy_timing_desc desc;
  732. struct phy_clk_params clk_params = {0};
  733. struct phy_timing_ops *ops = phy->ops.timing_ops;
  734. u32 phy_type = host->phy_type;
  735. memset(&desc, 0x0, sizeof(desc));
  736. h_total = dsi_h_total_dce(mode);
  737. v_total = DSI_V_TOTAL(mode);
  738. bpp = bits_per_pixel[host->dst_format];
  739. inter_num = bpp * mode->refresh_rate;
  740. if (host->data_lanes & DSI_DATA_LANE_0)
  741. num_of_lanes++;
  742. if (host->data_lanes & DSI_DATA_LANE_1)
  743. num_of_lanes++;
  744. if (host->data_lanes & DSI_DATA_LANE_2)
  745. num_of_lanes++;
  746. if (host->data_lanes & DSI_DATA_LANE_3)
  747. num_of_lanes++;
  748. if (use_mode_bit_clk)
  749. x = mode->clk_rate_hz;
  750. else {
  751. x = mult_frac(v_total * h_total, inter_num, num_of_lanes);
  752. if (phy_type == DSI_PHY_TYPE_CPHY)
  753. x = mult_frac(x, 7, 16);
  754. }
  755. y = rounddown(x, 1);
  756. clk_params.bitclk_mbps = rounddown(DIV_ROUND_UP_ULL(y, 1000000), 1);
  757. clk_params.escclk_numer = esc_clk_mhz;
  758. clk_params.escclk_denom = esc_clk_mmss_cc_prediv;
  759. clk_params.tlpx_numer_ns = tlpx_numer;
  760. clk_params.treot_ns = tr_eot;
  761. /* Setup default parameters */
  762. desc.clk_prepare.mipi_min = clk_prepare_spec_min;
  763. desc.clk_prepare.mipi_max = clk_prepare_spec_max;
  764. desc.clk_trail.mipi_min = clk_trail_spec_min;
  765. desc.hs_exit.mipi_min = hs_exit_spec_min;
  766. desc.hs_exit.rec_max = hs_exit_reco_max;
  767. desc.hs_rqst.mipi_min = hs_rqst_spec_min;
  768. desc.hs_rqst_clk.mipi_min = hs_rqst_spec_min;
  769. desc.hs_rqst.rec_max = hs_rqst_reco_max;
  770. if (ops->get_default_phy_params) {
  771. ops->get_default_phy_params(&clk_params, phy_type);
  772. } else {
  773. rc = -EINVAL;
  774. goto error;
  775. }
  776. DSI_PHY_DBG(phy, "BIT CLOCK = %d, tlpx_numer_ns=%d, treot_ns=%d\n",
  777. clk_params.bitclk_mbps, clk_params.tlpx_numer_ns,
  778. clk_params.treot_ns);
  779. if (phy_type == DSI_PHY_TYPE_CPHY)
  780. rc = dsi_phy_cmn_calc_cphy_timing_params(phy, &clk_params,
  781. &desc);
  782. else
  783. rc = dsi_phy_cmn_calc_timing_params(phy, &clk_params, &desc);
  784. if (rc) {
  785. DSI_PHY_ERR(phy, "Timing calc failed, rc=%d\n", rc);
  786. goto error;
  787. }
  788. if (ops->update_timing_params) {
  789. ops->update_timing_params(timing, &desc, phy_type);
  790. } else {
  791. rc = -EINVAL;
  792. goto error;
  793. }
  794. error:
  795. return rc;
  796. }
  797. int dsi_phy_timing_calc_init(struct dsi_phy_hw *phy,
  798. enum dsi_phy_version version)
  799. {
  800. struct phy_timing_ops *ops = NULL;
  801. if (version == DSI_PHY_VERSION_UNKNOWN ||
  802. version >= DSI_PHY_VERSION_MAX || !phy) {
  803. DSI_PHY_ERR(phy, "Unsupported version: %d\n", version);
  804. return -ENOTSUPP;
  805. }
  806. ops = kzalloc(sizeof(struct phy_timing_ops), GFP_KERNEL);
  807. if (!ops)
  808. return -EINVAL;
  809. phy->ops.timing_ops = ops;
  810. switch (version) {
  811. case DSI_PHY_VERSION_3_0:
  812. ops->get_default_phy_params =
  813. dsi_phy_hw_v3_0_get_default_phy_params;
  814. ops->calc_clk_zero =
  815. dsi_phy_hw_v3_0_calc_clk_zero;
  816. ops->calc_clk_trail_rec_min =
  817. dsi_phy_hw_v3_0_calc_clk_trail_rec_min;
  818. ops->calc_clk_trail_rec_max =
  819. dsi_phy_hw_v3_0_calc_clk_trail_rec_max;
  820. ops->calc_hs_zero =
  821. dsi_phy_hw_v3_0_calc_hs_zero;
  822. ops->calc_hs_trail =
  823. dsi_phy_hw_v3_0_calc_hs_trail;
  824. ops->update_timing_params =
  825. dsi_phy_hw_v3_0_update_timing_params;
  826. break;
  827. case DSI_PHY_VERSION_4_0:
  828. case DSI_PHY_VERSION_4_1:
  829. case DSI_PHY_VERSION_4_2:
  830. case DSI_PHY_VERSION_4_3:
  831. case DSI_PHY_VERSION_4_3_2:
  832. case DSI_PHY_VERSION_5_2:
  833. ops->get_default_phy_params =
  834. dsi_phy_hw_v4_0_get_default_phy_params;
  835. ops->calc_clk_zero =
  836. dsi_phy_hw_v4_0_calc_clk_zero;
  837. ops->calc_clk_trail_rec_min =
  838. dsi_phy_hw_v4_0_calc_clk_trail_rec_min;
  839. ops->calc_clk_trail_rec_max =
  840. dsi_phy_hw_v4_0_calc_clk_trail_rec_max;
  841. ops->calc_hs_zero =
  842. dsi_phy_hw_v4_0_calc_hs_zero;
  843. ops->calc_hs_trail =
  844. dsi_phy_hw_v4_0_calc_hs_trail;
  845. ops->update_timing_params =
  846. dsi_phy_hw_v4_0_update_timing_params;
  847. break;
  848. default:
  849. kfree(ops);
  850. return -ENOTSUPP;
  851. }
  852. return 0;
  853. }