root/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c

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

DEFINITIONS

This source file includes following definitions.
  1. mtk_hdmi_pll_prepare
  2. mtk_hdmi_pll_unprepare
  3. mtk_hdmi_pll_round_rate
  4. mtk_hdmi_pll_set_rate
  5. mtk_hdmi_pll_recalc_rate
  6. mtk_hdmi_phy_enable_tmds
  7. mtk_hdmi_phy_disable_tmds

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2014 MediaTek Inc.
   4  * Author: Jie Qiu <jie.qiu@mediatek.com>
   5  */
   6 
   7 #include "mtk_hdmi_phy.h"
   8 
   9 #define HDMI_CON0               0x00
  10 #define RG_HDMITX_PLL_EN                BIT(31)
  11 #define RG_HDMITX_PLL_FBKDIV            (0x7f << 24)
  12 #define PLL_FBKDIV_SHIFT                24
  13 #define RG_HDMITX_PLL_FBKSEL            (0x3 << 22)
  14 #define PLL_FBKSEL_SHIFT                22
  15 #define RG_HDMITX_PLL_PREDIV            (0x3 << 20)
  16 #define PREDIV_SHIFT                    20
  17 #define RG_HDMITX_PLL_POSDIV            (0x3 << 18)
  18 #define POSDIV_SHIFT                    18
  19 #define RG_HDMITX_PLL_RST_DLY           (0x3 << 16)
  20 #define RG_HDMITX_PLL_IR                (0xf << 12)
  21 #define PLL_IR_SHIFT                    12
  22 #define RG_HDMITX_PLL_IC                (0xf << 8)
  23 #define PLL_IC_SHIFT                    8
  24 #define RG_HDMITX_PLL_BP                (0xf << 4)
  25 #define PLL_BP_SHIFT                    4
  26 #define RG_HDMITX_PLL_BR                (0x3 << 2)
  27 #define PLL_BR_SHIFT                    2
  28 #define RG_HDMITX_PLL_BC                (0x3 << 0)
  29 #define PLL_BC_SHIFT                    0
  30 #define HDMI_CON1               0x04
  31 #define RG_HDMITX_PLL_DIVEN             (0x7 << 29)
  32 #define PLL_DIVEN_SHIFT                 29
  33 #define RG_HDMITX_PLL_AUTOK_EN          BIT(28)
  34 #define RG_HDMITX_PLL_AUTOK_KF          (0x3 << 26)
  35 #define RG_HDMITX_PLL_AUTOK_KS          (0x3 << 24)
  36 #define RG_HDMITX_PLL_AUTOK_LOAD        BIT(23)
  37 #define RG_HDMITX_PLL_BAND              (0x3f << 16)
  38 #define RG_HDMITX_PLL_REF_SEL           BIT(15)
  39 #define RG_HDMITX_PLL_BIAS_EN           BIT(14)
  40 #define RG_HDMITX_PLL_BIAS_LPF_EN       BIT(13)
  41 #define RG_HDMITX_PLL_TXDIV_EN          BIT(12)
  42 #define RG_HDMITX_PLL_TXDIV             (0x3 << 10)
  43 #define PLL_TXDIV_SHIFT                 10
  44 #define RG_HDMITX_PLL_LVROD_EN          BIT(9)
  45 #define RG_HDMITX_PLL_MONVC_EN          BIT(8)
  46 #define RG_HDMITX_PLL_MONCK_EN          BIT(7)
  47 #define RG_HDMITX_PLL_MONREF_EN         BIT(6)
  48 #define RG_HDMITX_PLL_TST_EN            BIT(5)
  49 #define RG_HDMITX_PLL_TST_CK_EN         BIT(4)
  50 #define RG_HDMITX_PLL_TST_SEL           (0xf << 0)
  51 #define HDMI_CON2               0x08
  52 #define RGS_HDMITX_PLL_AUTOK_BAND       (0x7f << 8)
  53 #define RGS_HDMITX_PLL_AUTOK_FAIL       BIT(1)
  54 #define RG_HDMITX_EN_TX_CKLDO           BIT(0)
  55 #define HDMI_CON3               0x0c
  56 #define RG_HDMITX_SER_EN                (0xf << 28)
  57 #define RG_HDMITX_PRD_EN                (0xf << 24)
  58 #define RG_HDMITX_PRD_IMP_EN            (0xf << 20)
  59 #define RG_HDMITX_DRV_EN                (0xf << 16)
  60 #define RG_HDMITX_DRV_IMP_EN            (0xf << 12)
  61 #define DRV_IMP_EN_SHIFT                12
  62 #define RG_HDMITX_MHLCK_FORCE           BIT(10)
  63 #define RG_HDMITX_MHLCK_PPIX_EN         BIT(9)
  64 #define RG_HDMITX_MHLCK_EN              BIT(8)
  65 #define RG_HDMITX_SER_DIN_SEL           (0xf << 4)
  66 #define RG_HDMITX_SER_5T1_BIST_EN       BIT(3)
  67 #define RG_HDMITX_SER_BIST_TOG          BIT(2)
  68 #define RG_HDMITX_SER_DIN_TOG           BIT(1)
  69 #define RG_HDMITX_SER_CLKDIG_INV        BIT(0)
  70 #define HDMI_CON4               0x10
  71 #define RG_HDMITX_PRD_IBIAS_CLK         (0xf << 24)
  72 #define RG_HDMITX_PRD_IBIAS_D2          (0xf << 16)
  73 #define RG_HDMITX_PRD_IBIAS_D1          (0xf << 8)
  74 #define RG_HDMITX_PRD_IBIAS_D0          (0xf << 0)
  75 #define PRD_IBIAS_CLK_SHIFT             24
  76 #define PRD_IBIAS_D2_SHIFT              16
  77 #define PRD_IBIAS_D1_SHIFT              8
  78 #define PRD_IBIAS_D0_SHIFT              0
  79 #define HDMI_CON5               0x14
  80 #define RG_HDMITX_DRV_IBIAS_CLK         (0x3f << 24)
  81 #define RG_HDMITX_DRV_IBIAS_D2          (0x3f << 16)
  82 #define RG_HDMITX_DRV_IBIAS_D1          (0x3f << 8)
  83 #define RG_HDMITX_DRV_IBIAS_D0          (0x3f << 0)
  84 #define DRV_IBIAS_CLK_SHIFT             24
  85 #define DRV_IBIAS_D2_SHIFT              16
  86 #define DRV_IBIAS_D1_SHIFT              8
  87 #define DRV_IBIAS_D0_SHIFT              0
  88 #define HDMI_CON6               0x18
  89 #define RG_HDMITX_DRV_IMP_CLK           (0x3f << 24)
  90 #define RG_HDMITX_DRV_IMP_D2            (0x3f << 16)
  91 #define RG_HDMITX_DRV_IMP_D1            (0x3f << 8)
  92 #define RG_HDMITX_DRV_IMP_D0            (0x3f << 0)
  93 #define DRV_IMP_CLK_SHIFT               24
  94 #define DRV_IMP_D2_SHIFT                16
  95 #define DRV_IMP_D1_SHIFT                8
  96 #define DRV_IMP_D0_SHIFT                0
  97 #define HDMI_CON7               0x1c
  98 #define RG_HDMITX_MHLCK_DRV_IBIAS       (0x1f << 27)
  99 #define RG_HDMITX_SER_DIN               (0x3ff << 16)
 100 #define RG_HDMITX_CHLDC_TST             (0xf << 12)
 101 #define RG_HDMITX_CHLCK_TST             (0xf << 8)
 102 #define RG_HDMITX_RESERVE               (0xff << 0)
 103 #define HDMI_CON8               0x20
 104 #define RGS_HDMITX_2T1_LEV              (0xf << 16)
 105 #define RGS_HDMITX_2T1_EDG              (0xf << 12)
 106 #define RGS_HDMITX_5T1_LEV              (0xf << 8)
 107 #define RGS_HDMITX_5T1_EDG              (0xf << 4)
 108 #define RGS_HDMITX_PLUG_TST             BIT(0)
 109 
 110 static const u8 PREDIV[3][4] = {
 111         {0x0, 0x0, 0x0, 0x0},   /* 27Mhz */
 112         {0x1, 0x1, 0x1, 0x1},   /* 74Mhz */
 113         {0x1, 0x1, 0x1, 0x1}    /* 148Mhz */
 114 };
 115 
 116 static const u8 TXDIV[3][4] = {
 117         {0x3, 0x3, 0x3, 0x2},   /* 27Mhz */
 118         {0x2, 0x1, 0x1, 0x1},   /* 74Mhz */
 119         {0x1, 0x0, 0x0, 0x0}    /* 148Mhz */
 120 };
 121 
 122 static const u8 FBKSEL[3][4] = {
 123         {0x1, 0x1, 0x1, 0x1},   /* 27Mhz */
 124         {0x1, 0x0, 0x1, 0x1},   /* 74Mhz */
 125         {0x1, 0x0, 0x1, 0x1}    /* 148Mhz */
 126 };
 127 
 128 static const u8 FBKDIV[3][4] = {
 129         {19, 24, 29, 19},       /* 27Mhz */
 130         {19, 24, 14, 19},       /* 74Mhz */
 131         {19, 24, 14, 19}        /* 148Mhz */
 132 };
 133 
 134 static const u8 DIVEN[3][4] = {
 135         {0x2, 0x1, 0x1, 0x2},   /* 27Mhz */
 136         {0x2, 0x2, 0x2, 0x2},   /* 74Mhz */
 137         {0x2, 0x2, 0x2, 0x2}    /* 148Mhz */
 138 };
 139 
 140 static const u8 HTPLLBP[3][4] = {
 141         {0xc, 0xc, 0x8, 0xc},   /* 27Mhz */
 142         {0xc, 0xf, 0xf, 0xc},   /* 74Mhz */
 143         {0xc, 0xf, 0xf, 0xc}    /* 148Mhz */
 144 };
 145 
 146 static const u8 HTPLLBC[3][4] = {
 147         {0x2, 0x3, 0x3, 0x2},   /* 27Mhz */
 148         {0x2, 0x3, 0x3, 0x2},   /* 74Mhz */
 149         {0x2, 0x3, 0x3, 0x2}    /* 148Mhz */
 150 };
 151 
 152 static const u8 HTPLLBR[3][4] = {
 153         {0x1, 0x1, 0x0, 0x1},   /* 27Mhz */
 154         {0x1, 0x2, 0x2, 0x1},   /* 74Mhz */
 155         {0x1, 0x2, 0x2, 0x1}    /* 148Mhz */
 156 };
 157 
 158 static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
 159 {
 160         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 161 
 162         dev_dbg(hdmi_phy->dev, "%s\n", __func__);
 163 
 164         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
 165         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
 166         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_MHLCK_EN);
 167         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
 168         usleep_range(100, 150);
 169         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
 170         usleep_range(100, 150);
 171         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
 172         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
 173 
 174         return 0;
 175 }
 176 
 177 static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 178 {
 179         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 180 
 181         dev_dbg(hdmi_phy->dev, "%s\n", __func__);
 182 
 183         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
 184         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
 185         usleep_range(100, 150);
 186         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
 187         usleep_range(100, 150);
 188         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
 189         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
 190         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
 191         usleep_range(100, 150);
 192 }
 193 
 194 static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 195                                     unsigned long *parent_rate)
 196 {
 197         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 198 
 199         hdmi_phy->pll_rate = rate;
 200         if (rate <= 74250000)
 201                 *parent_rate = rate;
 202         else
 203                 *parent_rate = rate / 2;
 204 
 205         return rate;
 206 }
 207 
 208 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 209                                  unsigned long parent_rate)
 210 {
 211         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 212         unsigned int pre_div;
 213         unsigned int div;
 214         unsigned int pre_ibias;
 215         unsigned int hdmi_ibias;
 216         unsigned int imp_en;
 217 
 218         dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__,
 219                 rate, parent_rate);
 220 
 221         if (rate <= 27000000) {
 222                 pre_div = 0;
 223                 div = 3;
 224         } else if (rate <= 74250000) {
 225                 pre_div = 1;
 226                 div = 2;
 227         } else {
 228                 pre_div = 1;
 229                 div = 1;
 230         }
 231 
 232         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
 233                           (pre_div << PREDIV_SHIFT), RG_HDMITX_PLL_PREDIV);
 234         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
 235         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
 236                           (0x1 << PLL_IC_SHIFT) | (0x1 << PLL_IR_SHIFT),
 237                           RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR);
 238         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
 239                           (div << PLL_TXDIV_SHIFT), RG_HDMITX_PLL_TXDIV);
 240         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
 241                           (0x1 << PLL_FBKSEL_SHIFT) | (19 << PLL_FBKDIV_SHIFT),
 242                           RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV);
 243         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
 244                           (0x2 << PLL_DIVEN_SHIFT), RG_HDMITX_PLL_DIVEN);
 245         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
 246                           (0xc << PLL_BP_SHIFT) | (0x2 << PLL_BC_SHIFT) |
 247                           (0x1 << PLL_BR_SHIFT),
 248                           RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
 249                           RG_HDMITX_PLL_BR);
 250         if (rate < 165000000) {
 251                 mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
 252                                         RG_HDMITX_PRD_IMP_EN);
 253                 pre_ibias = 0x3;
 254                 imp_en = 0x0;
 255                 hdmi_ibias = hdmi_phy->ibias;
 256         } else {
 257                 mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
 258                                       RG_HDMITX_PRD_IMP_EN);
 259                 pre_ibias = 0x6;
 260                 imp_en = 0xf;
 261                 hdmi_ibias = hdmi_phy->ibias_up;
 262         }
 263         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
 264                           (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
 265                           (pre_ibias << PRD_IBIAS_D2_SHIFT) |
 266                           (pre_ibias << PRD_IBIAS_D1_SHIFT) |
 267                           (pre_ibias << PRD_IBIAS_D0_SHIFT),
 268                           RG_HDMITX_PRD_IBIAS_CLK |
 269                           RG_HDMITX_PRD_IBIAS_D2 |
 270                           RG_HDMITX_PRD_IBIAS_D1 |
 271                           RG_HDMITX_PRD_IBIAS_D0);
 272         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
 273                           (imp_en << DRV_IMP_EN_SHIFT),
 274                           RG_HDMITX_DRV_IMP_EN);
 275         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
 276                           (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
 277                           (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
 278                           (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
 279                           (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT),
 280                           RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
 281                           RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
 282         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
 283                           (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
 284                           (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
 285                           (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
 286                           (hdmi_ibias << DRV_IBIAS_D0_SHIFT),
 287                           RG_HDMITX_DRV_IBIAS_CLK |
 288                           RG_HDMITX_DRV_IBIAS_D2 |
 289                           RG_HDMITX_DRV_IBIAS_D1 |
 290                           RG_HDMITX_DRV_IBIAS_D0);
 291         return 0;
 292 }
 293 
 294 static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
 295                                               unsigned long parent_rate)
 296 {
 297         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 298 
 299         return hdmi_phy->pll_rate;
 300 }
 301 
 302 static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 303         .prepare = mtk_hdmi_pll_prepare,
 304         .unprepare = mtk_hdmi_pll_unprepare,
 305         .set_rate = mtk_hdmi_pll_set_rate,
 306         .round_rate = mtk_hdmi_pll_round_rate,
 307         .recalc_rate = mtk_hdmi_pll_recalc_rate,
 308 };
 309 
 310 static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
 311 {
 312         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
 313                               RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN |
 314                               RG_HDMITX_DRV_EN);
 315         usleep_range(100, 150);
 316 }
 317 
 318 static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
 319 {
 320         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
 321                                 RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN |
 322                                 RG_HDMITX_SER_EN);
 323 }
 324 
 325 struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = {
 326         .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
 327         .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
 328         .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
 329         .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
 330 };
 331 
 332 MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>");
 333 MODULE_DESCRIPTION("MediaTek MT8173 HDMI PHY Driver");
 334 MODULE_LICENSE("GPL v2");

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