root/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pll_get_phy
  2. hdmi_pll_write
  3. hdmi_pll_read
  4. hdmi_tx_chan_write
  5. pll_get_cpctrl
  6. pll_get_rctrl
  7. pll_get_cctrl
  8. pll_get_integloop_gain
  9. pll_get_pll_cmp
  10. pll_cmp_to_fdata
  11. pll_get_post_div
  12. pll_calculate
  13. hdmi_8996_pll_set_clk_rate
  14. hdmi_8996_phy_ready_status
  15. hdmi_8996_pll_lock_status
  16. hdmi_8996_pll_prepare
  17. hdmi_8996_pll_round_rate
  18. hdmi_8996_pll_recalc_rate
  19. hdmi_8996_pll_unprepare
  20. hdmi_8996_pll_is_enabled
  21. msm_hdmi_pll_8996_init

   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 
  29 struct 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 
  41 struct 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 
  73 struct 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 
  81 static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll)
  82 {
  83         return platform_get_drvdata(pll->pdev);
  84 }
  85 
  86 static 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 
  92 static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset)
  93 {
  94         return msm_readl(pll->mmio_qserdes_com + offset);
  95 }
  96 
  97 static 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 
 103 static 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 
 112 static 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 
 120 static 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 
 128 static 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 
 144 static 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 
 157 static 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 
 166 static 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 
 177 retry:
 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 
 218 static 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 
 395 static 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 
 543 static 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 
 567 static 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 
 592 static 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 
 632 static 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 
 644 static 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 
 664 static 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 
 673 static 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 
 685 static 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 
 694 static const char * const hdmi_pll_parents[] = {
 695         "xo",
 696 };
 697 
 698 static 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 
 706 int 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", "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], label[32];
 727 
 728                 snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
 729                 snprintf(label, sizeof(label), "HDMI_TX_L%d", i);
 730 
 731                 pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name, label);
 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         clk = devm_clk_register(dev, &pll->clk_hw);
 740         if (IS_ERR(clk)) {
 741                 DRM_DEV_ERROR(dev, "failed to register pll clock\n");
 742                 return -EINVAL;
 743         }
 744 
 745         return 0;
 746 }
 747 
 748 static const char * const hdmi_phy_8996_reg_names[] = {
 749         "vddio",
 750         "vcca",
 751 };
 752 
 753 static const char * const hdmi_phy_8996_clk_names[] = {
 754         "iface", "ref",
 755 };
 756 
 757 const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = {
 758         .type = MSM_HDMI_PHY_8996,
 759         .reg_names = hdmi_phy_8996_reg_names,
 760         .num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names),
 761         .clk_names = hdmi_phy_8996_clk_names,
 762         .num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names),
 763 };

/* [<][>][^][v][top][bottom][index][help] */