dsi_pll_14nm_util.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "%s: " fmt, __func__
  6. #include <linux/kernel.h>
  7. #include <linux/err.h>
  8. #include <linux/iopoll.h>
  9. #include <linux/delay.h>
  10. #include "pll_drv.h"
  11. #include "dsi_pll.h"
  12. #include "dsi_pll_14nm.h"
  13. #define DSI_PLL_POLL_MAX_READS 15
  14. #define DSI_PLL_POLL_TIMEOUT_US 1000
  15. #define MSM8996_DSI_PLL_REVISION_2 2
  16. #define VCO_REF_CLK_RATE 19200000
  17. #define CEIL(x, y) (((x) + ((y)-1)) / (y))
  18. static int mdss_pll_read_stored_trim_codes(
  19. struct mdss_pll_resources *dsi_pll_res, s64 vco_clk_rate)
  20. {
  21. int i;
  22. int rc = 0;
  23. bool found = false;
  24. if (!dsi_pll_res->dfps) {
  25. rc = -EINVAL;
  26. goto end_read;
  27. }
  28. for (i = 0; i < dsi_pll_res->dfps->vco_rate_cnt; i++) {
  29. struct dfps_codes_info *codes_info =
  30. &dsi_pll_res->dfps->codes_dfps[i];
  31. pr_debug("valid=%d frame_rate=%d, code %d %d\n",
  32. codes_info->is_valid,
  33. codes_info->clk_rate, codes_info->pll_codes.pll_codes_1,
  34. codes_info->pll_codes.pll_codes_2);
  35. if (vco_clk_rate != codes_info->clk_rate &&
  36. codes_info->is_valid)
  37. continue;
  38. dsi_pll_res->cache_pll_trim_codes[0] =
  39. codes_info->pll_codes.pll_codes_1;
  40. dsi_pll_res->cache_pll_trim_codes[1] =
  41. codes_info->pll_codes.pll_codes_2;
  42. found = true;
  43. break;
  44. }
  45. if (!found) {
  46. rc = -EINVAL;
  47. goto end_read;
  48. }
  49. pr_debug("core_kvco_code=0x%x core_vco_tune=0x%x\n",
  50. dsi_pll_res->cache_pll_trim_codes[0],
  51. dsi_pll_res->cache_pll_trim_codes[1]);
  52. end_read:
  53. return rc;
  54. }
  55. int post_n1_div_set_div(void *context, unsigned int reg, unsigned int div)
  56. {
  57. struct mdss_pll_resources *pll = context;
  58. struct dsi_pll_db *pdb;
  59. struct dsi_pll_output *pout;
  60. int rc;
  61. u32 n1div = 0;
  62. rc = mdss_pll_resource_enable(pll, true);
  63. if (rc) {
  64. pr_err("Failed to enable mdss dsi pll resources\n");
  65. return rc;
  66. }
  67. /* in common clock framework the divider value provided is one less */
  68. div++;
  69. pdb = (struct dsi_pll_db *)pll->priv;
  70. pout = &pdb->out;
  71. /*
  72. * vco rate = bit_clk * postdiv * n1div
  73. * vco range from 1300 to 2600 Mhz
  74. * postdiv = 1
  75. * n1div = 1 to 15
  76. * n1div = roundup(1300Mhz / bit_clk)
  77. * support bit_clk above 86.67Mhz
  78. */
  79. pout->pll_n1div = div;
  80. n1div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
  81. n1div &= ~0xf;
  82. n1div |= (div & 0xf);
  83. MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n1div);
  84. /* ensure n1 divider is programed */
  85. wmb();
  86. pr_debug("ndx=%d div=%d postdiv=%x n1div=%x\n",
  87. pll->index, div, pout->pll_postdiv, pout->pll_n1div);
  88. mdss_pll_resource_enable(pll, false);
  89. return 0;
  90. }
  91. int post_n1_div_get_div(void *context, unsigned int reg, unsigned int *div)
  92. {
  93. int rc;
  94. struct mdss_pll_resources *pll = context;
  95. struct dsi_pll_db *pdb;
  96. struct dsi_pll_output *pout;
  97. pdb = (struct dsi_pll_db *)pll->priv;
  98. pout = &pdb->out;
  99. if (is_gdsc_disabled(pll))
  100. return 0;
  101. rc = mdss_pll_resource_enable(pll, true);
  102. if (rc) {
  103. pr_err("Failed to enable mdss dsi pll resources\n");
  104. return rc;
  105. }
  106. /*
  107. * postdiv = 1/2/4/8
  108. * n1div = 1 - 15
  109. * fot the time being, assume postdiv = 1
  110. */
  111. *div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
  112. *div &= 0xF;
  113. /*
  114. * initialize n1div here, it will get updated when
  115. * corresponding set_div is called.
  116. */
  117. pout->pll_n1div = *div;
  118. /* common clock framework will add one to the divider value sent */
  119. if (*div == 0)
  120. *div = 1; /* value of zero means div is 2 as per SWI */
  121. else
  122. *div -= 1;
  123. pr_debug("post n1 get div = %d\n", *div);
  124. mdss_pll_resource_enable(pll, false);
  125. return rc;
  126. }
  127. int n2_div_set_div(void *context, unsigned int reg, unsigned int div)
  128. {
  129. int rc;
  130. u32 n2div;
  131. struct mdss_pll_resources *pll = context;
  132. struct dsi_pll_db *pdb;
  133. struct dsi_pll_output *pout;
  134. struct mdss_pll_resources *slave;
  135. rc = mdss_pll_resource_enable(pll, true);
  136. if (rc) {
  137. pr_err("Failed to enable mdss dsi pll resources\n");
  138. return rc;
  139. }
  140. /*
  141. * in common clock framework the actual divider value
  142. * provided is one less.
  143. */
  144. div++;
  145. pdb = (struct dsi_pll_db *)pll->priv;
  146. pout = &pdb->out;
  147. /* this is for pixel clock */
  148. n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
  149. n2div &= ~0xf0; /* bits 4 to 7 */
  150. n2div |= (div << 4);
  151. MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG0, n2div);
  152. /* commit slave if split display is enabled */
  153. slave = pll->slave;
  154. if (slave)
  155. MDSS_PLL_REG_W(slave->pll_base, DSIPHY_CMN_CLK_CFG0, n2div);
  156. pout->pll_n2div = div;
  157. /* set dsiclk_sel=1 so that n2div *= 2 */
  158. MDSS_PLL_REG_W(pll->pll_base, DSIPHY_CMN_CLK_CFG1, 1);
  159. pr_debug("ndx=%d div=%d n2div=%x\n", pll->index, div, n2div);
  160. mdss_pll_resource_enable(pll, false);
  161. return rc;
  162. }
  163. int shadow_n2_div_set_div(void *context, unsigned int reg, unsigned int div)
  164. {
  165. struct mdss_pll_resources *pll = context;
  166. struct dsi_pll_db *pdb;
  167. struct dsi_pll_output *pout;
  168. u32 data;
  169. pdb = pll->priv;
  170. pout = &pdb->out;
  171. /*
  172. * in common clock framework the actual divider value
  173. * provided is one less.
  174. */
  175. div++;
  176. pout->pll_n2div = div;
  177. data = (pout->pll_n1div | (pout->pll_n2div << 4));
  178. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  179. DSI_DYNAMIC_REFRESH_PLL_CTRL19,
  180. DSIPHY_CMN_CLK_CFG0, DSIPHY_CMN_CLK_CFG1,
  181. data, 1);
  182. return 0;
  183. }
  184. int n2_div_get_div(void *context, unsigned int reg, unsigned int *div)
  185. {
  186. int rc;
  187. u32 n2div;
  188. struct mdss_pll_resources *pll = context;
  189. struct dsi_pll_db *pdb;
  190. struct dsi_pll_output *pout;
  191. if (is_gdsc_disabled(pll))
  192. return 0;
  193. pdb = (struct dsi_pll_db *)pll->priv;
  194. pout = &pdb->out;
  195. rc = mdss_pll_resource_enable(pll, true);
  196. if (rc) {
  197. pr_err("Failed to enable mdss dsi pll=%d resources\n",
  198. pll->index);
  199. return rc;
  200. }
  201. n2div = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_CMN_CLK_CFG0);
  202. n2div >>= 4;
  203. n2div &= 0x0f;
  204. /*
  205. * initialize n2div here, it will get updated when
  206. * corresponding set_div is called.
  207. */
  208. pout->pll_n2div = n2div;
  209. mdss_pll_resource_enable(pll, false);
  210. *div = n2div;
  211. /* common clock framework will add one to the divider value sent */
  212. if (*div == 0)
  213. *div = 1; /* value of zero means div is 2 as per SWI */
  214. else
  215. *div -= 1;
  216. pr_debug("ndx=%d div=%d\n", pll->index, *div);
  217. return rc;
  218. }
  219. static bool pll_is_pll_locked_14nm(struct mdss_pll_resources *pll)
  220. {
  221. u32 status;
  222. bool pll_locked;
  223. /* poll for PLL ready status */
  224. if (readl_poll_timeout_atomic((pll->pll_base +
  225. DSIPHY_PLL_RESET_SM_READY_STATUS),
  226. status,
  227. ((status & BIT(5)) > 0),
  228. DSI_PLL_POLL_MAX_READS,
  229. DSI_PLL_POLL_TIMEOUT_US)) {
  230. pr_err("DSI PLL ndx=%d status=%x failed to Lock\n",
  231. pll->index, status);
  232. pll_locked = false;
  233. } else if (readl_poll_timeout_atomic((pll->pll_base +
  234. DSIPHY_PLL_RESET_SM_READY_STATUS),
  235. status,
  236. ((status & BIT(0)) > 0),
  237. DSI_PLL_POLL_MAX_READS,
  238. DSI_PLL_POLL_TIMEOUT_US)) {
  239. pr_err("DSI PLL ndx=%d status=%x PLl not ready\n",
  240. pll->index, status);
  241. pll_locked = false;
  242. } else {
  243. pll_locked = true;
  244. }
  245. return pll_locked;
  246. }
  247. static void dsi_pll_start_14nm(void __iomem *pll_base)
  248. {
  249. pr_debug("start PLL at base=%pK\n", pll_base);
  250. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VREF_CFG1, 0x10);
  251. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 1);
  252. }
  253. static void dsi_pll_stop_14nm(void __iomem *pll_base)
  254. {
  255. pr_debug("stop PLL at base=%pK\n", pll_base);
  256. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0);
  257. }
  258. int dsi_pll_enable_seq_14nm(struct mdss_pll_resources *pll)
  259. {
  260. int rc = 0;
  261. if (!pll) {
  262. pr_err("Invalid PLL resources\n");
  263. return -EINVAL;
  264. }
  265. dsi_pll_start_14nm(pll->pll_base);
  266. /*
  267. * both DSIPHY_PLL_CLKBUFLR_EN and DSIPHY_CMN_GLBL_TEST_CTRL
  268. * enabled at mdss_dsi_14nm_phy_config()
  269. */
  270. if (!pll_is_pll_locked_14nm(pll)) {
  271. pr_err("DSI PLL ndx=%d lock failed\n", pll->index);
  272. rc = -EINVAL;
  273. goto init_lock_err;
  274. }
  275. pr_debug("DSI PLL ndx=%d Lock success\n", pll->index);
  276. init_lock_err:
  277. return rc;
  278. }
  279. static int dsi_pll_enable(struct clk_hw *hw)
  280. {
  281. int i, rc = 0;
  282. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  283. struct mdss_pll_resources *pll = vco->priv;
  284. /* Try all enable sequences until one succeeds */
  285. for (i = 0; i < vco->pll_en_seq_cnt; i++) {
  286. rc = vco->pll_enable_seqs[i](pll);
  287. pr_debug("DSI PLL %s after sequence #%d\n",
  288. rc ? "unlocked" : "locked", i + 1);
  289. if (!rc)
  290. break;
  291. }
  292. if (rc)
  293. pr_err("ndx=%d DSI PLL failed to lock\n", pll->index);
  294. else
  295. pll->pll_on = true;
  296. return rc;
  297. }
  298. static void dsi_pll_disable(struct clk_hw *hw)
  299. {
  300. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  301. struct mdss_pll_resources *pll = vco->priv;
  302. struct mdss_pll_resources *slave;
  303. if (!pll->pll_on &&
  304. mdss_pll_resource_enable(pll, true)) {
  305. pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
  306. return;
  307. }
  308. pll->handoff_resources = false;
  309. slave = pll->slave;
  310. dsi_pll_stop_14nm(pll->pll_base);
  311. mdss_pll_resource_enable(pll, false);
  312. pll->pll_on = false;
  313. pr_debug("DSI PLL ndx=%d Disabled\n", pll->index);
  314. }
  315. static void mdss_dsi_pll_14nm_input_init(struct mdss_pll_resources *pll,
  316. struct dsi_pll_db *pdb)
  317. {
  318. pdb->in.fref = 19200000; /* 19.2 Mhz*/
  319. pdb->in.fdata = 0; /* bit clock rate */
  320. pdb->in.dsiclk_sel = 1; /* 1, reg: 0x0014 */
  321. pdb->in.ssc_en = pll->ssc_en; /* 1, reg: 0x0494, bit 0 */
  322. pdb->in.ldo_en = 0; /* 0, reg: 0x004c, bit 0 */
  323. /* fixed input */
  324. pdb->in.refclk_dbler_en = 0; /* 0, reg: 0x04c0, bit 1 */
  325. pdb->in.vco_measure_time = 5; /* 5, unknown */
  326. pdb->in.kvco_measure_time = 5; /* 5, unknown */
  327. pdb->in.bandgap_timer = 4; /* 4, reg: 0x0430, bit 3 - 5 */
  328. pdb->in.pll_wakeup_timer = 5; /* 5, reg: 0x043c, bit 0 - 2 */
  329. pdb->in.plllock_cnt = 1; /* 1, reg: 0x0488, bit 1 - 2 */
  330. pdb->in.plllock_rng = 0; /* 0, reg: 0x0488, bit 3 - 4 */
  331. pdb->in.ssc_center = pll->ssc_center;/* 0, reg: 0x0494, bit 1 */
  332. pdb->in.ssc_adj_period = 37; /* 37, reg: 0x498, bit 0 - 9 */
  333. pdb->in.ssc_spread = pll->ssc_ppm / 1000;
  334. pdb->in.ssc_freq = pll->ssc_freq;
  335. pdb->in.pll_ie_trim = 4; /* 4, reg: 0x0400 */
  336. pdb->in.pll_ip_trim = 4; /* 4, reg: 0x0404 */
  337. pdb->in.pll_cpcset_cur = 1; /* 1, reg: 0x04f0, bit 0 - 2 */
  338. pdb->in.pll_cpmset_cur = 1; /* 1, reg: 0x04f0, bit 3 - 5 */
  339. pdb->in.pll_icpmset = 4; /* 4, reg: 0x04fc, bit 3 - 5 */
  340. pdb->in.pll_icpcset = 4; /* 4, reg: 0x04fc, bit 0 - 2 */
  341. pdb->in.pll_icpmset_p = 0; /* 0, reg: 0x04f4, bit 0 - 2 */
  342. pdb->in.pll_icpmset_m = 0; /* 0, reg: 0x04f4, bit 3 - 5 */
  343. pdb->in.pll_icpcset_p = 0; /* 0, reg: 0x04f8, bit 0 - 2 */
  344. pdb->in.pll_icpcset_m = 0; /* 0, reg: 0x04f8, bit 3 - 5 */
  345. pdb->in.pll_lpf_res1 = 3; /* 3, reg: 0x0504, bit 0 - 3 */
  346. pdb->in.pll_lpf_cap1 = 11; /* 11, reg: 0x0500, bit 0 - 3 */
  347. pdb->in.pll_lpf_cap2 = 1; /* 1, reg: 0x0500, bit 4 - 7 */
  348. pdb->in.pll_iptat_trim = 7;
  349. pdb->in.pll_c3ctrl = 2; /* 2 */
  350. pdb->in.pll_r3ctrl = 1; /* 1 */
  351. pdb->out.pll_postdiv = 1;
  352. }
  353. static void pll_14nm_ssc_calc(struct mdss_pll_resources *pll,
  354. struct dsi_pll_db *pdb)
  355. {
  356. u32 period, ssc_period;
  357. u32 ref, rem;
  358. s64 step_size;
  359. pr_debug("%s: vco=%lld ref=%lld\n", __func__,
  360. pll->vco_current_rate, pll->vco_ref_clk_rate);
  361. ssc_period = pdb->in.ssc_freq / 500;
  362. period = (unsigned long)pll->vco_ref_clk_rate / 1000;
  363. ssc_period = CEIL(period, ssc_period);
  364. ssc_period -= 1;
  365. pdb->out.ssc_period = ssc_period;
  366. pr_debug("%s: ssc, freq=%d spread=%d period=%d\n", __func__,
  367. pdb->in.ssc_freq, pdb->in.ssc_spread, pdb->out.ssc_period);
  368. step_size = (u32)pll->vco_current_rate;
  369. ref = pll->vco_ref_clk_rate;
  370. ref /= 1000;
  371. step_size = div_s64(step_size, ref);
  372. step_size <<= 20;
  373. step_size = div_s64(step_size, 1000);
  374. step_size *= pdb->in.ssc_spread;
  375. step_size = div_s64(step_size, 1000);
  376. step_size *= (pdb->in.ssc_adj_period + 1);
  377. rem = 0;
  378. step_size = div_s64_rem(step_size, ssc_period + 1, &rem);
  379. if (rem)
  380. step_size++;
  381. pr_debug("%s: step_size=%lld\n", __func__, step_size);
  382. step_size &= 0x0ffff; /* take lower 16 bits */
  383. pdb->out.ssc_step_size = step_size;
  384. }
  385. static void pll_14nm_dec_frac_calc(struct mdss_pll_resources *pll,
  386. struct dsi_pll_db *pdb)
  387. {
  388. struct dsi_pll_input *pin = &pdb->in;
  389. struct dsi_pll_output *pout = &pdb->out;
  390. u64 multiplier = BIT(20);
  391. u64 dec_start_multiple, dec_start, pll_comp_val;
  392. s32 duration, div_frac_start;
  393. s64 vco_clk_rate = pll->vco_current_rate;
  394. s64 fref = pll->vco_ref_clk_rate;
  395. pr_debug("vco_clk_rate=%lld ref_clk_rate=%lld\n",
  396. vco_clk_rate, fref);
  397. dec_start_multiple = div_s64(vco_clk_rate * multiplier, fref);
  398. div_s64_rem(dec_start_multiple, multiplier, &div_frac_start);
  399. dec_start = div_s64(dec_start_multiple, multiplier);
  400. pout->dec_start = (u32)dec_start;
  401. pout->div_frac_start = div_frac_start;
  402. if (pin->plllock_cnt == 0)
  403. duration = 1024;
  404. else if (pin->plllock_cnt == 1)
  405. duration = 256;
  406. else if (pin->plllock_cnt == 2)
  407. duration = 128;
  408. else
  409. duration = 32;
  410. pll_comp_val = duration * dec_start_multiple;
  411. pll_comp_val = div_u64(pll_comp_val, multiplier);
  412. do_div(pll_comp_val, 10);
  413. pout->plllock_cmp = (u32)pll_comp_val;
  414. pout->pll_txclk_en = 1;
  415. if (pll->revision == MSM8996_DSI_PLL_REVISION_2)
  416. pout->cmn_ldo_cntrl = 0x3c;
  417. else
  418. pout->cmn_ldo_cntrl = 0x1c;
  419. }
  420. static u32 pll_14nm_kvco_slop(u32 vrate)
  421. {
  422. u32 slop = 0;
  423. if (vrate > 1300000000UL && vrate <= 1800000000UL)
  424. slop = 600;
  425. else if (vrate > 1800000000UL && vrate < 2300000000UL)
  426. slop = 400;
  427. else if (vrate > 2300000000UL && vrate < 2600000000UL)
  428. slop = 280;
  429. return slop;
  430. }
  431. static void pll_14nm_calc_vco_count(struct dsi_pll_db *pdb,
  432. s64 vco_clk_rate, s64 fref)
  433. {
  434. struct dsi_pll_input *pin = &pdb->in;
  435. struct dsi_pll_output *pout = &pdb->out;
  436. u64 data;
  437. u32 cnt;
  438. data = fref * pin->vco_measure_time;
  439. do_div(data, 1000000);
  440. data &= 0x03ff; /* 10 bits */
  441. data -= 2;
  442. pout->pll_vco_div_ref = data;
  443. data = (unsigned long)vco_clk_rate / 1000000; /* unit is Mhz */
  444. data *= pin->vco_measure_time;
  445. do_div(data, 10);
  446. pout->pll_vco_count = data; /* reg: 0x0474, 0x0478 */
  447. data = fref * pin->kvco_measure_time;
  448. do_div(data, 1000000);
  449. data &= 0x03ff; /* 10 bits */
  450. data -= 1;
  451. pout->pll_kvco_div_ref = data;
  452. cnt = pll_14nm_kvco_slop(vco_clk_rate);
  453. cnt *= 2;
  454. cnt /= 100;
  455. cnt *= pin->kvco_measure_time;
  456. pout->pll_kvco_count = cnt;
  457. pout->pll_misc1 = 16;
  458. pout->pll_resetsm_cntrl = 48;
  459. pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3;
  460. pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer;
  461. pout->pll_kvco_code = 0;
  462. }
  463. static void pll_db_commit_ssc(struct mdss_pll_resources *pll,
  464. struct dsi_pll_db *pdb)
  465. {
  466. void __iomem *pll_base = pll->pll_base;
  467. struct dsi_pll_input *pin = &pdb->in;
  468. struct dsi_pll_output *pout = &pdb->out;
  469. char data;
  470. data = pin->ssc_adj_period;
  471. data &= 0x0ff;
  472. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER1, data);
  473. data = (pin->ssc_adj_period >> 8);
  474. data &= 0x03;
  475. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_ADJ_PER2, data);
  476. data = pout->ssc_period;
  477. data &= 0x0ff;
  478. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER1, data);
  479. data = (pout->ssc_period >> 8);
  480. data &= 0x0ff;
  481. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_PER2, data);
  482. data = pout->ssc_step_size;
  483. data &= 0x0ff;
  484. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE1, data);
  485. data = (pout->ssc_step_size >> 8);
  486. data &= 0x0ff;
  487. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_STEP_SIZE2, data);
  488. data = (pin->ssc_center & 0x01);
  489. data <<= 1;
  490. data |= 0x01; /* enable */
  491. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SSC_EN_CENTER, data);
  492. wmb(); /* make sure register committed */
  493. }
  494. static void pll_db_commit_common(struct mdss_pll_resources *pll,
  495. struct dsi_pll_db *pdb)
  496. {
  497. void __iomem *pll_base = pll->pll_base;
  498. struct dsi_pll_input *pin = &pdb->in;
  499. struct dsi_pll_output *pout = &pdb->out;
  500. char data;
  501. /* confgiure the non frequency dependent pll registers */
  502. data = 0;
  503. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_SYSCLK_EN_RESET, data);
  504. /* DSIPHY_PLL_CLKBUFLR_EN updated at dsi phy */
  505. data = pout->pll_txclk_en;
  506. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_TXCLK_EN, data);
  507. data = pout->pll_resetsm_cntrl;
  508. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL, data);
  509. data = pout->pll_resetsm_cntrl2;
  510. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL2, data);
  511. data = pout->pll_resetsm_cntrl5;
  512. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_RESETSM_CNTRL5, data);
  513. data = pout->pll_vco_div_ref;
  514. data &= 0x0ff;
  515. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF1, data);
  516. data = (pout->pll_vco_div_ref >> 8);
  517. data &= 0x03;
  518. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_DIV_REF2, data);
  519. data = pout->pll_kvco_div_ref;
  520. data &= 0x0ff;
  521. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF1, data);
  522. data = (pout->pll_kvco_div_ref >> 8);
  523. data &= 0x03;
  524. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_DIV_REF2, data);
  525. data = pout->pll_misc1;
  526. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_MISC1, data);
  527. data = pin->pll_ie_trim;
  528. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IE_TRIM, data);
  529. data = pin->pll_ip_trim;
  530. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IP_TRIM, data);
  531. data = ((pin->pll_cpmset_cur << 3) | pin->pll_cpcset_cur);
  532. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CP_SET_CUR, data);
  533. data = ((pin->pll_icpcset_p << 3) | pin->pll_icpcset_m);
  534. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPCSET, data);
  535. data = ((pin->pll_icpmset_p << 3) | pin->pll_icpcset_m);
  536. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICPMSET, data);
  537. data = ((pin->pll_icpmset << 3) | pin->pll_icpcset);
  538. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_ICP_SET, data);
  539. data = ((pdb->in.pll_lpf_cap2 << 4) | pdb->in.pll_lpf_cap1);
  540. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF1, data);
  541. data = pin->pll_iptat_trim;
  542. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_IPTAT_TRIM, data);
  543. data = (pdb->in.pll_c3ctrl | (pdb->in.pll_r3ctrl << 4));
  544. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_CRCTRL, data);
  545. }
  546. static void pll_db_commit_14nm(struct mdss_pll_resources *pll,
  547. struct dsi_pll_db *pdb)
  548. {
  549. void __iomem *pll_base = pll->pll_base;
  550. struct dsi_pll_input *pin = &pdb->in;
  551. struct dsi_pll_output *pout = &pdb->out;
  552. char data;
  553. data = pout->cmn_ldo_cntrl;
  554. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_LDO_CNTRL, data);
  555. pll_db_commit_common(pll, pdb);
  556. /* de assert pll start and apply pll sw reset */
  557. /* stop pll */
  558. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_PLL_CNTRL, 0);
  559. /* pll sw reset */
  560. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0x20);
  561. wmb(); /* make sure register committed */
  562. udelay(10);
  563. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_1, 0);
  564. wmb(); /* make sure register committed */
  565. data = pdb->in.dsiclk_sel; /* set dsiclk_sel = 1 */
  566. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG1, data);
  567. data = 0xff; /* data, clk, pll normal operation */
  568. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CTRL_0, data);
  569. /* confgiure the frequency dependent pll registers */
  570. data = pout->dec_start;
  571. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DEC_START, data);
  572. data = pout->div_frac_start;
  573. data &= 0x0ff;
  574. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START1, data);
  575. data = (pout->div_frac_start >> 8);
  576. data &= 0x0ff;
  577. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START2, data);
  578. data = (pout->div_frac_start >> 16);
  579. data &= 0x0f;
  580. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_DIV_FRAC_START3, data);
  581. data = pout->plllock_cmp;
  582. data &= 0x0ff;
  583. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP1, data);
  584. data = (pout->plllock_cmp >> 8);
  585. data &= 0x0ff;
  586. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP2, data);
  587. data = (pout->plllock_cmp >> 16);
  588. data &= 0x03;
  589. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP3, data);
  590. data = ((pin->plllock_cnt << 1) | (pin->plllock_rng << 3));
  591. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLLLOCK_CMP_EN, data);
  592. data = pout->pll_vco_count;
  593. data &= 0x0ff;
  594. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT1, data);
  595. data = (pout->pll_vco_count >> 8);
  596. data &= 0x0ff;
  597. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_COUNT2, data);
  598. data = pout->pll_kvco_count;
  599. data &= 0x0ff;
  600. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT1, data);
  601. data = (pout->pll_kvco_count >> 8);
  602. data &= 0x03;
  603. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_KVCO_COUNT2, data);
  604. /*
  605. * tx_band = pll_postdiv
  606. * 0: divided by 1 <== for now
  607. * 1: divided by 2
  608. * 2: divided by 4
  609. * 3: divided by 8
  610. */
  611. data = (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1);
  612. MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PLL_LPF2_POSTDIV, data);
  613. data = (pout->pll_n1div | (pout->pll_n2div << 4));
  614. MDSS_PLL_REG_W(pll_base, DSIPHY_CMN_CLK_CFG0, data);
  615. if (pll->ssc_en)
  616. pll_db_commit_ssc(pll, pdb);
  617. wmb(); /* make sure register committed */
  618. }
  619. /*
  620. * pll_source_finding:
  621. * Both GLBL_TEST_CTRL and CLKBUFLR_EN are configured
  622. * at mdss_dsi_14nm_phy_config()
  623. */
  624. static int pll_source_finding(struct mdss_pll_resources *pll)
  625. {
  626. u32 clk_buf_en;
  627. u32 glbl_test_ctrl;
  628. glbl_test_ctrl = MDSS_PLL_REG_R(pll->pll_base,
  629. DSIPHY_CMN_GLBL_TEST_CTRL);
  630. clk_buf_en = MDSS_PLL_REG_R(pll->pll_base,
  631. DSIPHY_PLL_CLKBUFLR_EN);
  632. glbl_test_ctrl &= BIT(2);
  633. glbl_test_ctrl >>= 2;
  634. pr_debug("%s: pll=%d clk_buf_en=%x glbl_test_ctrl=%x\n",
  635. __func__, pll->index, clk_buf_en, glbl_test_ctrl);
  636. clk_buf_en &= (PLL_OUTPUT_RIGHT | PLL_OUTPUT_LEFT);
  637. if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) &&
  638. (clk_buf_en == PLL_OUTPUT_BOTH))
  639. return PLL_MASTER;
  640. if ((glbl_test_ctrl == PLL_SOURCE_FROM_RIGHT) &&
  641. (clk_buf_en == PLL_OUTPUT_NONE))
  642. return PLL_SLAVE;
  643. if ((glbl_test_ctrl == PLL_SOURCE_FROM_LEFT) &&
  644. (clk_buf_en == PLL_OUTPUT_RIGHT))
  645. return PLL_STANDALONE;
  646. pr_debug("%s: Error pll setup, clk_buf_en=%x glbl_test_ctrl=%x\n",
  647. __func__, clk_buf_en, glbl_test_ctrl);
  648. return PLL_UNKNOWN;
  649. }
  650. static void pll_source_setup(struct mdss_pll_resources *pll)
  651. {
  652. int status;
  653. struct dsi_pll_db *pdb = (struct dsi_pll_db *)pll->priv;
  654. struct mdss_pll_resources *other;
  655. if (pdb->source_setup_done)
  656. return;
  657. pdb->source_setup_done++;
  658. status = pll_source_finding(pll);
  659. if (status == PLL_STANDALONE || status == PLL_UNKNOWN)
  660. return;
  661. other = pdb->next->pll;
  662. if (!other)
  663. return;
  664. pr_debug("%s: status=%d pll=%d other=%d\n", __func__,
  665. status, pll->index, other->index);
  666. if (status == PLL_MASTER)
  667. pll->slave = other;
  668. else
  669. other->slave = pll;
  670. }
  671. unsigned long pll_vco_recalc_rate_14nm(struct clk_hw *hw,
  672. unsigned long parent_rate)
  673. {
  674. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  675. struct mdss_pll_resources *pll = vco->priv;
  676. u64 vco_rate, multiplier = BIT(20);
  677. s32 div_frac_start;
  678. u32 dec_start;
  679. u64 ref_clk = vco->ref_clk_rate;
  680. int rc;
  681. if (pll->vco_current_rate)
  682. return (unsigned long)pll->vco_current_rate;
  683. if (is_gdsc_disabled(pll))
  684. return 0;
  685. rc = mdss_pll_resource_enable(pll, true);
  686. if (rc) {
  687. pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
  688. return rc;
  689. }
  690. dec_start = MDSS_PLL_REG_R(pll->pll_base,
  691. DSIPHY_PLL_DEC_START);
  692. dec_start &= 0x0ff;
  693. pr_debug("dec_start = 0x%x\n", dec_start);
  694. div_frac_start = (MDSS_PLL_REG_R(pll->pll_base,
  695. DSIPHY_PLL_DIV_FRAC_START3) & 0x0f) << 16;
  696. div_frac_start |= (MDSS_PLL_REG_R(pll->pll_base,
  697. DSIPHY_PLL_DIV_FRAC_START2) & 0x0ff) << 8;
  698. div_frac_start |= MDSS_PLL_REG_R(pll->pll_base,
  699. DSIPHY_PLL_DIV_FRAC_START1) & 0x0ff;
  700. pr_debug("div_frac_start = 0x%x\n", div_frac_start);
  701. vco_rate = ref_clk * dec_start;
  702. vco_rate += ((ref_clk * div_frac_start) / multiplier);
  703. pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
  704. mdss_pll_resource_enable(pll, false);
  705. pr_debug("%s: returning vco rate as %lu\n",
  706. __func__, (unsigned long)vco_rate);
  707. return (unsigned long)vco_rate;
  708. }
  709. int pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate,
  710. unsigned long parent_rate)
  711. {
  712. int rc;
  713. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  714. struct mdss_pll_resources *pll = vco->priv;
  715. struct mdss_pll_resources *slave;
  716. struct dsi_pll_db *pdb;
  717. pdb = (struct dsi_pll_db *)pll->priv;
  718. if (!pdb) {
  719. pr_err("No prov found\n");
  720. return -EINVAL;
  721. }
  722. rc = mdss_pll_resource_enable(pll, true);
  723. if (rc) {
  724. pr_err("Failed to enable mdss dsi plla=%d\n", pll->index);
  725. return rc;
  726. }
  727. pll_source_setup(pll);
  728. pr_debug("%s: ndx=%d base=%pK rate=%lu slave=%pK\n", __func__,
  729. pll->index, pll->pll_base, rate, pll->slave);
  730. pll->vco_current_rate = rate;
  731. pll->vco_ref_clk_rate = vco->ref_clk_rate;
  732. mdss_dsi_pll_14nm_input_init(pll, pdb);
  733. pll_14nm_dec_frac_calc(pll, pdb);
  734. if (pll->ssc_en)
  735. pll_14nm_ssc_calc(pll, pdb);
  736. pll_14nm_calc_vco_count(pdb, pll->vco_current_rate,
  737. pll->vco_ref_clk_rate);
  738. /* commit slave if split display is enabled */
  739. slave = pll->slave;
  740. if (slave)
  741. pll_db_commit_14nm(slave, pdb);
  742. /* commit master itself */
  743. pll_db_commit_14nm(pll, pdb);
  744. mdss_pll_resource_enable(pll, false);
  745. return rc;
  746. }
  747. static void shadow_pll_dynamic_refresh_14nm(struct mdss_pll_resources *pll,
  748. struct dsi_pll_db *pdb)
  749. {
  750. struct dsi_pll_output *pout = &pdb->out;
  751. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  752. DSI_DYNAMIC_REFRESH_PLL_CTRL20,
  753. DSIPHY_CMN_CTRL_0, DSIPHY_PLL_SYSCLK_EN_RESET,
  754. 0xFF, 0x0);
  755. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  756. DSI_DYNAMIC_REFRESH_PLL_CTRL21,
  757. DSIPHY_PLL_DEC_START, DSIPHY_PLL_DIV_FRAC_START1,
  758. pout->dec_start, (pout->div_frac_start & 0x0FF));
  759. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  760. DSI_DYNAMIC_REFRESH_PLL_CTRL22,
  761. DSIPHY_PLL_DIV_FRAC_START2, DSIPHY_PLL_DIV_FRAC_START3,
  762. ((pout->div_frac_start >> 8) & 0x0FF),
  763. ((pout->div_frac_start >> 16) & 0x0F));
  764. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  765. DSI_DYNAMIC_REFRESH_PLL_CTRL23,
  766. DSIPHY_PLL_PLLLOCK_CMP1, DSIPHY_PLL_PLLLOCK_CMP2,
  767. (pout->plllock_cmp & 0x0FF),
  768. ((pout->plllock_cmp >> 8) & 0x0FF));
  769. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  770. DSI_DYNAMIC_REFRESH_PLL_CTRL24,
  771. DSIPHY_PLL_PLLLOCK_CMP3, DSIPHY_PLL_PLL_VCO_TUNE,
  772. ((pout->plllock_cmp >> 16) & 0x03),
  773. (pll->cache_pll_trim_codes[1] | BIT(7))); /* VCO tune*/
  774. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  775. DSI_DYNAMIC_REFRESH_PLL_CTRL25,
  776. DSIPHY_PLL_KVCO_CODE, DSIPHY_PLL_RESETSM_CNTRL,
  777. (pll->cache_pll_trim_codes[0] | BIT(5)), 0x38);
  778. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  779. DSI_DYNAMIC_REFRESH_PLL_CTRL26,
  780. DSIPHY_PLL_PLL_LPF2_POSTDIV, DSIPHY_CMN_PLL_CNTRL,
  781. (((pout->pll_postdiv - 1) << 4) | pdb->in.pll_lpf_res1), 0x01);
  782. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  783. DSI_DYNAMIC_REFRESH_PLL_CTRL27,
  784. DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL,
  785. 0x01, 0x01);
  786. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  787. DSI_DYNAMIC_REFRESH_PLL_CTRL28,
  788. DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL,
  789. 0x01, 0x01);
  790. MDSS_DYN_PLL_REG_W(pll->dyn_pll_base,
  791. DSI_DYNAMIC_REFRESH_PLL_CTRL29,
  792. DSIPHY_CMN_PLL_CNTRL, DSIPHY_CMN_PLL_CNTRL,
  793. 0x01, 0x01);
  794. MDSS_PLL_REG_W(pll->dyn_pll_base,
  795. DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, 0x0000001E);
  796. MDSS_PLL_REG_W(pll->dyn_pll_base,
  797. DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, 0x001FFE00);
  798. /*
  799. * Ensure all the dynamic refresh registers are written before
  800. * dynamic refresh to change the fps is triggered
  801. */
  802. wmb();
  803. }
  804. int shadow_pll_vco_set_rate_14nm(struct clk_hw *hw, unsigned long rate,
  805. unsigned long parent_rate)
  806. {
  807. int rc;
  808. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  809. struct mdss_pll_resources *pll = vco->priv;
  810. struct dsi_pll_db *pdb;
  811. s64 vco_clk_rate = (s64)rate;
  812. if (!pll) {
  813. pr_err("PLL data not found\n");
  814. return -EINVAL;
  815. }
  816. pdb = pll->priv;
  817. if (!pdb) {
  818. pr_err("No priv data found\n");
  819. return -EINVAL;
  820. }
  821. rc = mdss_pll_read_stored_trim_codes(pll, vco_clk_rate);
  822. if (rc) {
  823. pr_err("cannot find pll codes rate=%lld\n", vco_clk_rate);
  824. return -EINVAL;
  825. }
  826. rc = mdss_pll_resource_enable(pll, true);
  827. if (rc) {
  828. pr_err("Failed to enable mdss dsi plla=%d\n", pll->index);
  829. return rc;
  830. }
  831. pr_debug("%s: ndx=%d base=%pK rate=%lu\n", __func__,
  832. pll->index, pll->pll_base, rate);
  833. pll->vco_current_rate = rate;
  834. pll->vco_ref_clk_rate = vco->ref_clk_rate;
  835. mdss_dsi_pll_14nm_input_init(pll, pdb);
  836. pll_14nm_dec_frac_calc(pll, pdb);
  837. pll_14nm_calc_vco_count(pdb, pll->vco_current_rate,
  838. pll->vco_ref_clk_rate);
  839. shadow_pll_dynamic_refresh_14nm(pll, pdb);
  840. rc = mdss_pll_resource_enable(pll, false);
  841. if (rc) {
  842. pr_err("Failed to enable mdss dsi plla=%d\n", pll->index);
  843. return rc;
  844. }
  845. return rc;
  846. }
  847. long pll_vco_round_rate_14nm(struct clk_hw *hw, unsigned long rate,
  848. unsigned long *parent_rate)
  849. {
  850. unsigned long rrate = rate;
  851. u32 div;
  852. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  853. div = vco->min_rate / rate;
  854. if (div > 15) {
  855. /* rate < 86.67 Mhz */
  856. pr_err("rate=%lu NOT supportted\n", rate);
  857. return -EINVAL;
  858. }
  859. if (rate < vco->min_rate)
  860. rrate = vco->min_rate;
  861. if (rate > vco->max_rate)
  862. rrate = vco->max_rate;
  863. *parent_rate = rrate;
  864. return rrate;
  865. }
  866. int pll_vco_prepare_14nm(struct clk_hw *hw)
  867. {
  868. int rc = 0;
  869. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  870. struct mdss_pll_resources *pll = vco->priv;
  871. if (!pll) {
  872. pr_err("Dsi pll resources are not available\n");
  873. return -EINVAL;
  874. }
  875. rc = mdss_pll_resource_enable(pll, true);
  876. if (rc) {
  877. pr_err("ndx=%d Failed to enable mdss dsi pll resources\n",
  878. pll->index);
  879. return rc;
  880. }
  881. if ((pll->vco_cached_rate != 0)
  882. && (pll->vco_cached_rate == clk_hw_get_rate(hw))) {
  883. rc = hw->init->ops->set_rate(hw, pll->vco_cached_rate,
  884. pll->vco_cached_rate);
  885. if (rc) {
  886. pr_err("index=%d vco_set_rate failed. rc=%d\n",
  887. rc, pll->index);
  888. mdss_pll_resource_enable(pll, false);
  889. goto error;
  890. }
  891. }
  892. rc = dsi_pll_enable(hw);
  893. if (rc) {
  894. mdss_pll_resource_enable(pll, false);
  895. pr_err("ndx=%d failed to enable dsi pll\n", pll->index);
  896. }
  897. error:
  898. return rc;
  899. }
  900. void pll_vco_unprepare_14nm(struct clk_hw *hw)
  901. {
  902. struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
  903. struct mdss_pll_resources *pll = vco->priv;
  904. if (!pll) {
  905. pr_err("Dsi pll resources are not available\n");
  906. return;
  907. }
  908. pll->vco_cached_rate = clk_hw_get_rate(hw);
  909. dsi_pll_disable(hw);
  910. }
  911. int dsi_mux_set_parent_14nm(void *context, unsigned int reg, unsigned int val)
  912. {
  913. return 0;
  914. }
  915. int dsi_mux_get_parent_14nm(void *context, unsigned int reg, unsigned int *val)
  916. {
  917. *val = 0;
  918. return 0;
  919. }