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