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