dsi_20nm_pll_util.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2014-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 <linux/clk/msm-clock-generic.h>
  11. #include "pll_drv.h"
  12. #include "dsi_pll.h"
  13. #define MMSS_DSI_PHY_PLL_SYS_CLK_CTRL 0x0000
  14. #define MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN 0x0004
  15. #define MMSS_DSI_PHY_PLL_CMN_MODE 0x0008
  16. #define MMSS_DSI_PHY_PLL_IE_TRIM 0x000C
  17. #define MMSS_DSI_PHY_PLL_IP_TRIM 0x0010
  18. #define MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL 0x0018
  19. #define MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL 0x001C
  20. #define MMSS_DSI_PHY_PLL_PLL_PHSEL_DC 0x0020
  21. #define MMSS_DSI_PHY_PLL_PLL_IP_SETI 0x0024
  22. #define MMSS_DSI_PHY_PLL_CORE_CLK_IN_SYNC_SEL 0x0028
  23. #define MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN 0x0030
  24. #define MMSS_DSI_PHY_PLL_PLL_CP_SETI 0x0034
  25. #define MMSS_DSI_PHY_PLL_PLL_IP_SETP 0x0038
  26. #define MMSS_DSI_PHY_PLL_PLL_CP_SETP 0x003C
  27. #define MMSS_DSI_PHY_PLL_ATB_SEL1 0x0040
  28. #define MMSS_DSI_PHY_PLL_ATB_SEL2 0x0044
  29. #define MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND 0x0048
  30. #define MMSS_DSI_PHY_PLL_RESETSM_CNTRL 0x004C
  31. #define MMSS_DSI_PHY_PLL_RESETSM_CNTRL2 0x0050
  32. #define MMSS_DSI_PHY_PLL_RESETSM_CNTRL3 0x0054
  33. #define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT1 0x0058
  34. #define MMSS_DSI_PHY_PLL_RESETSM_PLL_CAL_COUNT2 0x005C
  35. #define MMSS_DSI_PHY_PLL_DIV_REF1 0x0060
  36. #define MMSS_DSI_PHY_PLL_DIV_REF2 0x0064
  37. #define MMSS_DSI_PHY_PLL_KVCO_COUNT1 0x0068
  38. #define MMSS_DSI_PHY_PLL_KVCO_COUNT2 0x006C
  39. #define MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL 0x0070
  40. #define MMSS_DSI_PHY_PLL_KVCO_CODE 0x0074
  41. #define MMSS_DSI_PHY_PLL_VREF_CFG1 0x0078
  42. #define MMSS_DSI_PHY_PLL_VREF_CFG2 0x007C
  43. #define MMSS_DSI_PHY_PLL_VREF_CFG3 0x0080
  44. #define MMSS_DSI_PHY_PLL_VREF_CFG4 0x0084
  45. #define MMSS_DSI_PHY_PLL_VREF_CFG5 0x0088
  46. #define MMSS_DSI_PHY_PLL_VREF_CFG6 0x008C
  47. #define MMSS_DSI_PHY_PLL_PLLLOCK_CMP1 0x0090
  48. #define MMSS_DSI_PHY_PLL_PLLLOCK_CMP2 0x0094
  49. #define MMSS_DSI_PHY_PLL_PLLLOCK_CMP3 0x0098
  50. #define MMSS_DSI_PHY_PLL_BGTC 0x00A0
  51. #define MMSS_DSI_PHY_PLL_PLL_TEST_UPDN 0x00A4
  52. #define MMSS_DSI_PHY_PLL_PLL_VCO_TUNE 0x00A8
  53. #define MMSS_DSI_PHY_PLL_DEC_START1 0x00AC
  54. #define MMSS_DSI_PHY_PLL_PLL_AMP_OS 0x00B0
  55. #define MMSS_DSI_PHY_PLL_SSC_EN_CENTER 0x00B4
  56. #define MMSS_DSI_PHY_PLL_SSC_ADJ_PER1 0x00B8
  57. #define MMSS_DSI_PHY_PLL_SSC_ADJ_PER2 0x00BC
  58. #define MMSS_DSI_PHY_PLL_SSC_PER1 0x00C0
  59. #define MMSS_DSI_PHY_PLL_SSC_PER2 0x00C4
  60. #define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE1 0x00C8
  61. #define MMSS_DSI_PHY_PLL_SSC_STEP_SIZE2 0x00CC
  62. #define MMSS_DSI_PHY_PLL_RES_CODE_UP 0x00D0
  63. #define MMSS_DSI_PHY_PLL_RES_CODE_DN 0x00D4
  64. #define MMSS_DSI_PHY_PLL_RES_CODE_UP_OFFSET 0x00D8
  65. #define MMSS_DSI_PHY_PLL_RES_CODE_DN_OFFSET 0x00DC
  66. #define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG1 0x00E0
  67. #define MMSS_DSI_PHY_PLL_RES_CODE_START_SEG2 0x00E4
  68. #define MMSS_DSI_PHY_PLL_RES_CODE_CAL_CSR 0x00E8
  69. #define MMSS_DSI_PHY_PLL_RES_CODE 0x00EC
  70. #define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL 0x00F0
  71. #define MMSS_DSI_PHY_PLL_RES_TRIM_CONTROL2 0x00F4
  72. #define MMSS_DSI_PHY_PLL_RES_TRIM_EN_VCOCALDONE 0x00F8
  73. #define MMSS_DSI_PHY_PLL_FAUX_EN 0x00FC
  74. #define MMSS_DSI_PHY_PLL_DIV_FRAC_START1 0x0100
  75. #define MMSS_DSI_PHY_PLL_DIV_FRAC_START2 0x0104
  76. #define MMSS_DSI_PHY_PLL_DIV_FRAC_START3 0x0108
  77. #define MMSS_DSI_PHY_PLL_DEC_START2 0x010C
  78. #define MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN 0x0110
  79. #define MMSS_DSI_PHY_PLL_PLL_CRCTRL 0x0114
  80. #define MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL 0x013C
  81. #define MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL 0x0140
  82. #define MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER 0x0144
  83. #define MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER 0x0148
  84. #define MMSS_DSI_PHY_PLL_PLL_VCO_HIGH 0x014C
  85. #define MMSS_DSI_PHY_PLL_RESET_SM 0x0150
  86. #define MMSS_DSI_PHY_PLL_MUXVAL 0x0154
  87. #define MMSS_DSI_PHY_PLL_CORE_RES_CODE_DN 0x0158
  88. #define MMSS_DSI_PHY_PLL_CORE_RES_CODE_UP 0x015C
  89. #define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE 0x0160
  90. #define MMSS_DSI_PHY_PLL_CORE_VCO_TAIL 0x0164
  91. #define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0168
  92. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL0 0x014
  93. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL1 0x018
  94. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL2 0x01C
  95. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL3 0x020
  96. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL4 0x024
  97. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL5 0x028
  98. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL6 0x02C
  99. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL7 0x030
  100. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL8 0x034
  101. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL9 0x038
  102. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL10 0x03C
  103. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL11 0x040
  104. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL12 0x044
  105. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL13 0x048
  106. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL14 0x04C
  107. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL15 0x050
  108. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL16 0x054
  109. #define MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL17 0x058
  110. #define DSI_PLL_POLL_DELAY_US 1000
  111. #define DSI_PLL_POLL_TIMEOUT_US 15000
  112. int set_mdss_byte_mux_sel(struct mux_clk *clk, int sel)
  113. {
  114. return 0;
  115. }
  116. int get_mdss_byte_mux_sel(struct mux_clk *clk)
  117. {
  118. return 0;
  119. }
  120. int set_mdss_pixel_mux_sel(struct mux_clk *clk, int sel)
  121. {
  122. return 0;
  123. }
  124. int get_mdss_pixel_mux_sel(struct mux_clk *clk)
  125. {
  126. return 0;
  127. }
  128. static void pll_20nm_cache_trim_codes(struct mdss_pll_resources *dsi_pll_res)
  129. {
  130. int rc;
  131. if (dsi_pll_res->reg_upd)
  132. return;
  133. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  134. if (rc) {
  135. pr_err("Failed to enable mdss dsi pll resources\n");
  136. return;
  137. }
  138. dsi_pll_res->cache_pll_trim_codes[0] =
  139. MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  140. MMSS_DSI_PHY_PLL_CORE_KVCO_CODE);
  141. dsi_pll_res->cache_pll_trim_codes[1] =
  142. MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  143. MMSS_DSI_PHY_PLL_CORE_VCO_TUNE);
  144. pr_debug("core_kvco_code=0x%x core_vco_turn=0x%x\n",
  145. dsi_pll_res->cache_pll_trim_codes[0],
  146. dsi_pll_res->cache_pll_trim_codes[1]);
  147. mdss_pll_resource_enable(dsi_pll_res, false);
  148. dsi_pll_res->reg_upd = true;
  149. }
  150. static void pll_20nm_override_trim_codes(struct mdss_pll_resources *dsi_pll_res)
  151. {
  152. u32 reg_data;
  153. void __iomem *pll_base = dsi_pll_res->pll_base;
  154. /*
  155. * Override mux config for all cached trim codes from
  156. * saved config except for VCO Tune
  157. */
  158. reg_data = (dsi_pll_res->cache_pll_trim_codes[0] & 0x3f) | BIT(5);
  159. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_KVCO_CODE, reg_data);
  160. reg_data = (dsi_pll_res->cache_pll_trim_codes[1] & 0x7f) | BIT(7);
  161. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCO_TUNE, reg_data);
  162. }
  163. int set_bypass_lp_div_mux_sel(struct mux_clk *clk, int sel)
  164. {
  165. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  166. int reg_data;
  167. pr_debug("bypass_lp_div mux set to %s mode\n",
  168. sel ? "indirect" : "direct");
  169. pr_debug("POST_DIVIDER_CONTROL = 0x%x\n",
  170. MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  171. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL));
  172. reg_data = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  173. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
  174. reg_data |= BIT(7);
  175. MDSS_PLL_REG_W(dsi_pll_res->pll_base,
  176. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  177. reg_data | (sel << 5));
  178. pr_debug("POST_DIVIDER_CONTROL = 0x%x\n",
  179. MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  180. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL));
  181. return 0;
  182. }
  183. int set_shadow_bypass_lp_div_mux_sel(struct mux_clk *clk, int sel)
  184. {
  185. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  186. int reg_data, rem;
  187. if (!dsi_pll_res->resource_enable) {
  188. pr_err("PLL resources disabled. Dynamic fps invalid\n");
  189. return -EINVAL;
  190. }
  191. reg_data = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  192. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
  193. reg_data |= BIT(7);
  194. pr_debug("%d: reg_data = %x\n", __LINE__, reg_data);
  195. /* Repeat POST DIVIDER 2 times (4 writes)*/
  196. for (rem = 0; rem < 2; rem++)
  197. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  198. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL16 + (4 * rem),
  199. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  200. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  201. (reg_data | (sel << 5)), (reg_data | (sel << 5)));
  202. return 0;
  203. }
  204. int get_bypass_lp_div_mux_sel(struct mux_clk *clk)
  205. {
  206. int mux_mode, rc;
  207. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  208. if (is_gdsc_disabled(dsi_pll_res))
  209. return 0;
  210. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  211. if (rc) {
  212. pr_err("Failed to enable mdss dsi pll resources\n");
  213. return rc;
  214. }
  215. mux_mode = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  216. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL) & BIT(5);
  217. pr_debug("bypass_lp_div mux mode = %s\n",
  218. mux_mode ? "indirect" : "direct");
  219. mdss_pll_resource_enable(dsi_pll_res, false);
  220. return !!mux_mode;
  221. }
  222. int ndiv_set_div(struct div_clk *clk, int div)
  223. {
  224. int rc, reg_data;
  225. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  226. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  227. if (rc) {
  228. pr_err("Failed to enable mdss dsi pll resources\n");
  229. return rc;
  230. }
  231. reg_data = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  232. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL);
  233. MDSS_PLL_REG_W(dsi_pll_res->pll_base,
  234. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  235. reg_data | div);
  236. pr_debug("POST_DIVIDER_CONTROL = 0x%x\n",
  237. MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  238. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL));
  239. mdss_pll_resource_enable(dsi_pll_res, false);
  240. return rc;
  241. }
  242. int shadow_ndiv_set_div(struct div_clk *clk, int div)
  243. {
  244. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  245. if (!dsi_pll_res->resource_enable) {
  246. pr_err("PLL resources disabled. Dynamic fps invalid\n");
  247. return -EINVAL;
  248. }
  249. pr_debug("%d div=%i\n", __LINE__, div);
  250. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  251. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL14,
  252. MMSS_DSI_PHY_PLL_RESETSM_CNTRL3,
  253. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  254. 0x07, (0xB | div));
  255. return 0;
  256. }
  257. int ndiv_get_div(struct div_clk *clk)
  258. {
  259. int div = 0, rc;
  260. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  261. if (is_gdsc_disabled(dsi_pll_res))
  262. return 0;
  263. rc = mdss_pll_resource_enable(clk->priv, true);
  264. if (rc) {
  265. pr_err("Failed to enable mdss dsi pll resources\n");
  266. return rc;
  267. }
  268. div = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  269. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL) & 0x0F;
  270. mdss_pll_resource_enable(dsi_pll_res, false);
  271. return div;
  272. }
  273. int fixed_hr_oclk2_set_div(struct div_clk *clk, int div)
  274. {
  275. int rc;
  276. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  277. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  278. if (rc) {
  279. pr_err("Failed to enable mdss dsi pll resources\n");
  280. return rc;
  281. }
  282. MDSS_PLL_REG_W(dsi_pll_res->pll_base,
  283. MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER,
  284. (div - 1));
  285. mdss_pll_resource_enable(dsi_pll_res, false);
  286. return rc;
  287. }
  288. int shadow_fixed_hr_oclk2_set_div(struct div_clk *clk, int div)
  289. {
  290. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  291. if (!dsi_pll_res->resource_enable) {
  292. pr_err("PLL resources disabled. Dynamic fps invalid\n");
  293. return -EINVAL;
  294. }
  295. pr_debug("%d div = %d\n", __LINE__, div);
  296. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  297. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL5,
  298. MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER,
  299. MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER,
  300. (div - 1), (div - 1));
  301. return 0;
  302. }
  303. int fixed_hr_oclk2_get_div(struct div_clk *clk)
  304. {
  305. int div = 0, rc;
  306. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  307. if (is_gdsc_disabled(dsi_pll_res))
  308. return 0;
  309. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  310. if (rc) {
  311. pr_err("Failed to enable mdss dsi pll resources\n");
  312. return rc;
  313. }
  314. div = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  315. MMSS_DSI_PHY_PLL_HR_OCLK2_DIVIDER);
  316. mdss_pll_resource_enable(dsi_pll_res, false);
  317. return div + 1;
  318. }
  319. int hr_oclk3_set_div(struct div_clk *clk, int div)
  320. {
  321. int rc;
  322. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  323. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  324. if (rc) {
  325. pr_err("Failed to enable mdss dsi pll resources\n");
  326. return rc;
  327. }
  328. pr_debug("%d div = %d\n", __LINE__, div);
  329. MDSS_PLL_REG_W(dsi_pll_res->pll_base,
  330. MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER,
  331. (div - 1));
  332. pr_debug("%s: HR_OCLK3_DIVIDER = 0x%x\n", __func__,
  333. MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  334. MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER));
  335. mdss_pll_resource_enable(dsi_pll_res, false);
  336. return rc;
  337. }
  338. int shadow_hr_oclk3_set_div(struct div_clk *clk, int div)
  339. {
  340. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  341. if (!dsi_pll_res->resource_enable) {
  342. pr_err("PLL resources disabled. Dynamic fps invalid\n");
  343. return -EINVAL;
  344. }
  345. pr_debug("%d div = %d\n", __LINE__, div);
  346. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  347. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL6,
  348. MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER,
  349. MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER,
  350. (div - 1), (div - 1));
  351. return 0;
  352. }
  353. int hr_oclk3_get_div(struct div_clk *clk)
  354. {
  355. int div = 0, rc;
  356. struct mdss_pll_resources *dsi_pll_res = clk->priv;
  357. if (is_gdsc_disabled(dsi_pll_res))
  358. return 0;
  359. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  360. if (rc) {
  361. pr_err("Failed to enable mdss dsi pll resources\n");
  362. return rc;
  363. }
  364. div = MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  365. MMSS_DSI_PHY_PLL_HR_OCLK3_DIVIDER);
  366. mdss_pll_resource_enable(dsi_pll_res, false);
  367. return div + 1;
  368. }
  369. static bool pll_20nm_is_pll_locked(struct mdss_pll_resources *dsi_pll_res)
  370. {
  371. u32 status;
  372. bool pll_locked;
  373. /* poll for PLL ready status */
  374. if (readl_poll_timeout_atomic((dsi_pll_res->pll_base +
  375. MMSS_DSI_PHY_PLL_RESET_SM),
  376. status,
  377. ((status & BIT(5)) > 0),
  378. DSI_PLL_POLL_DELAY_US,
  379. DSI_PLL_POLL_TIMEOUT_US)) {
  380. pr_debug("DSI PLL status=%x failed to Lock\n", status);
  381. pll_locked = false;
  382. } else if (readl_poll_timeout_atomic((dsi_pll_res->pll_base +
  383. MMSS_DSI_PHY_PLL_RESET_SM),
  384. status,
  385. ((status & BIT(6)) > 0),
  386. DSI_PLL_POLL_DELAY_US,
  387. DSI_PLL_POLL_TIMEOUT_US)) {
  388. pr_debug("DSI PLL status=%x PLl not ready\n", status);
  389. pll_locked = false;
  390. } else {
  391. pll_locked = true;
  392. }
  393. return pll_locked;
  394. }
  395. void __dsi_pll_disable(void __iomem *pll_base)
  396. {
  397. if (!pll_base) {
  398. pr_err("Invalid pll base\n");
  399. return;
  400. }
  401. pr_debug("Disabling PHY PLL for PLL_BASE=%p\n", pll_base);
  402. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x02);
  403. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x06);
  404. }
  405. static void pll_20nm_config_powerdown(void __iomem *pll_base)
  406. {
  407. if (!pll_base) {
  408. pr_err("Invalid pll base.\n");
  409. return;
  410. }
  411. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SYS_CLK_CTRL, 0x00);
  412. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_CMN_MODE, 0x01);
  413. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x82);
  414. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN, 0x02);
  415. }
  416. static int dsi_pll_enable(struct clk *c)
  417. {
  418. int i, rc;
  419. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  420. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  421. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  422. if (rc) {
  423. pr_err("Failed to enable mdss dsi pll resources\n");
  424. return rc;
  425. }
  426. /* Try all enable sequences until one succeeds */
  427. for (i = 0; i < vco->pll_en_seq_cnt; i++) {
  428. rc = vco->pll_enable_seqs[i](dsi_pll_res);
  429. pr_debug("DSI PLL %s after sequence #%d\n",
  430. rc ? "unlocked" : "locked", i + 1);
  431. if (!rc)
  432. break;
  433. }
  434. /* Disable PLL1 to avoid current leakage while toggling MDSS GDSC */
  435. if (dsi_pll_res->pll_1_base)
  436. pll_20nm_config_powerdown(dsi_pll_res->pll_1_base);
  437. if (rc) {
  438. mdss_pll_resource_enable(dsi_pll_res, false);
  439. pr_err("DSI PLL failed to lock\n");
  440. }
  441. dsi_pll_res->pll_on = true;
  442. return rc;
  443. }
  444. static void dsi_pll_disable(struct clk *c)
  445. {
  446. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  447. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  448. if (!dsi_pll_res->pll_on &&
  449. mdss_pll_resource_enable(dsi_pll_res, true)) {
  450. pr_err("Failed to enable mdss dsi pll resources\n");
  451. return;
  452. }
  453. dsi_pll_res->handoff_resources = false;
  454. __dsi_pll_disable(dsi_pll_res->pll_base);
  455. /* Disable PLL1 to avoid current leakage while toggling MDSS GDSC */
  456. if (dsi_pll_res->pll_1_base)
  457. pll_20nm_config_powerdown(dsi_pll_res->pll_1_base);
  458. pll_20nm_config_powerdown(dsi_pll_res->pll_base);
  459. mdss_pll_resource_enable(dsi_pll_res, false);
  460. dsi_pll_res->pll_on = false;
  461. pr_debug("DSI PLL Disabled\n");
  462. }
  463. static void pll_20nm_config_common_block_1(void __iomem *pll_base)
  464. {
  465. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x82);
  466. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN, 0x2a);
  467. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_BIAS_EN_CLKBUFLR_EN, 0x2b);
  468. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x02);
  469. }
  470. static void pll_20nm_config_common_block_2(void __iomem *pll_base)
  471. {
  472. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SYS_CLK_CTRL, 0x40);
  473. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_IE_TRIM, 0x0F);
  474. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_IP_TRIM, 0x0F);
  475. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_PHSEL_CONTROL, 0x08);
  476. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_IPTAT_TRIM_VCCA_TX_SEL, 0x0E);
  477. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x08);
  478. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SYSCLK_EN_SEL_TXBAND, 0x4A);
  479. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_REF1, 0x00);
  480. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_REF2, 0x01);
  481. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CNTRL, 0x07);
  482. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_KVCO_CAL_CNTRL, 0x1f);
  483. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_KVCO_COUNT1, 0x8A);
  484. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_VREF_CFG3, 0x10);
  485. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_SSC_EN_CENTER, 0x00);
  486. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_FAUX_EN, 0x0C);
  487. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_RXTXEPCLK_EN, 0x0a);
  488. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_LOW_POWER_RO_CONTROL, 0x0f);
  489. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_CMN_MODE, 0x00);
  490. }
  491. static void pll_20nm_config_loop_bw(void __iomem *pll_base)
  492. {
  493. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_IP_SETI, 0x03);
  494. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CP_SETI, 0x3F);
  495. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_IP_SETP, 0x03);
  496. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CP_SETP, 0x1F);
  497. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_CRCTRL, 0x77);
  498. }
  499. static void pll_20nm_vco_rate_calc(struct mdss_pll_vco_calc *vco_calc,
  500. s64 vco_clk_rate, s64 ref_clk_rate)
  501. {
  502. s64 multiplier = (1 << 20);
  503. s64 duration = 1024, pll_comp_val;
  504. s64 dec_start_multiple, dec_start;
  505. s32 div_frac_start;
  506. s64 dec_start1, dec_start2;
  507. s32 div_frac_start1, div_frac_start2, div_frac_start3;
  508. s64 pll_plllock_cmp1, pll_plllock_cmp2, pll_plllock_cmp3;
  509. memset(vco_calc, 0, sizeof(*vco_calc));
  510. pr_debug("vco_clk_rate=%lld ref_clk_rate=%lld\n", vco_clk_rate,
  511. ref_clk_rate);
  512. dec_start_multiple = div_s64(vco_clk_rate * multiplier,
  513. 2 * ref_clk_rate);
  514. div_s64_rem(dec_start_multiple,
  515. multiplier, &div_frac_start);
  516. dec_start = div_s64(dec_start_multiple, multiplier);
  517. dec_start1 = (dec_start & 0x7f) | BIT(7);
  518. dec_start2 = ((dec_start & 0x80) >> 7) | BIT(1);
  519. div_frac_start1 = (div_frac_start & 0x7f) | BIT(7);
  520. div_frac_start2 = ((div_frac_start >> 7) & 0x7f) | BIT(7);
  521. div_frac_start3 = ((div_frac_start >> 14) & 0x3f) | BIT(6);
  522. pll_comp_val = (div_s64(dec_start_multiple * 2 * duration,
  523. 10 * multiplier)) - 1;
  524. pll_plllock_cmp1 = pll_comp_val & 0xff;
  525. pll_plllock_cmp2 = (pll_comp_val >> 8) & 0xff;
  526. pll_plllock_cmp3 = (pll_comp_val >> 16) & 0xff;
  527. pr_debug("dec_start_multiple = 0x%llx\n", dec_start_multiple);
  528. pr_debug("dec_start = 0x%llx, div_frac_start = 0x%x\n",
  529. dec_start, div_frac_start);
  530. pr_debug("dec_start1 = 0x%llx, dec_start2 = 0x%llx\n",
  531. dec_start1, dec_start2);
  532. pr_debug("div_frac_start1 = 0x%x, div_frac_start2 = 0x%x\n",
  533. div_frac_start1, div_frac_start2);
  534. pr_debug("div_frac_start3 = 0x%x\n", div_frac_start3);
  535. pr_debug("pll_comp_val = 0x%llx\n", pll_comp_val);
  536. pr_debug("pll_plllock_cmp1 = 0x%llx, pll_plllock_cmp2 =%llx\n",
  537. pll_plllock_cmp1, pll_plllock_cmp2);
  538. pr_debug("pll_plllock_cmp3 = 0x%llx\n", pll_plllock_cmp3);
  539. /* Assign to vco struct */
  540. vco_calc->div_frac_start1 = div_frac_start1;
  541. vco_calc->div_frac_start2 = div_frac_start2;
  542. vco_calc->div_frac_start3 = div_frac_start3;
  543. vco_calc->dec_start1 = dec_start1;
  544. vco_calc->dec_start2 = dec_start2;
  545. vco_calc->pll_plllock_cmp1 = pll_plllock_cmp1;
  546. vco_calc->pll_plllock_cmp2 = pll_plllock_cmp2;
  547. vco_calc->pll_plllock_cmp3 = pll_plllock_cmp3;
  548. }
  549. static void pll_20nm_config_vco_rate(void __iomem *pll_base,
  550. struct mdss_pll_vco_calc *vco_calc)
  551. {
  552. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_FRAC_START1,
  553. vco_calc->div_frac_start1);
  554. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_FRAC_START2,
  555. vco_calc->div_frac_start2);
  556. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DIV_FRAC_START3,
  557. vco_calc->div_frac_start3);
  558. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DEC_START1,
  559. vco_calc->dec_start1);
  560. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_DEC_START2,
  561. vco_calc->dec_start2);
  562. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP1,
  563. vco_calc->pll_plllock_cmp1);
  564. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP2,
  565. vco_calc->pll_plllock_cmp2);
  566. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP3,
  567. vco_calc->pll_plllock_cmp3);
  568. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN, 0x01);
  569. }
  570. int pll_20nm_vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate)
  571. {
  572. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  573. dsi_pll_res->vco_current_rate = rate;
  574. dsi_pll_res->vco_ref_clk_rate = vco->ref_clk_rate;
  575. return 0;
  576. }
  577. int shadow_pll_20nm_vco_set_rate(struct dsi_pll_vco_clk *vco,
  578. unsigned long rate)
  579. {
  580. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  581. struct mdss_pll_vco_calc vco_calc;
  582. s64 vco_clk_rate = rate;
  583. u32 rem;
  584. if (!dsi_pll_res->resource_enable) {
  585. pr_err("PLL resources disabled. Dynamic fps invalid\n");
  586. return -EINVAL;
  587. }
  588. pr_debug("req vco set rate: %lld\n", vco_clk_rate);
  589. pll_20nm_override_trim_codes(dsi_pll_res);
  590. /* div fraction, start and comp calculations */
  591. pll_20nm_vco_rate_calc(&vco_calc, vco_clk_rate,
  592. dsi_pll_res->vco_ref_clk_rate);
  593. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  594. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL0,
  595. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  596. MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN,
  597. 0xB1, 0);
  598. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  599. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL1,
  600. MMSS_DSI_PHY_PLL_PLLLOCK_CMP1,
  601. MMSS_DSI_PHY_PLL_PLLLOCK_CMP2,
  602. vco_calc.pll_plllock_cmp1, vco_calc.pll_plllock_cmp2);
  603. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  604. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL2,
  605. MMSS_DSI_PHY_PLL_PLLLOCK_CMP3,
  606. MMSS_DSI_PHY_PLL_DEC_START1,
  607. vco_calc.pll_plllock_cmp3, vco_calc.dec_start1);
  608. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  609. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL3,
  610. MMSS_DSI_PHY_PLL_DEC_START2,
  611. MMSS_DSI_PHY_PLL_DIV_FRAC_START1,
  612. vco_calc.dec_start2, vco_calc.div_frac_start1);
  613. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  614. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL4,
  615. MMSS_DSI_PHY_PLL_DIV_FRAC_START2,
  616. MMSS_DSI_PHY_PLL_DIV_FRAC_START3,
  617. vco_calc.div_frac_start2, vco_calc.div_frac_start3);
  618. /* Method 2 - Auto PLL calibration */
  619. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  620. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL7,
  621. MMSS_DSI_PHY_PLL_PLL_VCO_TUNE,
  622. MMSS_DSI_PHY_PLL_PLLLOCK_CMP_EN,
  623. 0, 0x0D);
  624. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  625. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL8,
  626. MMSS_DSI_PHY_PLL_POST_DIVIDER_CONTROL,
  627. MMSS_DSI_PHY_PLL_RESETSM_CNTRL3,
  628. 0xF0, 0x07);
  629. /*
  630. * RESETSM_CTRL3 has to be set for 12 times (6 reg writes),
  631. * Each register setting write 2 times, running in loop for 5
  632. * times (5 reg writes) and other two iterations are taken
  633. * care (one above and other in shadow_bypass
  634. */
  635. for (rem = 0; rem < 5; rem++) {
  636. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  637. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL9 + (4 * rem),
  638. MMSS_DSI_PHY_PLL_RESETSM_CNTRL3,
  639. MMSS_DSI_PHY_PLL_RESETSM_CNTRL3,
  640. 0x07, 0x07);
  641. }
  642. MDSS_DYN_PLL_REG_W(dsi_pll_res->dyn_pll_base,
  643. MMSS_DSI_DYNAMIC_REFRESH_PLL_CTRL15,
  644. MMSS_DSI_PHY_PLL_RESETSM_CNTRL3,
  645. MMSS_DSI_PHY_PLL_RESETSM_CNTRL3,
  646. 0x03, 0x03);
  647. /* memory barrier */
  648. wmb();
  649. return 0;
  650. }
  651. unsigned long pll_20nm_vco_get_rate(struct clk *c)
  652. {
  653. u64 vco_rate, multiplier = (1 << 20);
  654. s32 div_frac_start;
  655. u32 dec_start;
  656. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  657. u64 ref_clk = vco->ref_clk_rate;
  658. int rc;
  659. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  660. if (is_gdsc_disabled(dsi_pll_res))
  661. return 0;
  662. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  663. if (rc) {
  664. pr_err("Failed to enable mdss dsi pll resources\n");
  665. return rc;
  666. }
  667. dec_start = (MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  668. MMSS_DSI_PHY_PLL_DEC_START2) & BIT(0)) << 7;
  669. dec_start |= (MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  670. MMSS_DSI_PHY_PLL_DEC_START1) & 0x7f);
  671. pr_debug("dec_start = 0x%x\n", dec_start);
  672. div_frac_start = (MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  673. MMSS_DSI_PHY_PLL_DIV_FRAC_START3) & 0x3f) << 14;
  674. div_frac_start |= (MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  675. MMSS_DSI_PHY_PLL_DIV_FRAC_START2) & 0x7f) << 7;
  676. div_frac_start |= MDSS_PLL_REG_R(dsi_pll_res->pll_base,
  677. MMSS_DSI_PHY_PLL_DIV_FRAC_START1) & 0x7f;
  678. pr_debug("div_frac_start = 0x%x\n", div_frac_start);
  679. vco_rate = ref_clk * 2 * dec_start;
  680. vco_rate += ((ref_clk * 2 * div_frac_start) / multiplier);
  681. pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
  682. mdss_pll_resource_enable(dsi_pll_res, false);
  683. return (unsigned long)vco_rate;
  684. }
  685. long pll_20nm_vco_round_rate(struct clk *c, unsigned long rate)
  686. {
  687. unsigned long rrate = rate;
  688. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  689. if (rate < vco->min_rate)
  690. rrate = vco->min_rate;
  691. if (rate > vco->max_rate)
  692. rrate = vco->max_rate;
  693. return rrate;
  694. }
  695. enum handoff pll_20nm_vco_handoff(struct clk *c)
  696. {
  697. int rc;
  698. enum handoff ret = HANDOFF_DISABLED_CLK;
  699. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  700. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  701. if (is_gdsc_disabled(dsi_pll_res))
  702. return HANDOFF_DISABLED_CLK;
  703. rc = mdss_pll_resource_enable(dsi_pll_res, true);
  704. if (rc) {
  705. pr_err("Failed to enable mdss dsi pll resources\n");
  706. return ret;
  707. }
  708. if (pll_20nm_is_pll_locked(dsi_pll_res)) {
  709. dsi_pll_res->handoff_resources = true;
  710. dsi_pll_res->pll_on = true;
  711. c->rate = pll_20nm_vco_get_rate(c);
  712. ret = HANDOFF_ENABLED_CLK;
  713. dsi_pll_res->vco_locking_rate = c->rate;
  714. dsi_pll_res->is_init_locked = true;
  715. pll_20nm_cache_trim_codes(dsi_pll_res);
  716. pr_debug("handoff vco_locking_rate=%llu\n",
  717. dsi_pll_res->vco_locking_rate);
  718. } else {
  719. mdss_pll_resource_enable(dsi_pll_res, false);
  720. dsi_pll_res->vco_locking_rate = 0;
  721. dsi_pll_res->is_init_locked = false;
  722. }
  723. return ret;
  724. }
  725. int pll_20nm_vco_prepare(struct clk *c)
  726. {
  727. int rc = 0;
  728. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  729. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  730. if (!dsi_pll_res) {
  731. pr_err("Dsi pll resources are not available\n");
  732. return -EINVAL;
  733. }
  734. if ((dsi_pll_res->vco_cached_rate != 0)
  735. && (dsi_pll_res->vco_cached_rate == c->rate)) {
  736. rc = c->ops->set_rate(c, dsi_pll_res->vco_cached_rate);
  737. if (rc) {
  738. pr_err("vco_set_rate failed. rc=%d\n", rc);
  739. goto error;
  740. }
  741. }
  742. rc = dsi_pll_enable(c);
  743. error:
  744. return rc;
  745. }
  746. void pll_20nm_vco_unprepare(struct clk *c)
  747. {
  748. struct dsi_pll_vco_clk *vco = to_vco_clk(c);
  749. struct mdss_pll_resources *dsi_pll_res = vco->priv;
  750. if (!dsi_pll_res) {
  751. pr_err("Dsi pll resources are not available\n");
  752. return;
  753. }
  754. dsi_pll_res->vco_cached_rate = c->rate;
  755. dsi_pll_disable(c);
  756. }
  757. static void pll_20nm_config_resetsm(void __iomem *pll_base)
  758. {
  759. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0x24);
  760. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL2, 0x07);
  761. }
  762. static void pll_20nm_config_vco_start(void __iomem *pll_base)
  763. {
  764. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_VCOTAIL_EN, 0x03);
  765. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x02);
  766. udelay(10);
  767. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL3, 0x03);
  768. }
  769. static void pll_20nm_config_bypass_cal(void __iomem *pll_base)
  770. {
  771. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_RESETSM_CNTRL, 0xac);
  772. MDSS_PLL_REG_W(pll_base, MMSS_DSI_PHY_PLL_PLL_BKG_KVCO_CAL_EN, 0x28);
  773. }
  774. static int pll_20nm_vco_relock(struct mdss_pll_resources *dsi_pll_res)
  775. {
  776. int rc = 0;
  777. pll_20nm_override_trim_codes(dsi_pll_res);
  778. pll_20nm_config_bypass_cal(dsi_pll_res->pll_base);
  779. pll_20nm_config_vco_start(dsi_pll_res->pll_base);
  780. if (!pll_20nm_is_pll_locked(dsi_pll_res)) {
  781. pr_err("DSI PLL re-lock failed\n");
  782. rc = -EINVAL;
  783. }
  784. return rc;
  785. }
  786. static int pll_20nm_vco_init_lock(struct mdss_pll_resources *dsi_pll_res)
  787. {
  788. int rc = 0;
  789. pll_20nm_config_resetsm(dsi_pll_res->pll_base);
  790. pll_20nm_config_vco_start(dsi_pll_res->pll_base);
  791. if (!pll_20nm_is_pll_locked(dsi_pll_res)) {
  792. pr_err("DSI PLL init lock failed\n");
  793. rc = -EINVAL;
  794. goto init_lock_err;
  795. }
  796. pll_20nm_cache_trim_codes(dsi_pll_res);
  797. init_lock_err:
  798. return rc;
  799. }
  800. int pll_20nm_vco_enable_seq(struct mdss_pll_resources *dsi_pll_res)
  801. {
  802. int rc = 0;
  803. struct mdss_pll_vco_calc vco_calc;
  804. if (!dsi_pll_res) {
  805. pr_err("Invalid PLL resources\n");
  806. return -EINVAL;
  807. }
  808. pll_20nm_config_common_block_1(dsi_pll_res->pll_1_base);
  809. pll_20nm_config_common_block_1(dsi_pll_res->pll_base);
  810. pll_20nm_config_common_block_2(dsi_pll_res->pll_base);
  811. pll_20nm_config_loop_bw(dsi_pll_res->pll_base);
  812. pll_20nm_vco_rate_calc(&vco_calc, dsi_pll_res->vco_current_rate,
  813. dsi_pll_res->vco_ref_clk_rate);
  814. pll_20nm_config_vco_rate(dsi_pll_res->pll_base, &vco_calc);
  815. pr_debug("init lock=%d prev vco_rate=%llu, new vco_rate=%llu\n",
  816. dsi_pll_res->is_init_locked, dsi_pll_res->vco_locking_rate,
  817. dsi_pll_res->vco_current_rate);
  818. /*
  819. * Run auto-lock sequence if it is either bootup initial
  820. * locking or when the vco rate is changed. Otherwise, just
  821. * use stored codes and bypass caliberation.
  822. */
  823. if (!dsi_pll_res->is_init_locked || (dsi_pll_res->vco_locking_rate !=
  824. dsi_pll_res->vco_current_rate)) {
  825. rc = pll_20nm_vco_init_lock(dsi_pll_res);
  826. dsi_pll_res->is_init_locked = (rc) ? false : true;
  827. } else {
  828. rc = pll_20nm_vco_relock(dsi_pll_res);
  829. }
  830. dsi_pll_res->vco_locking_rate = (rc) ? 0 :
  831. dsi_pll_res->vco_current_rate;
  832. return rc;
  833. }