Merge back staging AVS changes for v4.21.
[sfrench/cifs-2.6.git] / drivers / gpu / drm / mediatek / mtk_mt2701_hdmi_phy.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018 MediaTek Inc.
4  * Author: Chunhui Dai <chunhui.dai@mediatek.com>
5  */
6
7 #include "mtk_hdmi_phy.h"
8
9 #define HDMI_CON0       0x00
10 #define RG_HDMITX_DRV_IBIAS             0
11 #define RG_HDMITX_DRV_IBIAS_MASK        (0x3f << 0)
12 #define RG_HDMITX_EN_SER                12
13 #define RG_HDMITX_EN_SER_MASK           (0x0f << 12)
14 #define RG_HDMITX_EN_SLDO               16
15 #define RG_HDMITX_EN_SLDO_MASK          (0x0f << 16)
16 #define RG_HDMITX_EN_PRED               20
17 #define RG_HDMITX_EN_PRED_MASK          (0x0f << 20)
18 #define RG_HDMITX_EN_IMP                24
19 #define RG_HDMITX_EN_IMP_MASK           (0x0f << 24)
20 #define RG_HDMITX_EN_DRV                28
21 #define RG_HDMITX_EN_DRV_MASK           (0x0f << 28)
22
23 #define HDMI_CON1       0x04
24 #define RG_HDMITX_PRED_IBIAS            18
25 #define RG_HDMITX_PRED_IBIAS_MASK       (0x0f << 18)
26 #define RG_HDMITX_PRED_IMP              (0x01 << 22)
27 #define RG_HDMITX_DRV_IMP               26
28 #define RG_HDMITX_DRV_IMP_MASK          (0x3f << 26)
29
30 #define HDMI_CON2       0x08
31 #define RG_HDMITX_EN_TX_CKLDO           (0x01 << 0)
32 #define RG_HDMITX_EN_TX_POSDIV          (0x01 << 1)
33 #define RG_HDMITX_TX_POSDIV             3
34 #define RG_HDMITX_TX_POSDIV_MASK        (0x03 << 3)
35 #define RG_HDMITX_EN_MBIAS              (0x01 << 6)
36 #define RG_HDMITX_MBIAS_LPF_EN          (0x01 << 7)
37
38 #define HDMI_CON4       0x10
39 #define RG_HDMITX_RESERVE_MASK          (0xffffffff << 0)
40
41 #define HDMI_CON6       0x18
42 #define RG_HTPLL_BR                     0
43 #define RG_HTPLL_BR_MASK                (0x03 << 0)
44 #define RG_HTPLL_BC                     2
45 #define RG_HTPLL_BC_MASK                (0x03 << 2)
46 #define RG_HTPLL_BP                     4
47 #define RG_HTPLL_BP_MASK                (0x0f << 4)
48 #define RG_HTPLL_IR                     8
49 #define RG_HTPLL_IR_MASK                (0x0f << 8)
50 #define RG_HTPLL_IC                     12
51 #define RG_HTPLL_IC_MASK                (0x0f << 12)
52 #define RG_HTPLL_POSDIV                 16
53 #define RG_HTPLL_POSDIV_MASK            (0x03 << 16)
54 #define RG_HTPLL_PREDIV                 18
55 #define RG_HTPLL_PREDIV_MASK            (0x03 << 18)
56 #define RG_HTPLL_FBKSEL                 20
57 #define RG_HTPLL_FBKSEL_MASK            (0x03 << 20)
58 #define RG_HTPLL_RLH_EN                 (0x01 << 22)
59 #define RG_HTPLL_FBKDIV                 24
60 #define RG_HTPLL_FBKDIV_MASK            (0x7f << 24)
61 #define RG_HTPLL_EN                     (0x01 << 31)
62
63 #define HDMI_CON7       0x1c
64 #define RG_HTPLL_AUTOK_EN               (0x01 << 23)
65 #define RG_HTPLL_DIVEN                  28
66 #define RG_HTPLL_DIVEN_MASK             (0x07 << 28)
67
68 static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
69 {
70         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
71
72         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
73         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
74         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
75         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
76         usleep_range(80, 100);
77         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
78         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
79         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
80         usleep_range(80, 100);
81         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
82         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
83         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
84         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
85         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
86         usleep_range(80, 100);
87         return 0;
88 }
89
90 static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
91 {
92         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
93
94         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
95         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
96         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
97         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
98         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
99         usleep_range(80, 100);
100         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
101         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
102         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
103         usleep_range(80, 100);
104         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
105         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
106         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
107         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
108         usleep_range(80, 100);
109 }
110
111 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
112                                  unsigned long parent_rate)
113 {
114         struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
115         u32 pos_div;
116
117         if (rate <= 64000000)
118                 pos_div = 3;
119         else if (rate <= 12800000)
120                 pos_div = 1;
121         else
122                 pos_div = 1;
123
124         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
125         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
126         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
127                           RG_HTPLL_IC_MASK);
128         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
129                           RG_HTPLL_IR_MASK);
130         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div << RG_HDMITX_TX_POSDIV),
131                           RG_HDMITX_TX_POSDIV_MASK);
132         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL),
133                           RG_HTPLL_FBKSEL_MASK);
134         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV),
135                           RG_HTPLL_FBKDIV_MASK);
136         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN),
137                           RG_HTPLL_DIVEN_MASK);
138         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP),
139                           RG_HTPLL_BP_MASK);
140         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC),
141                           RG_HTPLL_BC_MASK);
142         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR),
143                           RG_HTPLL_BR_MASK);
144
145         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PRED_IMP);
146         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 << RG_HDMITX_PRED_IBIAS),
147                           RG_HDMITX_PRED_IBIAS_MASK);
148         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_IMP_MASK);
149         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 << RG_HDMITX_DRV_IMP),
150                           RG_HDMITX_DRV_IMP_MASK);
151         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28, RG_HDMITX_RESERVE_MASK);
152         mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa << RG_HDMITX_DRV_IBIAS),
153                           RG_HDMITX_DRV_IBIAS_MASK);
154         return 0;
155 }
156
157 static const struct clk_ops mtk_hdmi_phy_pll_ops = {
158         .prepare = mtk_hdmi_pll_prepare,
159         .unprepare = mtk_hdmi_pll_unprepare,
160         .set_rate = mtk_hdmi_pll_set_rate,
161         .round_rate = mtk_hdmi_pll_round_rate,
162         .recalc_rate = mtk_hdmi_pll_recalc_rate,
163 };
164
165 static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
166 {
167         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
168         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
169         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
170         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
171         usleep_range(80, 100);
172         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
173         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
174         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
175         usleep_range(80, 100);
176         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
177         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
178         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
179         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
180         mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
181         usleep_range(80, 100);
182 }
183
184 static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
185 {
186         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
187         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
188         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
189         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
190         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
191         usleep_range(80, 100);
192         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
193         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
194         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
195         usleep_range(80, 100);
196         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
197         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
198         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
199         mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
200         usleep_range(80, 100);
201 }
202
203 struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = {
204         .tz_disabled = true,
205         .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
206         .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
207         .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
208 };
209
210 MODULE_AUTHOR("Chunhui Dai <chunhui.dai@mediatek.com>");
211 MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
212 MODULE_LICENSE("GPL v2");