Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2018 MediaTek Inc.
0004  * Author: Chunhui Dai <chunhui.dai@mediatek.com>
0005  */
0006 
0007 #include "phy-mtk-hdmi.h"
0008 
0009 #define HDMI_CON0   0x00
0010 #define RG_HDMITX_DRV_IBIAS     0
0011 #define RG_HDMITX_DRV_IBIAS_MASK    (0x3f << 0)
0012 #define RG_HDMITX_EN_SER        12
0013 #define RG_HDMITX_EN_SER_MASK       (0x0f << 12)
0014 #define RG_HDMITX_EN_SLDO       16
0015 #define RG_HDMITX_EN_SLDO_MASK      (0x0f << 16)
0016 #define RG_HDMITX_EN_PRED       20
0017 #define RG_HDMITX_EN_PRED_MASK      (0x0f << 20)
0018 #define RG_HDMITX_EN_IMP        24
0019 #define RG_HDMITX_EN_IMP_MASK       (0x0f << 24)
0020 #define RG_HDMITX_EN_DRV        28
0021 #define RG_HDMITX_EN_DRV_MASK       (0x0f << 28)
0022 
0023 #define HDMI_CON1   0x04
0024 #define RG_HDMITX_PRED_IBIAS        18
0025 #define RG_HDMITX_PRED_IBIAS_MASK   (0x0f << 18)
0026 #define RG_HDMITX_PRED_IMP      (0x01 << 22)
0027 #define RG_HDMITX_DRV_IMP       26
0028 #define RG_HDMITX_DRV_IMP_MASK      (0x3f << 26)
0029 
0030 #define HDMI_CON2   0x08
0031 #define RG_HDMITX_EN_TX_CKLDO       (0x01 << 0)
0032 #define RG_HDMITX_EN_TX_POSDIV      (0x01 << 1)
0033 #define RG_HDMITX_TX_POSDIV     3
0034 #define RG_HDMITX_TX_POSDIV_MASK    (0x03 << 3)
0035 #define RG_HDMITX_EN_MBIAS      (0x01 << 6)
0036 #define RG_HDMITX_MBIAS_LPF_EN      (0x01 << 7)
0037 
0038 #define HDMI_CON4   0x10
0039 #define RG_HDMITX_RESERVE_MASK      (0xffffffff << 0)
0040 
0041 #define HDMI_CON6   0x18
0042 #define RG_HTPLL_BR         0
0043 #define RG_HTPLL_BR_MASK        (0x03 << 0)
0044 #define RG_HTPLL_BC         2
0045 #define RG_HTPLL_BC_MASK        (0x03 << 2)
0046 #define RG_HTPLL_BP         4
0047 #define RG_HTPLL_BP_MASK        (0x0f << 4)
0048 #define RG_HTPLL_IR         8
0049 #define RG_HTPLL_IR_MASK        (0x0f << 8)
0050 #define RG_HTPLL_IC         12
0051 #define RG_HTPLL_IC_MASK        (0x0f << 12)
0052 #define RG_HTPLL_POSDIV         16
0053 #define RG_HTPLL_POSDIV_MASK        (0x03 << 16)
0054 #define RG_HTPLL_PREDIV         18
0055 #define RG_HTPLL_PREDIV_MASK        (0x03 << 18)
0056 #define RG_HTPLL_FBKSEL         20
0057 #define RG_HTPLL_FBKSEL_MASK        (0x03 << 20)
0058 #define RG_HTPLL_RLH_EN         (0x01 << 22)
0059 #define RG_HTPLL_FBKDIV         24
0060 #define RG_HTPLL_FBKDIV_MASK        (0x7f << 24)
0061 #define RG_HTPLL_EN         (0x01 << 31)
0062 
0063 #define HDMI_CON7   0x1c
0064 #define RG_HTPLL_AUTOK_EN       (0x01 << 23)
0065 #define RG_HTPLL_DIVEN          28
0066 #define RG_HTPLL_DIVEN_MASK     (0x07 << 28)
0067 
0068 static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
0069 {
0070     struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
0071 
0072     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
0073     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
0074     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
0075     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
0076     usleep_range(80, 100);
0077     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
0078     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
0079     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
0080     usleep_range(80, 100);
0081     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
0082     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
0083     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
0084     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
0085     usleep_range(80, 100);
0086     return 0;
0087 }
0088 
0089 static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
0090 {
0091     struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
0092 
0093     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
0094     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
0095     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
0096     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
0097     usleep_range(80, 100);
0098     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
0099     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
0100     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
0101     usleep_range(80, 100);
0102     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
0103     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
0104     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
0105     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
0106     usleep_range(80, 100);
0107 }
0108 
0109 static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
0110                     unsigned long *parent_rate)
0111 {
0112     return rate;
0113 }
0114 
0115 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
0116                  unsigned long parent_rate)
0117 {
0118     struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
0119     u32 pos_div;
0120 
0121     if (rate <= 64000000)
0122         pos_div = 3;
0123     else if (rate <= 128000000)
0124         pos_div = 2;
0125     else
0126         pos_div = 1;
0127 
0128     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
0129     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
0130     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
0131     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
0132               RG_HTPLL_IC_MASK);
0133     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
0134               RG_HTPLL_IR_MASK);
0135     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div << RG_HDMITX_TX_POSDIV),
0136               RG_HDMITX_TX_POSDIV_MASK);
0137     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL),
0138               RG_HTPLL_FBKSEL_MASK);
0139     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV),
0140               RG_HTPLL_FBKDIV_MASK);
0141     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN),
0142               RG_HTPLL_DIVEN_MASK);
0143     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP),
0144               RG_HTPLL_BP_MASK);
0145     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC),
0146               RG_HTPLL_BC_MASK);
0147     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR),
0148               RG_HTPLL_BR_MASK);
0149 
0150     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PRED_IMP);
0151     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 << RG_HDMITX_PRED_IBIAS),
0152               RG_HDMITX_PRED_IBIAS_MASK);
0153     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_IMP_MASK);
0154     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 << RG_HDMITX_DRV_IMP),
0155               RG_HDMITX_DRV_IMP_MASK);
0156     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28, RG_HDMITX_RESERVE_MASK);
0157     mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa << RG_HDMITX_DRV_IBIAS),
0158               RG_HDMITX_DRV_IBIAS_MASK);
0159     return 0;
0160 }
0161 
0162 static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
0163                           unsigned long parent_rate)
0164 {
0165     struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
0166     unsigned long out_rate, val;
0167 
0168     val = (readl(hdmi_phy->regs + HDMI_CON6)
0169            & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
0170     switch (val) {
0171     case 0x00:
0172         out_rate = parent_rate;
0173         break;
0174     case 0x01:
0175         out_rate = parent_rate / 2;
0176         break;
0177     default:
0178         out_rate = parent_rate / 4;
0179         break;
0180     }
0181 
0182     val = (readl(hdmi_phy->regs + HDMI_CON6)
0183            & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
0184     out_rate *= (val + 1) * 2;
0185     val = (readl(hdmi_phy->regs + HDMI_CON2)
0186            & RG_HDMITX_TX_POSDIV_MASK);
0187     out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
0188 
0189     if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
0190         out_rate /= 5;
0191 
0192     return out_rate;
0193 }
0194 
0195 static const struct clk_ops mtk_hdmi_phy_pll_ops = {
0196     .prepare = mtk_hdmi_pll_prepare,
0197     .unprepare = mtk_hdmi_pll_unprepare,
0198     .set_rate = mtk_hdmi_pll_set_rate,
0199     .round_rate = mtk_hdmi_pll_round_rate,
0200     .recalc_rate = mtk_hdmi_pll_recalc_rate,
0201 };
0202 
0203 static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
0204 {
0205     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
0206     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
0207     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
0208     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
0209     usleep_range(80, 100);
0210     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
0211     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
0212     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
0213     usleep_range(80, 100);
0214     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
0215     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
0216     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
0217     mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
0218     usleep_range(80, 100);
0219 }
0220 
0221 static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
0222 {
0223     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
0224     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
0225     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
0226     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
0227     usleep_range(80, 100);
0228     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
0229     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
0230     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
0231     usleep_range(80, 100);
0232     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
0233     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
0234     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
0235     mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
0236     usleep_range(80, 100);
0237 }
0238 
0239 struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = {
0240     .flags = CLK_SET_RATE_GATE,
0241     .pll_default_off = true,
0242     .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
0243     .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
0244     .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
0245 };
0246 
0247 MODULE_AUTHOR("Chunhui Dai <chunhui.dai@mediatek.com>");
0248 MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
0249 MODULE_LICENSE("GPL v2");