hdmi_pll_8998.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "%s: " fmt, __func__
  6. #include <linux/kernel.h>
  7. #include <linux/err.h>
  8. #include <linux/delay.h>
  9. #include <linux/iopoll.h>
  10. #include <linux/clk/msm-clk-provider.h>
  11. #include <linux/clk/msm-clk.h>
  12. #include <linux/clk/msm-clock-generic.h>
  13. #include <dt-bindings/clock/msm-clocks-8998.h>
  14. #include "pll_drv.h"
  15. #include "hdmi_pll.h"
  16. #define _W(x, y, z) MDSS_PLL_REG_W(x, y, z)
  17. #define _R(x, y) MDSS_PLL_REG_R(x, y)
  18. /* PLL REGISTERS */
  19. #define BIAS_EN_CLKBUFLR_EN (0x034)
  20. #define CLK_ENABLE1 (0x038)
  21. #define SYS_CLK_CTRL (0x03C)
  22. #define SYSCLK_BUF_ENABLE (0x040)
  23. #define PLL_IVCO (0x048)
  24. #define CP_CTRL_MODE0 (0x060)
  25. #define PLL_RCTRL_MODE0 (0x068)
  26. #define PLL_CCTRL_MODE0 (0x070)
  27. #define SYSCLK_EN_SEL (0x080)
  28. #define RESETSM_CNTRL (0x088)
  29. #define LOCK_CMP_EN (0x090)
  30. #define LOCK_CMP1_MODE0 (0x098)
  31. #define LOCK_CMP2_MODE0 (0x09C)
  32. #define LOCK_CMP3_MODE0 (0x0A0)
  33. #define DEC_START_MODE0 (0x0B0)
  34. #define DIV_FRAC_START1_MODE0 (0x0B8)
  35. #define DIV_FRAC_START2_MODE0 (0x0BC)
  36. #define DIV_FRAC_START3_MODE0 (0x0C0)
  37. #define INTEGLOOP_GAIN0_MODE0 (0x0D8)
  38. #define INTEGLOOP_GAIN1_MODE0 (0x0DC)
  39. #define VCO_TUNE_CTRL (0x0EC)
  40. #define VCO_TUNE_MAP (0x0F0)
  41. #define CLK_SELECT (0x138)
  42. #define HSCLK_SEL (0x13C)
  43. #define CORECLK_DIV_MODE0 (0x148)
  44. #define CORE_CLK_EN (0x154)
  45. #define C_READY_STATUS (0x158)
  46. #define SVS_MODE_CLK_SEL (0x164)
  47. /* Tx Channel PHY registers */
  48. #define PHY_TX_EMP_POST1_LVL(n) ((((n) * 0x200) + 0x400) + 0x000)
  49. #define PHY_TX_INTERFACE_SELECT_TX_BAND(n) ((((n) * 0x200) + 0x400) + 0x008)
  50. #define PHY_TX_CLKBUF_TERM_ENABLE(n) ((((n) * 0x200) + 0x400) + 0x00C)
  51. #define PHY_TX_DRV_LVL_RES_CODE_OFFSET(n) ((((n) * 0x200) + 0x400) + 0x014)
  52. #define PHY_TX_DRV_LVL(n) ((((n) * 0x200) + 0x400) + 0x018)
  53. #define PHY_TX_LANE_CONFIG(n) ((((n) * 0x200) + 0x400) + 0x01C)
  54. #define PHY_TX_PRE_DRIVER_1(n) ((((n) * 0x200) + 0x400) + 0x024)
  55. #define PHY_TX_PRE_DRIVER_2(n) ((((n) * 0x200) + 0x400) + 0x028)
  56. #define PHY_TX_LANE_MODE(n) ((((n) * 0x200) + 0x400) + 0x02C)
  57. /* HDMI PHY registers */
  58. #define PHY_CFG (0x00)
  59. #define PHY_PD_CTL (0x04)
  60. #define PHY_MODE (0x10)
  61. #define PHY_CLOCK (0x5C)
  62. #define PHY_CMN_CTRL (0x68)
  63. #define PHY_STATUS (0xB4)
  64. #define HDMI_BIT_CLK_TO_PIX_CLK_RATIO 10
  65. #define HDMI_MHZ_TO_HZ 1000000
  66. #define HDMI_HZ_TO_MHZ 1000000
  67. #define HDMI_REF_CLOCK_MHZ 19.2
  68. #define HDMI_REF_CLOCK_HZ (HDMI_REF_CLOCK_MHZ * 1000000)
  69. #define HDMI_VCO_MIN_RATE_HZ 25000000
  70. #define HDMI_VCO_MAX_RATE_HZ 600000000
  71. struct 8998_reg_cfg {
  72. u32 tx_band;
  73. u32 svs_mode_clk_sel;
  74. u32 hsclk_sel;
  75. u32 lock_cmp_en;
  76. u32 cctrl_mode0;
  77. u32 rctrl_mode0;
  78. u32 cpctrl_mode0;
  79. u32 dec_start_mode0;
  80. u32 div_frac_start1_mode0;
  81. u32 div_frac_start2_mode0;
  82. u32 div_frac_start3_mode0;
  83. u32 integloop_gain0_mode0;
  84. u32 integloop_gain1_mode0;
  85. u32 lock_cmp1_mode0;
  86. u32 lock_cmp2_mode0;
  87. u32 lock_cmp3_mode0;
  88. u32 ssc_per1;
  89. u32 ssc_per2;
  90. u32 ssc_step_size1;
  91. u32 ssc_step_size2;
  92. u32 core_clk_en;
  93. u32 coreclk_div_mode0;
  94. u32 phy_mode;
  95. u32 vco_freq;
  96. u32 hsclk_divsel;
  97. u32 vco_ratio;
  98. u32 ssc_en_center;
  99. u32 l0_tx_drv_lvl;
  100. u32 l0_tx_emp_post1_lvl;
  101. u32 l1_tx_drv_lvl;
  102. u32 l1_tx_emp_post1_lvl;
  103. u32 l2_tx_drv_lvl;
  104. u32 l2_tx_emp_post1_lvl;
  105. u32 l3_tx_drv_lvl;
  106. u32 l3_tx_emp_post1_lvl;
  107. u32 l0_pre_driver_1;
  108. u32 l0_pre_driver_2;
  109. u32 l1_pre_driver_1;
  110. u32 l1_pre_driver_2;
  111. u32 l2_pre_driver_1;
  112. u32 l2_pre_driver_2;
  113. u32 l3_pre_driver_1;
  114. u32 l3_pre_driver_2;
  115. bool debug;
  116. };
  117. static void hdmi_8998_get_div(struct 8998_reg_cfg * cfg, unsigned long pclk)
  118. {
  119. u32 const ratio_list[] = {1, 2, 3, 4, 5, 6,
  120. 9, 10, 12, 15, 25};
  121. u32 const band_list[] = {0, 1, 2, 3};
  122. u32 const sz_ratio = ARRAY_SIZE(ratio_list);
  123. u32 const sz_band = ARRAY_SIZE(band_list);
  124. u32 const min_freq = 8000, max_freq = 12000;
  125. u32 const cmp_cnt = 1024;
  126. u32 const th_min = 500, th_max = 1000;
  127. u64 bit_clk = pclk * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
  128. u32 half_rate_mode = 0;
  129. u32 freq_optimal, list_elements;
  130. int optimal_index;
  131. u32 i, j, k;
  132. u32 freq_list[sz_ratio * sz_band];
  133. u32 found_hsclk_divsel = 0, found_vco_ratio;
  134. u32 found_tx_band_sel, found_vco_freq;
  135. find_optimal_index:
  136. freq_optimal = max_freq;
  137. optimal_index = -1;
  138. list_elements = 0;
  139. for (i = 0; i < sz_ratio; i++) {
  140. for (j = 0; j < sz_band; j++) {
  141. u64 freq = (bit_clk / (1 << half_rate_mode));
  142. freq *= (ratio_list[i] * (1 << band_list[j]));
  143. do_div(freq, (u64) HDMI_MHZ_TO_HZ);
  144. freq_list[list_elements++] = freq;
  145. }
  146. }
  147. for (k = 0; k < ARRAY_SIZE(freq_list); k++) {
  148. u32 const clks_pll_div = 2, core_clk_div = 5;
  149. u32 const rng1 = 16, rng2 = 8;
  150. u32 core_clk, rvar1;
  151. u32 th1, th2;
  152. core_clk = (((freq_list[k] /
  153. ratio_list[k / sz_band]) /
  154. clks_pll_div) / core_clk_div);
  155. rvar1 = HDMI_REF_CLOCK_HZ / cmp_cnt;
  156. rvar1 *= rng1;
  157. rvar1 /= core_clk;
  158. th1 = rvar1;
  159. rvar1 = HDMI_REF_CLOCK_HZ / cmp_cnt;
  160. rvar1 *= rng2;
  161. rvar1 /= core_clk;
  162. th2 = rvar1;
  163. if (freq_list[k] >= min_freq &&
  164. freq_list[k] <= max_freq) {
  165. if ((th1 >= th_min && th1 <= th_max) ||
  166. (th2 >= th_min && th2 <= th_max)) {
  167. if (freq_list[k] <= freq_optimal) {
  168. freq_optimal = freq_list[k];
  169. optimal_index = k;
  170. }
  171. }
  172. }
  173. }
  174. if (optimal_index == -1) {
  175. if (!half_rate_mode) {
  176. half_rate_mode = 1;
  177. goto find_optimal_index;
  178. } else {
  179. /* set to default values */
  180. found_vco_freq = max_freq;
  181. found_hsclk_divsel = 0;
  182. found_vco_ratio = 2;
  183. found_tx_band_sel = 0;
  184. pr_err("Config error for pclk %ld\n", pclk);
  185. }
  186. } else {
  187. found_vco_ratio = ratio_list[optimal_index / sz_band];
  188. found_tx_band_sel = band_list[optimal_index % sz_band];
  189. found_vco_freq = freq_optimal;
  190. }
  191. switch (found_vco_ratio) {
  192. case 1:
  193. found_hsclk_divsel = 15;
  194. break;
  195. case 2:
  196. found_hsclk_divsel = 0;
  197. break;
  198. case 3:
  199. found_hsclk_divsel = 4;
  200. break;
  201. case 4:
  202. found_hsclk_divsel = 8;
  203. break;
  204. case 5:
  205. found_hsclk_divsel = 12;
  206. break;
  207. case 6:
  208. found_hsclk_divsel = 1;
  209. break;
  210. case 9:
  211. found_hsclk_divsel = 5;
  212. break;
  213. case 10:
  214. found_hsclk_divsel = 2;
  215. break;
  216. case 12:
  217. found_hsclk_divsel = 9;
  218. break;
  219. case 15:
  220. found_hsclk_divsel = 13;
  221. break;
  222. case 25:
  223. found_hsclk_divsel = 14;
  224. break;
  225. }
  226. pr_debug("found_vco_freq=%d\n", found_vco_freq);
  227. pr_debug("found_hsclk_divsel=%d\n", found_hsclk_divsel);
  228. pr_debug("found_vco_ratio=%d\n", found_vco_ratio);
  229. pr_debug("found_tx_band_sel=%d\n", found_tx_band_sel);
  230. pr_debug("half_rate_mode=%d\n", half_rate_mode);
  231. pr_debug("optimal_index=%d\n", optimal_index);
  232. cfg->vco_freq = found_vco_freq;
  233. cfg->hsclk_divsel = found_hsclk_divsel;
  234. cfg->vco_ratio = found_vco_ratio;
  235. cfg->tx_band = found_tx_band_sel;
  236. }
  237. static int hdmi_8998_config_phy(unsigned long rate,
  238. struct 8998_reg_cfg * cfg)
  239. {
  240. u64 const high_freq_bit_clk_threshold = 3400000000UL;
  241. u64 const dig_freq_bit_clk_threshold = 1500000000UL;
  242. u64 const mid_freq_bit_clk_threshold = 750000000;
  243. u64 fdata, tmds_clk;
  244. u64 pll_div = 4 * HDMI_REF_CLOCK_HZ;
  245. u64 bclk;
  246. u64 vco_freq_mhz;
  247. u64 hsclk_sel, dec_start, div_frac_start;
  248. u64 rem;
  249. u64 cpctrl, rctrl, cctrl;
  250. u64 integloop_gain;
  251. u32 digclk_divsel;
  252. u32 tmds_bclk_ratio;
  253. u64 cmp_rng, cmp_cnt = 1024, pll_cmp;
  254. bool gen_ssc = false;
  255. bclk = rate * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
  256. if (bclk > high_freq_bit_clk_threshold) {
  257. tmds_clk = rate / 4;
  258. tmds_bclk_ratio = 1;
  259. } else {
  260. tmds_clk = rate;
  261. tmds_bclk_ratio = 0;
  262. }
  263. hdmi_8998_get_div(cfg, rate);
  264. vco_freq_mhz = cfg->vco_freq * (u64) HDMI_HZ_TO_MHZ;
  265. fdata = cfg->vco_freq;
  266. do_div(fdata, cfg->vco_ratio);
  267. hsclk_sel = cfg->hsclk_divsel;
  268. dec_start = vco_freq_mhz;
  269. do_div(dec_start, pll_div);
  270. div_frac_start = vco_freq_mhz * (1 << 20);
  271. rem = do_div(div_frac_start, pll_div);
  272. div_frac_start -= (dec_start * (1 << 20));
  273. if (rem > (pll_div >> 1))
  274. div_frac_start++;
  275. if ((div_frac_start != 0) || gen_ssc) {
  276. cpctrl = 0x8;
  277. rctrl = 0x16;
  278. cctrl = 0x34;
  279. } else {
  280. cpctrl = 0x30;
  281. rctrl = 0x18;
  282. cctrl = 0x2;
  283. }
  284. digclk_divsel = (bclk > dig_freq_bit_clk_threshold) ? 0x1 : 0x2;
  285. integloop_gain = ((div_frac_start != 0) ||
  286. gen_ssc) ? 0x3F : 0xC4;
  287. integloop_gain <<= digclk_divsel;
  288. integloop_gain = (integloop_gain <= 2046 ? integloop_gain : 0x7FE);
  289. cmp_rng = gen_ssc ? 0x40 : 0x10;
  290. pll_cmp = cmp_cnt * fdata;
  291. rem = do_div(pll_cmp, (u64)(HDMI_REF_CLOCK_MHZ * 10));
  292. if (rem > ((u64)(HDMI_REF_CLOCK_MHZ * 10) >> 1))
  293. pll_cmp++;
  294. pll_cmp = pll_cmp - 1;
  295. pr_debug("VCO_FREQ = %u\n", cfg->vco_freq);
  296. pr_debug("FDATA = %llu\n", fdata);
  297. pr_debug("DEC_START = %llu\n", dec_start);
  298. pr_debug("DIV_FRAC_START = %llu\n", div_frac_start);
  299. pr_debug("CPCTRL = %llu\n", cpctrl);
  300. pr_debug("RCTRL = %llu\n", rctrl);
  301. pr_debug("CCTRL = %llu\n", cctrl);
  302. pr_debug("DIGCLK_DIVSEL = %u\n", digclk_divsel);
  303. pr_debug("INTEGLOOP_GAIN = %llu\n", integloop_gain);
  304. pr_debug("CMP_RNG = %llu\n", cmp_rng);
  305. pr_debug("PLL_CMP = %llu\n", pll_cmp);
  306. cfg->svs_mode_clk_sel = (digclk_divsel & 0xFF);
  307. cfg->hsclk_sel = (0x20 | hsclk_sel);
  308. cfg->lock_cmp_en = (gen_ssc ? 0x4 : 0x0);
  309. cfg->cctrl_mode0 = (cctrl & 0xFF);
  310. cfg->rctrl_mode0 = (rctrl & 0xFF);
  311. cfg->cpctrl_mode0 = (cpctrl & 0xFF);
  312. cfg->dec_start_mode0 = (dec_start & 0xFF);
  313. cfg->div_frac_start1_mode0 = (div_frac_start & 0xFF);
  314. cfg->div_frac_start2_mode0 = ((div_frac_start & 0xFF00) >> 8);
  315. cfg->div_frac_start3_mode0 = ((div_frac_start & 0xF0000) >> 16);
  316. cfg->integloop_gain0_mode0 = (integloop_gain & 0xFF);
  317. cfg->integloop_gain1_mode0 = (integloop_gain & 0xF00) >> 8;
  318. cfg->lock_cmp1_mode0 = (pll_cmp & 0xFF);
  319. cfg->lock_cmp2_mode0 = ((pll_cmp & 0xFF00) >> 8);
  320. cfg->lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
  321. cfg->ssc_per1 = 0;
  322. cfg->ssc_per2 = 0;
  323. cfg->ssc_step_size1 = 0;
  324. cfg->ssc_step_size2 = 0;
  325. cfg->core_clk_en = 0x2C;
  326. cfg->coreclk_div_mode0 = 0x5;
  327. cfg->phy_mode = (tmds_bclk_ratio ? 0x5 : 0x4);
  328. cfg->ssc_en_center = 0x0;
  329. if (bclk > high_freq_bit_clk_threshold) {
  330. cfg->l0_tx_drv_lvl = 0xA;
  331. cfg->l0_tx_emp_post1_lvl = 0x3;
  332. cfg->l1_tx_drv_lvl = 0xA;
  333. cfg->l1_tx_emp_post1_lvl = 0x3;
  334. cfg->l2_tx_drv_lvl = 0xA;
  335. cfg->l2_tx_emp_post1_lvl = 0x3;
  336. cfg->l3_tx_drv_lvl = 0x8;
  337. cfg->l3_tx_emp_post1_lvl = 0x3;
  338. cfg->l0_pre_driver_1 = 0x0;
  339. cfg->l0_pre_driver_2 = 0x1C;
  340. cfg->l1_pre_driver_1 = 0x0;
  341. cfg->l1_pre_driver_2 = 0x1C;
  342. cfg->l2_pre_driver_1 = 0x0;
  343. cfg->l2_pre_driver_2 = 0x1C;
  344. cfg->l3_pre_driver_1 = 0x0;
  345. cfg->l3_pre_driver_2 = 0x0;
  346. } else if (bclk > dig_freq_bit_clk_threshold) {
  347. cfg->l0_tx_drv_lvl = 0x9;
  348. cfg->l0_tx_emp_post1_lvl = 0x3;
  349. cfg->l1_tx_drv_lvl = 0x9;
  350. cfg->l1_tx_emp_post1_lvl = 0x3;
  351. cfg->l2_tx_drv_lvl = 0x9;
  352. cfg->l2_tx_emp_post1_lvl = 0x3;
  353. cfg->l3_tx_drv_lvl = 0x8;
  354. cfg->l3_tx_emp_post1_lvl = 0x3;
  355. cfg->l0_pre_driver_1 = 0x0;
  356. cfg->l0_pre_driver_2 = 0x16;
  357. cfg->l1_pre_driver_1 = 0x0;
  358. cfg->l1_pre_driver_2 = 0x16;
  359. cfg->l2_pre_driver_1 = 0x0;
  360. cfg->l2_pre_driver_2 = 0x16;
  361. cfg->l3_pre_driver_1 = 0x0;
  362. cfg->l3_pre_driver_2 = 0x0;
  363. } else if (bclk > mid_freq_bit_clk_threshold) {
  364. cfg->l0_tx_drv_lvl = 0x9;
  365. cfg->l0_tx_emp_post1_lvl = 0x3;
  366. cfg->l1_tx_drv_lvl = 0x9;
  367. cfg->l1_tx_emp_post1_lvl = 0x3;
  368. cfg->l2_tx_drv_lvl = 0x9;
  369. cfg->l2_tx_emp_post1_lvl = 0x3;
  370. cfg->l3_tx_drv_lvl = 0x8;
  371. cfg->l3_tx_emp_post1_lvl = 0x3;
  372. cfg->l0_pre_driver_1 = 0x0;
  373. cfg->l0_pre_driver_2 = 0x0E;
  374. cfg->l1_pre_driver_1 = 0x0;
  375. cfg->l1_pre_driver_2 = 0x0E;
  376. cfg->l2_pre_driver_1 = 0x0;
  377. cfg->l2_pre_driver_2 = 0x0E;
  378. cfg->l3_pre_driver_1 = 0x0;
  379. cfg->l3_pre_driver_2 = 0x0;
  380. } else {
  381. cfg->l0_tx_drv_lvl = 0x0;
  382. cfg->l0_tx_emp_post1_lvl = 0x0;
  383. cfg->l1_tx_drv_lvl = 0x0;
  384. cfg->l1_tx_emp_post1_lvl = 0x0;
  385. cfg->l2_tx_drv_lvl = 0x0;
  386. cfg->l2_tx_emp_post1_lvl = 0x0;
  387. cfg->l3_tx_drv_lvl = 0x0;
  388. cfg->l3_tx_emp_post1_lvl = 0x0;
  389. cfg->l0_pre_driver_1 = 0x0;
  390. cfg->l0_pre_driver_2 = 0x01;
  391. cfg->l1_pre_driver_1 = 0x0;
  392. cfg->l1_pre_driver_2 = 0x01;
  393. cfg->l2_pre_driver_1 = 0x0;
  394. cfg->l2_pre_driver_2 = 0x01;
  395. cfg->l3_pre_driver_1 = 0x0;
  396. cfg->l3_pre_driver_2 = 0x0;
  397. }
  398. return 0;
  399. }
  400. static int hdmi_8998_pll_set_clk_rate(struct clk *c, unsigned long rate)
  401. {
  402. int rc = 0;
  403. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  404. struct mdss_pll_resources *io = vco->priv;
  405. struct 8998_reg_cfg cfg = {0};
  406. void __iomem *phy = io->phy_base, *pll = io->pll_base;
  407. rc = hdmi_8998_config_phy(rate, &cfg);
  408. if (rc) {
  409. pr_err("rate calculation failed\n, rc=%d\n", rc);
  410. return rc;
  411. }
  412. _W(phy, PHY_PD_CTL, 0x0);
  413. udelay(500);
  414. _W(phy, PHY_PD_CTL, 0x1);
  415. _W(pll, RESETSM_CNTRL, 0x20);
  416. _W(phy, PHY_CMN_CTRL, 0x6);
  417. _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(0), cfg.tx_band);
  418. _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(1), cfg.tx_band);
  419. _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(2), cfg.tx_band);
  420. _W(pll, PHY_TX_INTERFACE_SELECT_TX_BAND(3), cfg.tx_band);
  421. _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(0), 0x1);
  422. _W(pll, PHY_TX_LANE_MODE(0), 0x20);
  423. _W(pll, PHY_TX_LANE_MODE(1), 0x20);
  424. _W(pll, PHY_TX_LANE_MODE(2), 0x20);
  425. _W(pll, PHY_TX_LANE_MODE(3), 0x20);
  426. _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(1), 0x1);
  427. _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(2), 0x1);
  428. _W(pll, PHY_TX_CLKBUF_TERM_ENABLE(3), 0x1);
  429. _W(pll, SYSCLK_BUF_ENABLE, 0x2);
  430. _W(pll, BIAS_EN_CLKBUFLR_EN, 0xB);
  431. _W(pll, SYSCLK_EN_SEL, 0x37);
  432. _W(pll, SYS_CLK_CTRL, 0x2);
  433. _W(pll, CLK_ENABLE1, 0xE);
  434. _W(pll, PLL_IVCO, 0xF);
  435. _W(pll, VCO_TUNE_CTRL, 0x0);
  436. _W(pll, SVS_MODE_CLK_SEL, cfg.svs_mode_clk_sel);
  437. _W(pll, CLK_SELECT, 0x30);
  438. _W(pll, HSCLK_SEL, cfg.hsclk_sel);
  439. _W(pll, LOCK_CMP_EN, cfg.lock_cmp_en);
  440. _W(pll, PLL_CCTRL_MODE0, cfg.cctrl_mode0);
  441. _W(pll, PLL_RCTRL_MODE0, cfg.rctrl_mode0);
  442. _W(pll, CP_CTRL_MODE0, cfg.cpctrl_mode0);
  443. _W(pll, DEC_START_MODE0, cfg.dec_start_mode0);
  444. _W(pll, DIV_FRAC_START1_MODE0, cfg.div_frac_start1_mode0);
  445. _W(pll, DIV_FRAC_START2_MODE0, cfg.div_frac_start2_mode0);
  446. _W(pll, DIV_FRAC_START3_MODE0, cfg.div_frac_start3_mode0);
  447. _W(pll, INTEGLOOP_GAIN0_MODE0, cfg.integloop_gain0_mode0);
  448. _W(pll, INTEGLOOP_GAIN1_MODE0, cfg.integloop_gain1_mode0);
  449. _W(pll, LOCK_CMP1_MODE0, cfg.lock_cmp1_mode0);
  450. _W(pll, LOCK_CMP2_MODE0, cfg.lock_cmp2_mode0);
  451. _W(pll, LOCK_CMP3_MODE0, cfg.lock_cmp3_mode0);
  452. _W(pll, VCO_TUNE_MAP, 0x0);
  453. _W(pll, CORE_CLK_EN, cfg.core_clk_en);
  454. _W(pll, CORECLK_DIV_MODE0, cfg.coreclk_div_mode0);
  455. _W(pll, PHY_TX_DRV_LVL(0), cfg.l0_tx_drv_lvl);
  456. _W(pll, PHY_TX_DRV_LVL(1), cfg.l1_tx_drv_lvl);
  457. _W(pll, PHY_TX_DRV_LVL(2), cfg.l2_tx_drv_lvl);
  458. _W(pll, PHY_TX_DRV_LVL(3), cfg.l3_tx_drv_lvl);
  459. _W(pll, PHY_TX_EMP_POST1_LVL(0), cfg.l0_tx_emp_post1_lvl);
  460. _W(pll, PHY_TX_EMP_POST1_LVL(1), cfg.l1_tx_emp_post1_lvl);
  461. _W(pll, PHY_TX_EMP_POST1_LVL(2), cfg.l2_tx_emp_post1_lvl);
  462. _W(pll, PHY_TX_EMP_POST1_LVL(3), cfg.l3_tx_emp_post1_lvl);
  463. _W(pll, PHY_TX_PRE_DRIVER_1(0), cfg.l0_pre_driver_1);
  464. _W(pll, PHY_TX_PRE_DRIVER_1(1), cfg.l1_pre_driver_1);
  465. _W(pll, PHY_TX_PRE_DRIVER_1(2), cfg.l2_pre_driver_1);
  466. _W(pll, PHY_TX_PRE_DRIVER_1(3), cfg.l3_pre_driver_1);
  467. _W(pll, PHY_TX_PRE_DRIVER_2(0), cfg.l0_pre_driver_2);
  468. _W(pll, PHY_TX_PRE_DRIVER_2(1), cfg.l1_pre_driver_2);
  469. _W(pll, PHY_TX_PRE_DRIVER_2(2), cfg.l2_pre_driver_2);
  470. _W(pll, PHY_TX_PRE_DRIVER_2(3), cfg.l3_pre_driver_2);
  471. _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(0), 0x0);
  472. _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(1), 0x0);
  473. _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(2), 0x0);
  474. _W(pll, PHY_TX_DRV_LVL_RES_CODE_OFFSET(3), 0x0);
  475. _W(phy, PHY_MODE, cfg.phy_mode);
  476. _W(pll, PHY_TX_LANE_CONFIG(0), 0x10);
  477. _W(pll, PHY_TX_LANE_CONFIG(1), 0x10);
  478. _W(pll, PHY_TX_LANE_CONFIG(2), 0x10);
  479. _W(pll, PHY_TX_LANE_CONFIG(3), 0x10);
  480. /* Ensure all registers are flushed to hardware */
  481. wmb();
  482. return 0;
  483. }
  484. static int hdmi_8998_pll_lock_status(struct mdss_pll_resources *io)
  485. {
  486. u32 const delay_us = 100;
  487. u32 const timeout_us = 5000;
  488. u32 status;
  489. int rc = 0;
  490. void __iomem *pll = io->pll_base;
  491. rc = mdss_pll_resource_enable(io, true);
  492. if (rc) {
  493. pr_err("pll resource can't be enabled\n");
  494. return rc;
  495. }
  496. rc = readl_poll_timeout_atomic(pll + C_READY_STATUS,
  497. status,
  498. ((status & BIT(0)) > 0),
  499. delay_us,
  500. timeout_us);
  501. if (rc)
  502. pr_err("HDMI PLL(%d) lock failed, status=0x%08x\n",
  503. io->index, status);
  504. else
  505. pr_debug("HDMI PLL(%d) lock passed, status=0x%08x\n",
  506. io->index, status);
  507. mdss_pll_resource_enable(io, false);
  508. return rc;
  509. }
  510. static int hdmi_8998_phy_ready_status(struct mdss_pll_resources *io)
  511. {
  512. u32 const delay_us = 100;
  513. u32 const timeout_us = 5000;
  514. u32 status;
  515. int rc = 0;
  516. void __iomem *phy = io->phy_base;
  517. rc = mdss_pll_resource_enable(io, true);
  518. if (rc) {
  519. pr_err("pll resource can't be enabled\n");
  520. return rc;
  521. }
  522. rc = readl_poll_timeout_atomic(phy + PHY_STATUS,
  523. status,
  524. ((status & BIT(0)) > 0),
  525. delay_us,
  526. timeout_us);
  527. if (rc)
  528. pr_err("HDMI PHY(%d) not ready, status=0x%08x\n",
  529. io->index, status);
  530. else
  531. pr_debug("HDMI PHY(%d) ready, status=0x%08x\n",
  532. io->index, status);
  533. mdss_pll_resource_enable(io, false);
  534. return rc;
  535. }
  536. static int hdmi_8998_vco_set_rate(struct clk *c, unsigned long rate)
  537. {
  538. int rc = 0;
  539. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  540. struct mdss_pll_resources *io = vco->priv;
  541. rc = mdss_pll_resource_enable(io, true);
  542. if (rc) {
  543. pr_err("pll resource enable failed, rc=%d\n", rc);
  544. return rc;
  545. }
  546. if (io->pll_on)
  547. goto error;
  548. rc = hdmi_8998_pll_set_clk_rate(c, rate);
  549. if (rc) {
  550. pr_err("failed to set clk rate, rc=%d\n", rc);
  551. goto error;
  552. }
  553. vco->rate = rate;
  554. vco->rate_set = true;
  555. error:
  556. (void)mdss_pll_resource_enable(io, false);
  557. return rc;
  558. }
  559. static long hdmi_8998_vco_round_rate(struct clk *c, unsigned long rate)
  560. {
  561. unsigned long rrate = rate;
  562. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  563. if (rate < vco->min_rate)
  564. rrate = vco->min_rate;
  565. if (rate > vco->max_rate)
  566. rrate = vco->max_rate;
  567. return rrate;
  568. }
  569. static int hdmi_8998_pll_enable(struct clk *c)
  570. {
  571. int rc = 0;
  572. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  573. struct mdss_pll_resources *io = vco->priv;
  574. void __iomem *phy = io->phy_base, *pll = io->pll_base;
  575. _W(phy, PHY_CFG, 0x1);
  576. udelay(100);
  577. _W(phy, PHY_CFG, 0x59);
  578. udelay(100);
  579. _W(phy, PHY_CLOCK, 0x6);
  580. /* Ensure all registers are flushed to hardware */
  581. wmb();
  582. rc = hdmi_8998_pll_lock_status(io);
  583. if (rc) {
  584. pr_err("PLL not locked, rc=%d\n", rc);
  585. return rc;
  586. }
  587. _W(pll, PHY_TX_LANE_CONFIG(0), 0x1F);
  588. _W(pll, PHY_TX_LANE_CONFIG(1), 0x1F);
  589. _W(pll, PHY_TX_LANE_CONFIG(2), 0x1F);
  590. _W(pll, PHY_TX_LANE_CONFIG(3), 0x1F);
  591. /* Ensure all registers are flushed to hardware */
  592. wmb();
  593. rc = hdmi_8998_phy_ready_status(io);
  594. if (rc) {
  595. pr_err("PHY NOT READY, rc=%d\n", rc);
  596. return rc;
  597. }
  598. _W(phy, PHY_CFG, 0x58);
  599. udelay(1);
  600. _W(phy, PHY_CFG, 0x59);
  601. /* Ensure all registers are flushed to hardware */
  602. wmb();
  603. io->pll_on = true;
  604. return rc;
  605. }
  606. static int hdmi_8998_vco_prepare(struct clk *c)
  607. {
  608. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  609. struct mdss_pll_resources *io = vco->priv;
  610. int rc = 0;
  611. if (!io) {
  612. pr_err("hdmi pll resources are not available\n");
  613. return -EINVAL;
  614. }
  615. rc = mdss_pll_resource_enable(io, true);
  616. if (rc) {
  617. pr_err("pll resource enable failed, rc=%d\n", rc);
  618. return rc;
  619. }
  620. if (!vco->rate_set && vco->rate) {
  621. rc = hdmi_8998_pll_set_clk_rate(c, vco->rate);
  622. if (rc) {
  623. pr_err("set rate failed, rc=%d\n", rc);
  624. goto error;
  625. }
  626. }
  627. rc = hdmi_8998_pll_enable(c);
  628. if (rc)
  629. pr_err("pll enabled failed, rc=%d\n", rc);
  630. error:
  631. if (rc)
  632. mdss_pll_resource_enable(io, false);
  633. return rc;
  634. }
  635. static void hdmi_8998_pll_disable(struct hdmi_pll_vco_clk *vco)
  636. {
  637. struct mdss_pll_resources *io = vco->priv;
  638. void __iomem *phy = io->phy_base;
  639. if (!io->pll_on)
  640. return;
  641. _W(phy, PHY_PD_CTL, 0x0);
  642. /* Ensure all registers are flushed to hardware */
  643. wmb();
  644. vco->rate_set = false;
  645. io->handoff_resources = false;
  646. io->pll_on = false;
  647. }
  648. static void hdmi_8998_vco_unprepare(struct clk *c)
  649. {
  650. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  651. struct mdss_pll_resources *io = vco->priv;
  652. if (!io) {
  653. pr_err("HDMI pll resources not available\n");
  654. return;
  655. }
  656. hdmi_8998_pll_disable(vco);
  657. mdss_pll_resource_enable(io, false);
  658. }
  659. static enum handoff hdmi_8998_vco_handoff(struct clk *c)
  660. {
  661. enum handoff ret = HANDOFF_DISABLED_CLK;
  662. struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
  663. struct mdss_pll_resources *io = vco->priv;
  664. if (mdss_pll_resource_enable(io, true)) {
  665. pr_err("pll resource can't be enabled\n");
  666. return ret;
  667. }
  668. io->handoff_resources = true;
  669. if (_R(io->pll_base, C_READY_STATUS) & BIT(0) &&
  670. _R(io->phy_base, PHY_STATUS) & BIT(0)) {
  671. io->pll_on = true;
  672. /* TODO: calculate rate based on the phy/pll register values. */
  673. ret = HANDOFF_ENABLED_CLK;
  674. } else {
  675. io->handoff_resources = false;
  676. mdss_pll_resource_enable(io, false);
  677. pr_debug("%s: PHY/PLL not ready\n", __func__);
  678. }
  679. pr_debug("done, ret=%d\n", ret);
  680. return ret;
  681. }
  682. static const struct clk_ops hdmi_8998_vco_clk_ops = {
  683. .set_rate = hdmi_8998_vco_set_rate,
  684. .round_rate = hdmi_8998_vco_round_rate,
  685. .prepare = hdmi_8998_vco_prepare,
  686. .unprepare = hdmi_8998_vco_unprepare,
  687. .handoff = hdmi_8998_vco_handoff,
  688. };
  689. static struct hdmi_pll_vco_clk hdmi_vco_clk = {
  690. .min_rate = HDMI_VCO_MIN_RATE_HZ,
  691. .max_rate = HDMI_VCO_MAX_RATE_HZ,
  692. .c = {
  693. .dbg_name = "hdmi_8998_vco_clk",
  694. .ops = &hdmi_8998_vco_clk_ops,
  695. CLK_INIT(hdmi_vco_clk.c),
  696. },
  697. };
  698. static struct clk_lookup hdmipllcc_8998[] = {
  699. CLK_LIST(hdmi_vco_clk),
  700. };
  701. int hdmi_8998_pll_clock_register(struct platform_device *pdev,
  702. struct mdss_pll_resources *pll_res)
  703. {
  704. int rc = 0;
  705. hdmi_vco_clk.priv = pll_res;
  706. rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8998,
  707. ARRAY_SIZE(hdmipllcc_8998));
  708. if (rc) {
  709. pr_err("clock register failed, rc=%d\n", rc);
  710. return rc;
  711. }
  712. return rc;
  713. }