Skip to content

Commit 0fc721b

Browse files
chunhui daickhu-mediatek
authored andcommitted
drm/mediatek: add hdmi driver for MT2701 and MT7623
This patch adds hdmi dirver suppot for both MT2701 and MT7623. And also support other (existing or future) chips that use the same binding and driver. Signed-off-by: chunhui dai <[email protected]> Signed-off-by: CK Hu <[email protected]>
1 parent d1ef028 commit 0fc721b

File tree

5 files changed

+226
-3
lines changed

5 files changed

+226
-3
lines changed

drivers/gpu/drm/mediatek/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
1919
mediatek-drm-hdmi-objs := mtk_cec.o \
2020
mtk_hdmi.o \
2121
mtk_hdmi_ddc.o \
22+
mtk_mt2701_hdmi_phy.o \
2223
mtk_mt8173_hdmi_phy.o \
2324
mtk_hdmi_phy.o
2425

25-
obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
26+
obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o

drivers/gpu/drm/mediatek/mtk_hdmi.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,13 @@ static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable)
241241
* The ARM trusted firmware provides an API for the HDMI driver to set
242242
* this control bit to enable HDMI output in supervisor mode.
243243
*/
244-
arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904, 0x80000000,
245-
0, 0, 0, 0, 0, &res);
244+
if (hdmi_phy->conf && hdmi_phy->conf->tz_disabled)
245+
regmap_update_bits(hdmi->sys_regmap,
246+
hdmi->sys_offset + HDMI_SYS_CFG20,
247+
0x80008005, enable ? 0x80000005 : 0x8000);
248+
else
249+
arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904,
250+
0x80000000, 0, 0, 0, 0, 0, &res);
246251

247252
regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,
248253
HDMI_PCLK_FREE_RUN, enable ? HDMI_PCLK_FREE_RUN : 0);

drivers/gpu/drm/mediatek/mtk_hdmi_phy.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
214214
}
215215

216216
static const struct of_device_id mtk_hdmi_phy_match[] = {
217+
{ .compatible = "mediatek,mt2701-hdmi-phy",
218+
.data = &mtk_hdmi_phy_2701_conf,
219+
},
217220
{ .compatible = "mediatek,mt8173-hdmi-phy",
218221
.data = &mtk_hdmi_phy_8173_conf,
219222
},

drivers/gpu/drm/mediatek/mtk_hdmi_phy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
struct mtk_hdmi_phy;
2121

2222
struct mtk_hdmi_phy_conf {
23+
bool tz_disabled;
2324
const struct clk_ops *hdmi_phy_clk_ops;
2425
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
2526
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
@@ -54,5 +55,6 @@ unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
5455

5556
extern struct platform_driver mtk_hdmi_phy_driver;
5657
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
58+
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
5759

5860
#endif /* _MTK_HDMI_PHY_H */
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2018 MediaTek Inc.
4+
* Author: Chunhui Dai <[email protected]>
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 <[email protected]>");
211+
MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
212+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)