dsi_phy_timing_calc.c 27 KB

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