1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2016, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2024 Freebox SAS 5 */ 6 7 #include <linux/clk-provider.h> 8 #include <linux/delay.h> 9 10 #include "hdmi.h" 11 12 #define HDMI_VCO_MAX_FREQ 12000000000UL 13 #define HDMI_VCO_MIN_FREQ 8000000000UL 14 15 #define HDMI_PCLK_MAX_FREQ 600000000 16 #define HDMI_PCLK_MIN_FREQ 25000000 17 18 #define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL 19 #define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL 20 #define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL 21 #define HDMI_CORECLK_DIV 5 22 #define HDMI_DEFAULT_REF_CLOCK 19200000 23 #define HDMI_PLL_CMP_CNT 1024 24 25 #define HDMI_PLL_POLL_MAX_READS 100 26 #define HDMI_PLL_POLL_TIMEOUT_US 150 27 28 #define HDMI_NUM_TX_CHANNEL 4 29 30 struct hdmi_pll_8998 { 31 struct platform_device *pdev; 32 struct clk_hw clk_hw; 33 unsigned long rate; 34 35 /* pll mmio base */ 36 void __iomem *mmio_qserdes_com; 37 /* tx channel base */ 38 void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL]; 39 }; 40 41 #define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8998, clk_hw) 42 43 struct hdmi_8998_phy_pll_reg_cfg { 44 u32 com_svs_mode_clk_sel; 45 u32 com_hsclk_sel; 46 u32 com_pll_cctrl_mode0; 47 u32 com_pll_rctrl_mode0; 48 u32 com_cp_ctrl_mode0; 49 u32 com_dec_start_mode0; 50 u32 com_div_frac_start1_mode0; 51 u32 com_div_frac_start2_mode0; 52 u32 com_div_frac_start3_mode0; 53 u32 com_integloop_gain0_mode0; 54 u32 com_integloop_gain1_mode0; 55 u32 com_lock_cmp_en; 56 u32 com_lock_cmp1_mode0; 57 u32 com_lock_cmp2_mode0; 58 u32 com_lock_cmp3_mode0; 59 u32 com_core_clk_en; 60 u32 com_coreclk_div_mode0; 61 62 u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL]; 63 u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL]; 64 u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL]; 65 u32 tx_lx_pre_driver_1[HDMI_NUM_TX_CHANNEL]; 66 u32 tx_lx_pre_driver_2[HDMI_NUM_TX_CHANNEL]; 67 u32 tx_lx_res_code_offset[HDMI_NUM_TX_CHANNEL]; 68 69 u32 phy_mode; 70 }; 71 72 struct hdmi_8998_post_divider { 73 u64 vco_freq; 74 int hsclk_divsel; 75 int vco_ratio; 76 int tx_band_sel; 77 int half_rate_mode; 78 }; 79 80 static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8998 *pll) 81 { 82 return platform_get_drvdata(pll->pdev); 83 } 84 85 static inline void hdmi_pll_write(struct hdmi_pll_8998 *pll, int offset, 86 u32 data) 87 { 88 writel(data, pll->mmio_qserdes_com + offset); 89 } 90 91 static inline u32 hdmi_pll_read(struct hdmi_pll_8998 *pll, int offset) 92 { 93 return readl(pll->mmio_qserdes_com + offset); 94 } 95 96 static inline void hdmi_tx_chan_write(struct hdmi_pll_8998 *pll, int channel, 97 int offset, int data) 98 { 99 writel(data, pll->mmio_qserdes_tx[channel] + offset); 100 } 101 102 static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk, 103 bool gen_ssc) 104 { 105 if ((frac_start != 0) || gen_ssc) 106 return 0x8; 107 108 return 0x30; 109 } 110 111 static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc) 112 { 113 if ((frac_start != 0) || gen_ssc) 114 return 0x16; 115 116 return 0x18; 117 } 118 119 static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc) 120 { 121 if ((frac_start != 0) || gen_ssc) 122 return 0x34; 123 124 return 0x2; 125 } 126 127 static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk, 128 bool gen_ssc) 129 { 130 int digclk_divsel = bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2; 131 u64 base; 132 133 if ((frac_start != 0) || gen_ssc) 134 base = 0x3F; 135 else 136 base = 0xC4; 137 138 base <<= (digclk_divsel == 2 ? 1 : 0); 139 140 return (base <= 2046 ? base : 2046); 141 } 142 143 static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) 144 { 145 u64 dividend = HDMI_PLL_CMP_CNT * fdata; 146 u32 divisor = ref_clk * 10; 147 u32 rem; 148 149 rem = do_div(dividend, divisor); 150 if (rem > (divisor >> 1)) 151 dividend++; 152 153 return dividend - 1; 154 } 155 156 static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk) 157 { 158 u64 fdata = ((u64)pll_cmp) * ref_clk * 10; 159 160 do_div(fdata, HDMI_PLL_CMP_CNT); 161 162 return fdata; 163 } 164 165 #define HDMI_REF_CLOCK_HZ ((u64)19200000) 166 #define HDMI_MHZ_TO_HZ ((u64)1000000) 167 static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk) 168 { 169 u32 const ratio_list[] = {1, 2, 3, 4, 5, 6, 170 9, 10, 12, 15, 25}; 171 u32 const band_list[] = {0, 1, 2, 3}; 172 u32 const sz_ratio = ARRAY_SIZE(ratio_list); 173 u32 const sz_band = ARRAY_SIZE(band_list); 174 u32 const cmp_cnt = 1024; 175 u32 const th_min = 500, th_max = 1000; 176 u32 half_rate_mode = 0; 177 u32 list_elements; 178 int optimal_index; 179 u32 i, j, k; 180 u32 found_hsclk_divsel = 0, found_vco_ratio; 181 u32 found_tx_band_sel; 182 u64 const min_freq = HDMI_VCO_MIN_FREQ, max_freq = HDMI_VCO_MAX_FREQ; 183 u64 freq_list[ARRAY_SIZE(ratio_list) * ARRAY_SIZE(band_list)]; 184 u64 found_vco_freq; 185 u64 freq_optimal; 186 187 find_optimal_index: 188 freq_optimal = max_freq; 189 optimal_index = -1; 190 list_elements = 0; 191 192 for (i = 0; i < sz_ratio; i++) { 193 for (j = 0; j < sz_band; j++) { 194 u64 freq = div_u64(bclk, (1 << half_rate_mode)); 195 196 freq *= (ratio_list[i] * (1 << band_list[j])); 197 freq_list[list_elements++] = freq; 198 } 199 } 200 201 for (k = 0; k < ARRAY_SIZE(freq_list); k++) { 202 u32 const clks_pll_div = 2, core_clk_div = 5; 203 u32 const rng1 = 16, rng2 = 8; 204 u32 th1, th2; 205 u64 core_clk, rvar1, rem; 206 207 core_clk = div_u64(freq_list[k], 208 ratio_list[k / sz_band] * clks_pll_div * 209 core_clk_div); 210 211 rvar1 = HDMI_REF_CLOCK_HZ * rng1 * HDMI_MHZ_TO_HZ; 212 rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem); 213 if (rem > ((cmp_cnt * core_clk) >> 1)) 214 rvar1++; 215 th1 = rvar1; 216 217 rvar1 = HDMI_REF_CLOCK_HZ * rng2 * HDMI_MHZ_TO_HZ; 218 rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem); 219 if (rem > ((cmp_cnt * core_clk) >> 1)) 220 rvar1++; 221 th2 = rvar1; 222 223 if (freq_list[k] >= min_freq && 224 freq_list[k] <= max_freq) { 225 if ((th1 >= th_min && th1 <= th_max) || 226 (th2 >= th_min && th2 <= th_max)) { 227 if (freq_list[k] <= freq_optimal) { 228 freq_optimal = freq_list[k]; 229 optimal_index = k; 230 } 231 } 232 } 233 } 234 235 if (optimal_index == -1) { 236 if (!half_rate_mode) { 237 half_rate_mode = 1; 238 goto find_optimal_index; 239 } else { 240 return -EINVAL; 241 } 242 } else { 243 found_vco_ratio = ratio_list[optimal_index / sz_band]; 244 found_tx_band_sel = band_list[optimal_index % sz_band]; 245 found_vco_freq = freq_optimal; 246 } 247 248 switch (found_vco_ratio) { 249 case 1: 250 found_hsclk_divsel = 15; 251 break; 252 case 2: 253 found_hsclk_divsel = 0; 254 break; 255 case 3: 256 found_hsclk_divsel = 4; 257 break; 258 case 4: 259 found_hsclk_divsel = 8; 260 break; 261 case 5: 262 found_hsclk_divsel = 12; 263 break; 264 case 6: 265 found_hsclk_divsel = 1; 266 break; 267 case 9: 268 found_hsclk_divsel = 5; 269 break; 270 case 10: 271 found_hsclk_divsel = 2; 272 break; 273 case 12: 274 found_hsclk_divsel = 9; 275 break; 276 case 15: 277 found_hsclk_divsel = 13; 278 break; 279 case 25: 280 found_hsclk_divsel = 14; 281 break; 282 }; 283 284 pd->vco_freq = found_vco_freq; 285 pd->tx_band_sel = found_tx_band_sel; 286 pd->vco_ratio = found_vco_ratio; 287 pd->hsclk_divsel = found_hsclk_divsel; 288 289 return 0; 290 } 291 292 static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk, 293 struct hdmi_8998_phy_pll_reg_cfg *cfg) 294 { 295 struct hdmi_8998_post_divider pd; 296 u64 bclk; 297 u64 dec_start; 298 u64 frac_start; 299 u64 fdata; 300 u32 pll_divisor; 301 u32 rem; 302 u32 cpctrl; 303 u32 rctrl; 304 u32 cctrl; 305 u32 integloop_gain; 306 u32 pll_cmp; 307 int i, ret; 308 309 /* bit clk = 10 * pix_clk */ 310 bclk = ((u64)pix_clk) * 10; 311 312 ret = pll_get_post_div(&pd, bclk); 313 if (ret) 314 return ret; 315 316 dec_start = pd.vco_freq; 317 pll_divisor = 4 * ref_clk; 318 do_div(dec_start, pll_divisor); 319 320 frac_start = pd.vco_freq * (1 << 20); 321 322 rem = do_div(frac_start, pll_divisor); 323 frac_start -= dec_start * (1 << 20); 324 if (rem > (pll_divisor >> 1)) 325 frac_start++; 326 327 cpctrl = pll_get_cpctrl(frac_start, ref_clk, false); 328 rctrl = pll_get_rctrl(frac_start, false); 329 cctrl = pll_get_cctrl(frac_start, false); 330 integloop_gain = pll_get_integloop_gain(frac_start, bclk, 331 ref_clk, false); 332 333 fdata = pd.vco_freq; 334 do_div(fdata, pd.vco_ratio); 335 336 pll_cmp = pll_get_pll_cmp(fdata, ref_clk); 337 338 /* Convert these values to register specific values */ 339 if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) 340 cfg->com_svs_mode_clk_sel = 1; 341 else 342 cfg->com_svs_mode_clk_sel = 2; 343 344 cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel); 345 cfg->com_pll_cctrl_mode0 = cctrl; 346 cfg->com_pll_rctrl_mode0 = rctrl; 347 cfg->com_cp_ctrl_mode0 = cpctrl; 348 cfg->com_dec_start_mode0 = dec_start; 349 cfg->com_div_frac_start1_mode0 = (frac_start & 0xff); 350 cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8); 351 cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16); 352 cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff); 353 cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8); 354 cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff); 355 cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8); 356 cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); 357 cfg->com_lock_cmp_en = 0x0; 358 cfg->com_core_clk_en = 0x2c; 359 cfg->com_coreclk_div_mode0 = HDMI_CORECLK_DIV; 360 cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x5 : 0x4; 361 362 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) 363 cfg->tx_lx_tx_band[i] = pd.tx_band_sel; 364 365 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { 366 cfg->tx_lx_tx_drv_lvl[0] = 0x0f; 367 cfg->tx_lx_tx_drv_lvl[1] = 0x0f; 368 cfg->tx_lx_tx_drv_lvl[2] = 0x0f; 369 cfg->tx_lx_tx_drv_lvl[3] = 0x0f; 370 cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03; 371 cfg->tx_lx_tx_emp_post1_lvl[1] = 0x02; 372 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03; 373 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00; 374 cfg->tx_lx_pre_driver_1[0] = 0x00; 375 cfg->tx_lx_pre_driver_1[1] = 0x00; 376 cfg->tx_lx_pre_driver_1[2] = 0x00; 377 cfg->tx_lx_pre_driver_1[3] = 0x00; 378 cfg->tx_lx_pre_driver_2[0] = 0x1C; 379 cfg->tx_lx_pre_driver_2[1] = 0x1C; 380 cfg->tx_lx_pre_driver_2[2] = 0x1C; 381 cfg->tx_lx_pre_driver_2[3] = 0x00; 382 cfg->tx_lx_res_code_offset[0] = 0x03; 383 cfg->tx_lx_res_code_offset[1] = 0x00; 384 cfg->tx_lx_res_code_offset[2] = 0x00; 385 cfg->tx_lx_res_code_offset[3] = 0x03; 386 } else if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) { 387 cfg->tx_lx_tx_drv_lvl[0] = 0x0f; 388 cfg->tx_lx_tx_drv_lvl[1] = 0x0f; 389 cfg->tx_lx_tx_drv_lvl[2] = 0x0f; 390 cfg->tx_lx_tx_drv_lvl[3] = 0x0f; 391 cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03; 392 cfg->tx_lx_tx_emp_post1_lvl[1] = 0x03; 393 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03; 394 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00; 395 cfg->tx_lx_pre_driver_1[0] = 0x00; 396 cfg->tx_lx_pre_driver_1[1] = 0x00; 397 cfg->tx_lx_pre_driver_1[2] = 0x00; 398 cfg->tx_lx_pre_driver_1[3] = 0x00; 399 cfg->tx_lx_pre_driver_2[0] = 0x16; 400 cfg->tx_lx_pre_driver_2[1] = 0x16; 401 cfg->tx_lx_pre_driver_2[2] = 0x16; 402 cfg->tx_lx_pre_driver_2[3] = 0x18; 403 cfg->tx_lx_res_code_offset[0] = 0x03; 404 cfg->tx_lx_res_code_offset[1] = 0x00; 405 cfg->tx_lx_res_code_offset[2] = 0x00; 406 cfg->tx_lx_res_code_offset[3] = 0x00; 407 } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { 408 cfg->tx_lx_tx_drv_lvl[0] = 0x0f; 409 cfg->tx_lx_tx_drv_lvl[1] = 0x0f; 410 cfg->tx_lx_tx_drv_lvl[2] = 0x0f; 411 cfg->tx_lx_tx_drv_lvl[3] = 0x0f; 412 cfg->tx_lx_tx_emp_post1_lvl[0] = 0x05; 413 cfg->tx_lx_tx_emp_post1_lvl[1] = 0x05; 414 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x05; 415 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00; 416 cfg->tx_lx_pre_driver_1[0] = 0x00; 417 cfg->tx_lx_pre_driver_1[1] = 0x00; 418 cfg->tx_lx_pre_driver_1[2] = 0x00; 419 cfg->tx_lx_pre_driver_1[3] = 0x00; 420 cfg->tx_lx_pre_driver_2[0] = 0x0E; 421 cfg->tx_lx_pre_driver_2[1] = 0x0E; 422 cfg->tx_lx_pre_driver_2[2] = 0x0E; 423 cfg->tx_lx_pre_driver_2[3] = 0x0E; 424 cfg->tx_lx_res_code_offset[0] = 0x00; 425 cfg->tx_lx_res_code_offset[1] = 0x00; 426 cfg->tx_lx_res_code_offset[2] = 0x00; 427 cfg->tx_lx_res_code_offset[3] = 0x00; 428 } else { 429 cfg->tx_lx_tx_drv_lvl[0] = 0x01; 430 cfg->tx_lx_tx_drv_lvl[1] = 0x01; 431 cfg->tx_lx_tx_drv_lvl[2] = 0x01; 432 cfg->tx_lx_tx_drv_lvl[3] = 0x00; 433 cfg->tx_lx_tx_emp_post1_lvl[0] = 0x00; 434 cfg->tx_lx_tx_emp_post1_lvl[1] = 0x00; 435 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x00; 436 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00; 437 cfg->tx_lx_pre_driver_1[0] = 0x00; 438 cfg->tx_lx_pre_driver_1[1] = 0x00; 439 cfg->tx_lx_pre_driver_1[2] = 0x00; 440 cfg->tx_lx_pre_driver_1[3] = 0x00; 441 cfg->tx_lx_pre_driver_2[0] = 0x16; 442 cfg->tx_lx_pre_driver_2[1] = 0x16; 443 cfg->tx_lx_pre_driver_2[2] = 0x16; 444 cfg->tx_lx_pre_driver_2[3] = 0x18; 445 cfg->tx_lx_res_code_offset[0] = 0x00; 446 cfg->tx_lx_res_code_offset[1] = 0x00; 447 cfg->tx_lx_res_code_offset[2] = 0x00; 448 cfg->tx_lx_res_code_offset[3] = 0x00; 449 } 450 451 return 0; 452 } 453 454 static int hdmi_8998_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate, 455 unsigned long parent_rate) 456 { 457 struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw); 458 struct hdmi_phy *phy = pll_get_phy(pll); 459 struct hdmi_8998_phy_pll_reg_cfg cfg = {}; 460 int i, ret; 461 462 ret = pll_calculate(rate, parent_rate, &cfg); 463 if (ret) { 464 DRM_ERROR("PLL calculation failed\n"); 465 return ret; 466 } 467 468 /* Initially shut down PHY */ 469 hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x0); 470 udelay(500); 471 472 /* Power up sequence */ 473 hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x1); 474 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20); 475 hdmi_phy_write(phy, REG_HDMI_8998_PHY_CMN_CTRL, 0x6); 476 477 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 478 hdmi_tx_chan_write(pll, i, 479 REG_HDMI_8998_PHY_TXn_INTERFACE_SELECT_TX_BAND, 480 cfg.tx_lx_tx_band[i]); 481 hdmi_tx_chan_write(pll, i, 482 REG_HDMI_8998_PHY_TXn_CLKBUF_TERM_ENABLE, 483 0x1); 484 hdmi_tx_chan_write(pll, i, 485 REG_HDMI_8998_PHY_TXn_LANE_MODE, 486 0x20); 487 } 488 489 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x02); 490 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x0B); 491 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37); 492 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02); 493 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E); 494 495 /* Bypass VCO calibration */ 496 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SVS_MODE_CLK_SEL, 497 cfg.com_svs_mode_clk_sel); 498 499 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_IVCO, 0x07); 500 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_CTRL, 0x00); 501 502 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_SEL, 0x30); 503 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_HSCLK_SEL, 504 cfg.com_hsclk_sel); 505 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP_EN, 506 cfg.com_lock_cmp_en); 507 508 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_CCTRL_MODE0, 509 cfg.com_pll_cctrl_mode0); 510 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_RCTRL_MODE0, 511 cfg.com_pll_rctrl_mode0); 512 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CP_CTRL_MODE0, 513 cfg.com_cp_ctrl_mode0); 514 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DEC_START_MODE0, 515 cfg.com_dec_start_mode0); 516 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0, 517 cfg.com_div_frac_start1_mode0); 518 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0, 519 cfg.com_div_frac_start2_mode0); 520 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0, 521 cfg.com_div_frac_start3_mode0); 522 523 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 524 cfg.com_integloop_gain0_mode0); 525 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 526 cfg.com_integloop_gain1_mode0); 527 528 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP1_MODE0, 529 cfg.com_lock_cmp1_mode0); 530 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP2_MODE0, 531 cfg.com_lock_cmp2_mode0); 532 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP3_MODE0, 533 cfg.com_lock_cmp3_mode0); 534 535 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00); 536 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORE_CLK_EN, 537 cfg.com_core_clk_en); 538 hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORECLK_DIV_MODE0, 539 cfg.com_coreclk_div_mode0); 540 541 /* TX lanes setup (TX 0/1/2/3) */ 542 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 543 hdmi_tx_chan_write(pll, i, 544 REG_HDMI_8998_PHY_TXn_DRV_LVL, 545 cfg.tx_lx_tx_drv_lvl[i]); 546 hdmi_tx_chan_write(pll, i, 547 REG_HDMI_8998_PHY_TXn_EMP_POST1_LVL, 548 cfg.tx_lx_tx_emp_post1_lvl[i]); 549 hdmi_tx_chan_write(pll, i, 550 REG_HDMI_8998_PHY_TXn_PRE_DRIVER_1, 551 cfg.tx_lx_pre_driver_1[i]); 552 hdmi_tx_chan_write(pll, i, 553 REG_HDMI_8998_PHY_TXn_PRE_DRIVER_2, 554 cfg.tx_lx_pre_driver_2[i]); 555 hdmi_tx_chan_write(pll, i, 556 REG_HDMI_8998_PHY_TXn_DRV_LVL_RES_CODE_OFFSET, 557 cfg.tx_lx_res_code_offset[i]); 558 } 559 560 hdmi_phy_write(phy, REG_HDMI_8998_PHY_MODE, cfg.phy_mode); 561 562 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 563 hdmi_tx_chan_write(pll, i, 564 REG_HDMI_8998_PHY_TXn_LANE_CONFIG, 565 0x10); 566 } 567 568 /* 569 * Ensure that vco configuration gets flushed to hardware before 570 * enabling the PLL 571 */ 572 wmb(); 573 574 pll->rate = rate; 575 576 return 0; 577 } 578 579 static int hdmi_8998_phy_ready_status(struct hdmi_phy *phy) 580 { 581 u32 nb_tries = HDMI_PLL_POLL_MAX_READS; 582 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; 583 u32 status; 584 int phy_ready = 0; 585 586 while (nb_tries--) { 587 status = hdmi_phy_read(phy, REG_HDMI_8998_PHY_STATUS); 588 phy_ready = status & BIT(0); 589 590 if (phy_ready) 591 break; 592 593 udelay(timeout); 594 } 595 596 return phy_ready; 597 } 598 599 static int hdmi_8998_pll_lock_status(struct hdmi_pll_8998 *pll) 600 { 601 u32 status; 602 int nb_tries = HDMI_PLL_POLL_MAX_READS; 603 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; 604 int pll_locked = 0; 605 606 while (nb_tries--) { 607 status = hdmi_pll_read(pll, 608 REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS); 609 pll_locked = status & BIT(0); 610 611 if (pll_locked) 612 break; 613 614 udelay(timeout); 615 } 616 617 return pll_locked; 618 } 619 620 static int hdmi_8998_pll_prepare(struct clk_hw *hw) 621 { 622 struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw); 623 struct hdmi_phy *phy = pll_get_phy(pll); 624 int i, ret = 0; 625 626 hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x1); 627 udelay(100); 628 629 hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59); 630 udelay(100); 631 632 ret = hdmi_8998_pll_lock_status(pll); 633 if (!ret) 634 return ret; 635 636 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 637 hdmi_tx_chan_write(pll, i, 638 REG_HDMI_8998_PHY_TXn_LANE_CONFIG, 0x1F); 639 } 640 641 /* Ensure all registers are flushed to hardware */ 642 wmb(); 643 644 ret = hdmi_8998_phy_ready_status(phy); 645 if (!ret) 646 return ret; 647 648 /* Restart the retiming buffer */ 649 hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x58); 650 udelay(1); 651 hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59); 652 653 /* Ensure all registers are flushed to hardware */ 654 wmb(); 655 656 return 0; 657 } 658 659 static long hdmi_8998_pll_round_rate(struct clk_hw *hw, 660 unsigned long rate, 661 unsigned long *parent_rate) 662 { 663 if (rate < HDMI_PCLK_MIN_FREQ) 664 return HDMI_PCLK_MIN_FREQ; 665 else if (rate > HDMI_PCLK_MAX_FREQ) 666 return HDMI_PCLK_MAX_FREQ; 667 else 668 return rate; 669 } 670 671 static unsigned long hdmi_8998_pll_recalc_rate(struct clk_hw *hw, 672 unsigned long parent_rate) 673 { 674 struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw); 675 return pll->rate; 676 } 677 678 static void hdmi_8998_pll_unprepare(struct clk_hw *hw) 679 { 680 struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw); 681 struct hdmi_phy *phy = pll_get_phy(pll); 682 683 hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0); 684 usleep_range(100, 150); 685 } 686 687 static int hdmi_8998_pll_is_enabled(struct clk_hw *hw) 688 { 689 struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw); 690 u32 status; 691 int pll_locked; 692 693 status = hdmi_pll_read(pll, REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS); 694 pll_locked = status & BIT(0); 695 696 return pll_locked; 697 } 698 699 static const struct clk_ops hdmi_8998_pll_ops = { 700 .set_rate = hdmi_8998_pll_set_clk_rate, 701 .round_rate = hdmi_8998_pll_round_rate, 702 .recalc_rate = hdmi_8998_pll_recalc_rate, 703 .prepare = hdmi_8998_pll_prepare, 704 .unprepare = hdmi_8998_pll_unprepare, 705 .is_enabled = hdmi_8998_pll_is_enabled, 706 }; 707 708 static const struct clk_init_data pll_init = { 709 .name = "hdmipll", 710 .ops = &hdmi_8998_pll_ops, 711 .parent_data = (const struct clk_parent_data[]){ 712 { .fw_name = "xo", .name = "xo_board" }, 713 }, 714 .num_parents = 1, 715 .flags = CLK_IGNORE_UNUSED, 716 }; 717 718 int msm_hdmi_pll_8998_init(struct platform_device *pdev) 719 { 720 struct device *dev = &pdev->dev; 721 struct hdmi_pll_8998 *pll; 722 int ret, i; 723 724 pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); 725 if (!pll) 726 return -ENOMEM; 727 728 pll->pdev = pdev; 729 730 pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll"); 731 if (IS_ERR(pll->mmio_qserdes_com)) { 732 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 733 return -ENOMEM; 734 } 735 736 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 737 char name[32]; 738 739 snprintf(name, sizeof(name), "hdmi_tx_l%d", i); 740 741 pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name); 742 if (IS_ERR(pll->mmio_qserdes_tx[i])) { 743 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 744 return -ENOMEM; 745 } 746 } 747 pll->clk_hw.init = &pll_init; 748 749 ret = devm_clk_hw_register(dev, &pll->clk_hw); 750 if (ret) { 751 DRM_DEV_ERROR(dev, "failed to register pll clock\n"); 752 return ret; 753 } 754 755 ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw); 756 if (ret) { 757 DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); 758 return ret; 759 } 760 761 return 0; 762 } 763 764 static const char * const hdmi_phy_8998_reg_names[] = { 765 "vddio", 766 "vcca", 767 }; 768 769 static const char * const hdmi_phy_8998_clk_names[] = { 770 "iface", "ref", "xo", 771 }; 772 773 const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg = { 774 .type = MSM_HDMI_PHY_8998, 775 .reg_names = hdmi_phy_8998_reg_names, 776 .num_regs = ARRAY_SIZE(hdmi_phy_8998_reg_names), 777 .clk_names = hdmi_phy_8998_clk_names, 778 .num_clks = ARRAY_SIZE(hdmi_phy_8998_clk_names), 779 }; 780