hdmi_phy_8996.c (21254B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2016, The Linux Foundation. All rights reserved. 4 */ 5 6#include <linux/clk-provider.h> 7#include <linux/delay.h> 8 9#include "hdmi.h" 10 11#define HDMI_VCO_MAX_FREQ 12000000000UL 12#define HDMI_VCO_MIN_FREQ 8000000000UL 13 14#define HDMI_PCLK_MAX_FREQ 600000000 15#define HDMI_PCLK_MIN_FREQ 25000000 16 17#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL 18#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL 19#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL 20#define HDMI_CORECLK_DIV 5 21#define HDMI_DEFAULT_REF_CLOCK 19200000 22#define HDMI_PLL_CMP_CNT 1024 23 24#define HDMI_PLL_POLL_MAX_READS 100 25#define HDMI_PLL_POLL_TIMEOUT_US 150 26 27#define HDMI_NUM_TX_CHANNEL 4 28 29struct hdmi_pll_8996 { 30 struct platform_device *pdev; 31 struct clk_hw clk_hw; 32 33 /* pll mmio base */ 34 void __iomem *mmio_qserdes_com; 35 /* tx channel base */ 36 void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL]; 37}; 38 39#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw) 40 41struct hdmi_8996_phy_pll_reg_cfg { 42 u32 tx_lx_lane_mode[HDMI_NUM_TX_CHANNEL]; 43 u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL]; 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; 61 u32 com_vco_tune_ctrl; 62 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_vmode_ctrl1[HDMI_NUM_TX_CHANNEL]; 66 u32 tx_lx_vmode_ctrl2[HDMI_NUM_TX_CHANNEL]; 67 u32 tx_lx_res_code_lane_tx[HDMI_NUM_TX_CHANNEL]; 68 u32 tx_lx_hp_pd_enables[HDMI_NUM_TX_CHANNEL]; 69 70 u32 phy_mode; 71}; 72 73struct hdmi_8996_post_divider { 74 u64 vco_freq; 75 int hsclk_divsel; 76 int vco_ratio; 77 int tx_band_sel; 78 int half_rate_mode; 79}; 80 81static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll) 82{ 83 return platform_get_drvdata(pll->pdev); 84} 85 86static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset, 87 u32 data) 88{ 89 msm_writel(data, pll->mmio_qserdes_com + offset); 90} 91 92static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset) 93{ 94 return msm_readl(pll->mmio_qserdes_com + offset); 95} 96 97static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel, 98 int offset, int data) 99{ 100 msm_writel(data, pll->mmio_qserdes_tx[channel] + offset); 101} 102 103static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk, 104 bool gen_ssc) 105{ 106 if ((frac_start != 0) || gen_ssc) 107 return (11000000 / (ref_clk / 20)); 108 109 return 0x23; 110} 111 112static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc) 113{ 114 if ((frac_start != 0) || gen_ssc) 115 return 0x16; 116 117 return 0x10; 118} 119 120static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc) 121{ 122 if ((frac_start != 0) || gen_ssc) 123 return 0x28; 124 125 return 0x1; 126} 127 128static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk, 129 bool gen_ssc) 130{ 131 int digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2; 132 u64 base; 133 134 if ((frac_start != 0) || gen_ssc) 135 base = (64 * ref_clk) / HDMI_DEFAULT_REF_CLOCK; 136 else 137 base = (1022 * ref_clk) / 100; 138 139 base <<= digclk_divsel; 140 141 return (base <= 2046 ? base : 2046); 142} 143 144static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) 145{ 146 u64 dividend = HDMI_PLL_CMP_CNT * fdata; 147 u32 divisor = ref_clk * 10; 148 u32 rem; 149 150 rem = do_div(dividend, divisor); 151 if (rem > (divisor >> 1)) 152 dividend++; 153 154 return dividend - 1; 155} 156 157static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk) 158{ 159 u64 fdata = ((u64)pll_cmp) * ref_clk * 10; 160 161 do_div(fdata, HDMI_PLL_CMP_CNT); 162 163 return fdata; 164} 165 166static int pll_get_post_div(struct hdmi_8996_post_divider *pd, u64 bclk) 167{ 168 int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 }; 169 int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 }; 170 int tx_band_sel[] = { 0, 1, 2, 3 }; 171 u64 vco_freq[60]; 172 u64 vco, vco_optimal; 173 int half_rate_mode = 0; 174 int vco_optimal_index, vco_freq_index; 175 int i, j; 176 177retry: 178 vco_optimal = HDMI_VCO_MAX_FREQ; 179 vco_optimal_index = -1; 180 vco_freq_index = 0; 181 for (i = 0; i < 15; i++) { 182 for (j = 0; j < 4; j++) { 183 u32 ratio_mult = ratio[i] << tx_band_sel[j]; 184 185 vco = bclk >> half_rate_mode; 186 vco *= ratio_mult; 187 vco_freq[vco_freq_index++] = vco; 188 } 189 } 190 191 for (i = 0; i < 60; i++) { 192 u64 vco_tmp = vco_freq[i]; 193 194 if ((vco_tmp >= HDMI_VCO_MIN_FREQ) && 195 (vco_tmp <= vco_optimal)) { 196 vco_optimal = vco_tmp; 197 vco_optimal_index = i; 198 } 199 } 200 201 if (vco_optimal_index == -1) { 202 if (!half_rate_mode) { 203 half_rate_mode = 1; 204 goto retry; 205 } 206 } else { 207 pd->vco_freq = vco_optimal; 208 pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4]; 209 pd->vco_ratio = ratio[vco_optimal_index / 4]; 210 pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4]; 211 212 return 0; 213 } 214 215 return -EINVAL; 216} 217 218static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk, 219 struct hdmi_8996_phy_pll_reg_cfg *cfg) 220{ 221 struct hdmi_8996_post_divider pd; 222 u64 bclk; 223 u64 tmds_clk; 224 u64 dec_start; 225 u64 frac_start; 226 u64 fdata; 227 u32 pll_divisor; 228 u32 rem; 229 u32 cpctrl; 230 u32 rctrl; 231 u32 cctrl; 232 u32 integloop_gain; 233 u32 pll_cmp; 234 int i, ret; 235 236 /* bit clk = 10 * pix_clk */ 237 bclk = ((u64)pix_clk) * 10; 238 239 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) 240 tmds_clk = pix_clk >> 2; 241 else 242 tmds_clk = pix_clk; 243 244 ret = pll_get_post_div(&pd, bclk); 245 if (ret) 246 return ret; 247 248 dec_start = pd.vco_freq; 249 pll_divisor = 4 * ref_clk; 250 do_div(dec_start, pll_divisor); 251 252 frac_start = pd.vco_freq * (1 << 20); 253 254 rem = do_div(frac_start, pll_divisor); 255 frac_start -= dec_start * (1 << 20); 256 if (rem > (pll_divisor >> 1)) 257 frac_start++; 258 259 cpctrl = pll_get_cpctrl(frac_start, ref_clk, false); 260 rctrl = pll_get_rctrl(frac_start, false); 261 cctrl = pll_get_cctrl(frac_start, false); 262 integloop_gain = pll_get_integloop_gain(frac_start, bclk, 263 ref_clk, false); 264 265 fdata = pd.vco_freq; 266 do_div(fdata, pd.vco_ratio); 267 268 pll_cmp = pll_get_pll_cmp(fdata, ref_clk); 269 270 DBG("VCO freq: %llu", pd.vco_freq); 271 DBG("fdata: %llu", fdata); 272 DBG("pix_clk: %lu", pix_clk); 273 DBG("tmds clk: %llu", tmds_clk); 274 DBG("HSCLK_SEL: %d", pd.hsclk_divsel); 275 DBG("DEC_START: %llu", dec_start); 276 DBG("DIV_FRAC_START: %llu", frac_start); 277 DBG("PLL_CPCTRL: %u", cpctrl); 278 DBG("PLL_RCTRL: %u", rctrl); 279 DBG("PLL_CCTRL: %u", cctrl); 280 DBG("INTEGLOOP_GAIN: %u", integloop_gain); 281 DBG("TX_BAND: %d", pd.tx_band_sel); 282 DBG("PLL_CMP: %u", pll_cmp); 283 284 /* Convert these values to register specific values */ 285 if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) 286 cfg->com_svs_mode_clk_sel = 1; 287 else 288 cfg->com_svs_mode_clk_sel = 2; 289 290 cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel); 291 cfg->com_pll_cctrl_mode0 = cctrl; 292 cfg->com_pll_rctrl_mode0 = rctrl; 293 cfg->com_cp_ctrl_mode0 = cpctrl; 294 cfg->com_dec_start_mode0 = dec_start; 295 cfg->com_div_frac_start1_mode0 = (frac_start & 0xff); 296 cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8); 297 cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16); 298 cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff); 299 cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8); 300 cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff); 301 cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8); 302 cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); 303 cfg->com_lock_cmp_en = 0x0; 304 cfg->com_core_clk_en = 0x2c; 305 cfg->com_coreclk_div = HDMI_CORECLK_DIV; 306 cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0; 307 cfg->com_vco_tune_ctrl = 0x0; 308 309 cfg->tx_lx_lane_mode[0] = 310 cfg->tx_lx_lane_mode[2] = 0x43; 311 312 cfg->tx_lx_hp_pd_enables[0] = 313 cfg->tx_lx_hp_pd_enables[1] = 314 cfg->tx_lx_hp_pd_enables[2] = 0x0c; 315 cfg->tx_lx_hp_pd_enables[3] = 0x3; 316 317 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) 318 cfg->tx_lx_tx_band[i] = pd.tx_band_sel + 4; 319 320 if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { 321 cfg->tx_lx_tx_drv_lvl[0] = 322 cfg->tx_lx_tx_drv_lvl[1] = 323 cfg->tx_lx_tx_drv_lvl[2] = 0x25; 324 cfg->tx_lx_tx_drv_lvl[3] = 0x22; 325 326 cfg->tx_lx_tx_emp_post1_lvl[0] = 327 cfg->tx_lx_tx_emp_post1_lvl[1] = 328 cfg->tx_lx_tx_emp_post1_lvl[2] = 0x23; 329 cfg->tx_lx_tx_emp_post1_lvl[3] = 0x27; 330 331 cfg->tx_lx_vmode_ctrl1[0] = 332 cfg->tx_lx_vmode_ctrl1[1] = 333 cfg->tx_lx_vmode_ctrl1[2] = 334 cfg->tx_lx_vmode_ctrl1[3] = 0x00; 335 336 cfg->tx_lx_vmode_ctrl2[0] = 337 cfg->tx_lx_vmode_ctrl2[1] = 338 cfg->tx_lx_vmode_ctrl2[2] = 0x0D; 339 340 cfg->tx_lx_vmode_ctrl2[3] = 0x00; 341 } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { 342 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 343 cfg->tx_lx_tx_drv_lvl[i] = 0x25; 344 cfg->tx_lx_tx_emp_post1_lvl[i] = 0x23; 345 cfg->tx_lx_vmode_ctrl1[i] = 0x00; 346 } 347 348 cfg->tx_lx_vmode_ctrl2[0] = 349 cfg->tx_lx_vmode_ctrl2[1] = 350 cfg->tx_lx_vmode_ctrl2[2] = 0x0D; 351 cfg->tx_lx_vmode_ctrl2[3] = 0x00; 352 } else { 353 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 354 cfg->tx_lx_tx_drv_lvl[i] = 0x20; 355 cfg->tx_lx_tx_emp_post1_lvl[i] = 0x20; 356 cfg->tx_lx_vmode_ctrl1[i] = 0x00; 357 cfg->tx_lx_vmode_ctrl2[i] = 0x0E; 358 } 359 } 360 361 DBG("com_svs_mode_clk_sel = 0x%x", cfg->com_svs_mode_clk_sel); 362 DBG("com_hsclk_sel = 0x%x", cfg->com_hsclk_sel); 363 DBG("com_lock_cmp_en = 0x%x", cfg->com_lock_cmp_en); 364 DBG("com_pll_cctrl_mode0 = 0x%x", cfg->com_pll_cctrl_mode0); 365 DBG("com_pll_rctrl_mode0 = 0x%x", cfg->com_pll_rctrl_mode0); 366 DBG("com_cp_ctrl_mode0 = 0x%x", cfg->com_cp_ctrl_mode0); 367 DBG("com_dec_start_mode0 = 0x%x", cfg->com_dec_start_mode0); 368 DBG("com_div_frac_start1_mode0 = 0x%x", cfg->com_div_frac_start1_mode0); 369 DBG("com_div_frac_start2_mode0 = 0x%x", cfg->com_div_frac_start2_mode0); 370 DBG("com_div_frac_start3_mode0 = 0x%x", cfg->com_div_frac_start3_mode0); 371 DBG("com_integloop_gain0_mode0 = 0x%x", cfg->com_integloop_gain0_mode0); 372 DBG("com_integloop_gain1_mode0 = 0x%x", cfg->com_integloop_gain1_mode0); 373 DBG("com_lock_cmp1_mode0 = 0x%x", cfg->com_lock_cmp1_mode0); 374 DBG("com_lock_cmp2_mode0 = 0x%x", cfg->com_lock_cmp2_mode0); 375 DBG("com_lock_cmp3_mode0 = 0x%x", cfg->com_lock_cmp3_mode0); 376 DBG("com_core_clk_en = 0x%x", cfg->com_core_clk_en); 377 DBG("com_coreclk_div = 0x%x", cfg->com_coreclk_div); 378 DBG("phy_mode = 0x%x", cfg->phy_mode); 379 380 DBG("tx_l0_lane_mode = 0x%x", cfg->tx_lx_lane_mode[0]); 381 DBG("tx_l2_lane_mode = 0x%x", cfg->tx_lx_lane_mode[2]); 382 383 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 384 DBG("tx_l%d_tx_band = 0x%x", i, cfg->tx_lx_tx_band[i]); 385 DBG("tx_l%d_tx_drv_lvl = 0x%x", i, cfg->tx_lx_tx_drv_lvl[i]); 386 DBG("tx_l%d_tx_emp_post1_lvl = 0x%x", i, 387 cfg->tx_lx_tx_emp_post1_lvl[i]); 388 DBG("tx_l%d_vmode_ctrl1 = 0x%x", i, cfg->tx_lx_vmode_ctrl1[i]); 389 DBG("tx_l%d_vmode_ctrl2 = 0x%x", i, cfg->tx_lx_vmode_ctrl2[i]); 390 } 391 392 return 0; 393} 394 395static int hdmi_8996_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate, 396 unsigned long parent_rate) 397{ 398 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); 399 struct hdmi_phy *phy = pll_get_phy(pll); 400 struct hdmi_8996_phy_pll_reg_cfg cfg; 401 int i, ret; 402 403 memset(&cfg, 0x00, sizeof(cfg)); 404 405 ret = pll_calculate(rate, parent_rate, &cfg); 406 if (ret) { 407 DRM_ERROR("PLL calculation failed\n"); 408 return ret; 409 } 410 411 /* Initially shut down PHY */ 412 DBG("Disabling PHY"); 413 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x0); 414 udelay(500); 415 416 /* Power up sequence */ 417 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x04); 418 419 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1); 420 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20); 421 hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0F); 422 hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0F); 423 424 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 425 hdmi_tx_chan_write(pll, i, 426 REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE, 427 0x03); 428 hdmi_tx_chan_write(pll, i, 429 REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND, 430 cfg.tx_lx_tx_band[i]); 431 hdmi_tx_chan_write(pll, i, 432 REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN, 433 0x03); 434 } 435 436 hdmi_tx_chan_write(pll, 0, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE, 437 cfg.tx_lx_lane_mode[0]); 438 hdmi_tx_chan_write(pll, 2, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE, 439 cfg.tx_lx_lane_mode[2]); 440 441 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E); 442 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07); 443 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37); 444 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02); 445 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E); 446 447 /* Bypass VCO calibration */ 448 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL, 449 cfg.com_svs_mode_clk_sel); 450 451 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_TRIM, 0x0F); 452 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_IVCO, 0x0F); 453 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL, 454 cfg.com_vco_tune_ctrl); 455 456 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x06); 457 458 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_SELECT, 0x30); 459 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL, 460 cfg.com_hsclk_sel); 461 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN, 462 cfg.com_lock_cmp_en); 463 464 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0, 465 cfg.com_pll_cctrl_mode0); 466 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0, 467 cfg.com_pll_rctrl_mode0); 468 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0, 469 cfg.com_cp_ctrl_mode0); 470 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0, 471 cfg.com_dec_start_mode0); 472 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0, 473 cfg.com_div_frac_start1_mode0); 474 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0, 475 cfg.com_div_frac_start2_mode0); 476 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0, 477 cfg.com_div_frac_start3_mode0); 478 479 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 480 cfg.com_integloop_gain0_mode0); 481 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 482 cfg.com_integloop_gain1_mode0); 483 484 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0, 485 cfg.com_lock_cmp1_mode0); 486 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0, 487 cfg.com_lock_cmp2_mode0); 488 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0, 489 cfg.com_lock_cmp3_mode0); 490 491 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00); 492 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN, 493 cfg.com_core_clk_en); 494 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV, 495 cfg.com_coreclk_div); 496 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG, 0x02); 497 498 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM, 0x15); 499 500 /* TX lanes setup (TX 0/1/2/3) */ 501 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 502 hdmi_tx_chan_write(pll, i, 503 REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL, 504 cfg.tx_lx_tx_drv_lvl[i]); 505 hdmi_tx_chan_write(pll, i, 506 REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL, 507 cfg.tx_lx_tx_emp_post1_lvl[i]); 508 hdmi_tx_chan_write(pll, i, 509 REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1, 510 cfg.tx_lx_vmode_ctrl1[i]); 511 hdmi_tx_chan_write(pll, i, 512 REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2, 513 cfg.tx_lx_vmode_ctrl2[i]); 514 hdmi_tx_chan_write(pll, i, 515 REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET, 516 0x00); 517 hdmi_tx_chan_write(pll, i, 518 REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET, 519 0x00); 520 hdmi_tx_chan_write(pll, i, 521 REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN, 522 0x03); 523 hdmi_tx_chan_write(pll, i, 524 REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN, 525 0x40); 526 hdmi_tx_chan_write(pll, i, 527 REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES, 528 cfg.tx_lx_hp_pd_enables[i]); 529 } 530 531 hdmi_phy_write(phy, REG_HDMI_8996_PHY_MODE, cfg.phy_mode); 532 hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1F); 533 534 /* 535 * Ensure that vco configuration gets flushed to hardware before 536 * enabling the PLL 537 */ 538 wmb(); 539 540 return 0; 541} 542 543static int hdmi_8996_phy_ready_status(struct hdmi_phy *phy) 544{ 545 u32 nb_tries = HDMI_PLL_POLL_MAX_READS; 546 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; 547 u32 status; 548 int phy_ready = 0; 549 550 DBG("Waiting for PHY ready"); 551 552 while (nb_tries--) { 553 status = hdmi_phy_read(phy, REG_HDMI_8996_PHY_STATUS); 554 phy_ready = status & BIT(0); 555 556 if (phy_ready) 557 break; 558 559 udelay(timeout); 560 } 561 562 DBG("PHY is %sready", phy_ready ? "" : "*not* "); 563 564 return phy_ready; 565} 566 567static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996 *pll) 568{ 569 u32 status; 570 int nb_tries = HDMI_PLL_POLL_MAX_READS; 571 unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; 572 int pll_locked = 0; 573 574 DBG("Waiting for PLL lock"); 575 576 while (nb_tries--) { 577 status = hdmi_pll_read(pll, 578 REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS); 579 pll_locked = status & BIT(0); 580 581 if (pll_locked) 582 break; 583 584 udelay(timeout); 585 } 586 587 DBG("HDMI PLL is %slocked", pll_locked ? "" : "*not* "); 588 589 return pll_locked; 590} 591 592static int hdmi_8996_pll_prepare(struct clk_hw *hw) 593{ 594 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); 595 struct hdmi_phy *phy = pll_get_phy(pll); 596 int i, ret = 0; 597 598 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x1); 599 udelay(100); 600 601 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19); 602 udelay(100); 603 604 ret = hdmi_8996_pll_lock_status(pll); 605 if (!ret) 606 return ret; 607 608 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) 609 hdmi_tx_chan_write(pll, i, 610 REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 611 0x6F); 612 613 /* Disable SSC */ 614 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER1, 0x0); 615 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER2, 0x0); 616 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1, 0x0); 617 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2, 0x0); 618 hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER, 0x2); 619 620 ret = hdmi_8996_phy_ready_status(phy); 621 if (!ret) 622 return ret; 623 624 /* Restart the retiming buffer */ 625 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x18); 626 udelay(1); 627 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19); 628 629 return 0; 630} 631 632static long hdmi_8996_pll_round_rate(struct clk_hw *hw, 633 unsigned long rate, 634 unsigned long *parent_rate) 635{ 636 if (rate < HDMI_PCLK_MIN_FREQ) 637 return HDMI_PCLK_MIN_FREQ; 638 else if (rate > HDMI_PCLK_MAX_FREQ) 639 return HDMI_PCLK_MAX_FREQ; 640 else 641 return rate; 642} 643 644static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw, 645 unsigned long parent_rate) 646{ 647 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); 648 u64 fdata; 649 u32 cmp1, cmp2, cmp3, pll_cmp; 650 651 cmp1 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0); 652 cmp2 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0); 653 cmp3 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0); 654 655 pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16); 656 657 fdata = pll_cmp_to_fdata(pll_cmp + 1, parent_rate); 658 659 do_div(fdata, 10); 660 661 return fdata; 662} 663 664static void hdmi_8996_pll_unprepare(struct clk_hw *hw) 665{ 666 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); 667 struct hdmi_phy *phy = pll_get_phy(pll); 668 669 hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x6); 670 usleep_range(100, 150); 671} 672 673static int hdmi_8996_pll_is_enabled(struct clk_hw *hw) 674{ 675 struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); 676 u32 status; 677 int pll_locked; 678 679 status = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS); 680 pll_locked = status & BIT(0); 681 682 return pll_locked; 683} 684 685static const struct clk_ops hdmi_8996_pll_ops = { 686 .set_rate = hdmi_8996_pll_set_clk_rate, 687 .round_rate = hdmi_8996_pll_round_rate, 688 .recalc_rate = hdmi_8996_pll_recalc_rate, 689 .prepare = hdmi_8996_pll_prepare, 690 .unprepare = hdmi_8996_pll_unprepare, 691 .is_enabled = hdmi_8996_pll_is_enabled, 692}; 693 694static const char * const hdmi_pll_parents[] = { 695 "xo", 696}; 697 698static const struct clk_init_data pll_init = { 699 .name = "hdmipll", 700 .ops = &hdmi_8996_pll_ops, 701 .parent_names = hdmi_pll_parents, 702 .num_parents = ARRAY_SIZE(hdmi_pll_parents), 703 .flags = CLK_IGNORE_UNUSED, 704}; 705 706int msm_hdmi_pll_8996_init(struct platform_device *pdev) 707{ 708 struct device *dev = &pdev->dev; 709 struct hdmi_pll_8996 *pll; 710 struct clk *clk; 711 int i; 712 713 pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); 714 if (!pll) 715 return -ENOMEM; 716 717 pll->pdev = pdev; 718 719 pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll"); 720 if (IS_ERR(pll->mmio_qserdes_com)) { 721 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 722 return -ENOMEM; 723 } 724 725 for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { 726 char name[32]; 727 728 snprintf(name, sizeof(name), "hdmi_tx_l%d", i); 729 730 pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name); 731 if (IS_ERR(pll->mmio_qserdes_tx[i])) { 732 DRM_DEV_ERROR(dev, "failed to map pll base\n"); 733 return -ENOMEM; 734 } 735 } 736 pll->clk_hw.init = &pll_init; 737 738 clk = devm_clk_register(dev, &pll->clk_hw); 739 if (IS_ERR(clk)) { 740 DRM_DEV_ERROR(dev, "failed to register pll clock\n"); 741 return -EINVAL; 742 } 743 744 return 0; 745} 746 747static const char * const hdmi_phy_8996_reg_names[] = { 748 "vddio", 749 "vcca", 750}; 751 752static const char * const hdmi_phy_8996_clk_names[] = { 753 "iface", "ref", 754}; 755 756const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = { 757 .type = MSM_HDMI_PHY_8996, 758 .reg_names = hdmi_phy_8996_reg_names, 759 .num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names), 760 .clk_names = hdmi_phy_8996_clk_names, 761 .num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names), 762};