• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2014 MediaTek Inc.
3  * Author: Jie Qiu <jie.qiu@mediatek.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 
15 #include <linux/clk.h>
16 #include <linux/clk-provider.h>
17 #include <linux/delay.h>
18 #include <linux/io.h>
19 #include <linux/mfd/syscon.h>
20 #include <linux/module.h>
21 #include <linux/phy/phy.h>
22 #include <linux/platform_device.h>
23 #include <linux/types.h>
24 
25 #define HDMI_CON0		0x00
26 #define RG_HDMITX_PLL_EN		BIT(31)
27 #define RG_HDMITX_PLL_FBKDIV		(0x7f << 24)
28 #define PLL_FBKDIV_SHIFT		24
29 #define RG_HDMITX_PLL_FBKSEL		(0x3 << 22)
30 #define PLL_FBKSEL_SHIFT		22
31 #define RG_HDMITX_PLL_PREDIV		(0x3 << 20)
32 #define PREDIV_SHIFT			20
33 #define RG_HDMITX_PLL_POSDIV		(0x3 << 18)
34 #define POSDIV_SHIFT			18
35 #define RG_HDMITX_PLL_RST_DLY		(0x3 << 16)
36 #define RG_HDMITX_PLL_IR		(0xf << 12)
37 #define PLL_IR_SHIFT			12
38 #define RG_HDMITX_PLL_IC		(0xf << 8)
39 #define PLL_IC_SHIFT			8
40 #define RG_HDMITX_PLL_BP		(0xf << 4)
41 #define PLL_BP_SHIFT			4
42 #define RG_HDMITX_PLL_BR		(0x3 << 2)
43 #define PLL_BR_SHIFT			2
44 #define RG_HDMITX_PLL_BC		(0x3 << 0)
45 #define PLL_BC_SHIFT			0
46 #define HDMI_CON1		0x04
47 #define RG_HDMITX_PLL_DIVEN		(0x7 << 29)
48 #define PLL_DIVEN_SHIFT			29
49 #define RG_HDMITX_PLL_AUTOK_EN		BIT(28)
50 #define RG_HDMITX_PLL_AUTOK_KF		(0x3 << 26)
51 #define RG_HDMITX_PLL_AUTOK_KS		(0x3 << 24)
52 #define RG_HDMITX_PLL_AUTOK_LOAD	BIT(23)
53 #define RG_HDMITX_PLL_BAND		(0x3f << 16)
54 #define RG_HDMITX_PLL_REF_SEL		BIT(15)
55 #define RG_HDMITX_PLL_BIAS_EN		BIT(14)
56 #define RG_HDMITX_PLL_BIAS_LPF_EN	BIT(13)
57 #define RG_HDMITX_PLL_TXDIV_EN		BIT(12)
58 #define RG_HDMITX_PLL_TXDIV		(0x3 << 10)
59 #define PLL_TXDIV_SHIFT			10
60 #define RG_HDMITX_PLL_LVROD_EN		BIT(9)
61 #define RG_HDMITX_PLL_MONVC_EN		BIT(8)
62 #define RG_HDMITX_PLL_MONCK_EN		BIT(7)
63 #define RG_HDMITX_PLL_MONREF_EN		BIT(6)
64 #define RG_HDMITX_PLL_TST_EN		BIT(5)
65 #define RG_HDMITX_PLL_TST_CK_EN		BIT(4)
66 #define RG_HDMITX_PLL_TST_SEL		(0xf << 0)
67 #define HDMI_CON2		0x08
68 #define RGS_HDMITX_PLL_AUTOK_BAND	(0x7f << 8)
69 #define RGS_HDMITX_PLL_AUTOK_FAIL	BIT(1)
70 #define RG_HDMITX_EN_TX_CKLDO		BIT(0)
71 #define HDMI_CON3		0x0c
72 #define RG_HDMITX_SER_EN		(0xf << 28)
73 #define RG_HDMITX_PRD_EN		(0xf << 24)
74 #define RG_HDMITX_PRD_IMP_EN		(0xf << 20)
75 #define RG_HDMITX_DRV_EN		(0xf << 16)
76 #define RG_HDMITX_DRV_IMP_EN		(0xf << 12)
77 #define DRV_IMP_EN_SHIFT		12
78 #define RG_HDMITX_MHLCK_FORCE		BIT(10)
79 #define RG_HDMITX_MHLCK_PPIX_EN		BIT(9)
80 #define RG_HDMITX_MHLCK_EN		BIT(8)
81 #define RG_HDMITX_SER_DIN_SEL		(0xf << 4)
82 #define RG_HDMITX_SER_5T1_BIST_EN	BIT(3)
83 #define RG_HDMITX_SER_BIST_TOG		BIT(2)
84 #define RG_HDMITX_SER_DIN_TOG		BIT(1)
85 #define RG_HDMITX_SER_CLKDIG_INV	BIT(0)
86 #define HDMI_CON4		0x10
87 #define RG_HDMITX_PRD_IBIAS_CLK		(0xf << 24)
88 #define RG_HDMITX_PRD_IBIAS_D2		(0xf << 16)
89 #define RG_HDMITX_PRD_IBIAS_D1		(0xf << 8)
90 #define RG_HDMITX_PRD_IBIAS_D0		(0xf << 0)
91 #define PRD_IBIAS_CLK_SHIFT		24
92 #define PRD_IBIAS_D2_SHIFT		16
93 #define PRD_IBIAS_D1_SHIFT		8
94 #define PRD_IBIAS_D0_SHIFT		0
95 #define HDMI_CON5		0x14
96 #define RG_HDMITX_DRV_IBIAS_CLK		(0x3f << 24)
97 #define RG_HDMITX_DRV_IBIAS_D2		(0x3f << 16)
98 #define RG_HDMITX_DRV_IBIAS_D1		(0x3f << 8)
99 #define RG_HDMITX_DRV_IBIAS_D0		(0x3f << 0)
100 #define DRV_IBIAS_CLK_SHIFT		24
101 #define DRV_IBIAS_D2_SHIFT		16
102 #define DRV_IBIAS_D1_SHIFT		8
103 #define DRV_IBIAS_D0_SHIFT		0
104 #define HDMI_CON6		0x18
105 #define RG_HDMITX_DRV_IMP_CLK		(0x3f << 24)
106 #define RG_HDMITX_DRV_IMP_D2		(0x3f << 16)
107 #define RG_HDMITX_DRV_IMP_D1		(0x3f << 8)
108 #define RG_HDMITX_DRV_IMP_D0		(0x3f << 0)
109 #define DRV_IMP_CLK_SHIFT		24
110 #define DRV_IMP_D2_SHIFT		16
111 #define DRV_IMP_D1_SHIFT		8
112 #define DRV_IMP_D0_SHIFT		0
113 #define HDMI_CON7		0x1c
114 #define RG_HDMITX_MHLCK_DRV_IBIAS	(0x1f << 27)
115 #define RG_HDMITX_SER_DIN		(0x3ff << 16)
116 #define RG_HDMITX_CHLDC_TST		(0xf << 12)
117 #define RG_HDMITX_CHLCK_TST		(0xf << 8)
118 #define RG_HDMITX_RESERVE		(0xff << 0)
119 #define HDMI_CON8		0x20
120 #define RGS_HDMITX_2T1_LEV		(0xf << 16)
121 #define RGS_HDMITX_2T1_EDG		(0xf << 12)
122 #define RGS_HDMITX_5T1_LEV		(0xf << 8)
123 #define RGS_HDMITX_5T1_EDG		(0xf << 4)
124 #define RGS_HDMITX_PLUG_TST		BIT(0)
125 
126 struct mtk_hdmi_phy {
127 	void __iomem *regs;
128 	struct device *dev;
129 	struct clk *pll;
130 	struct clk_hw pll_hw;
131 	unsigned long pll_rate;
132 	u8 drv_imp_clk;
133 	u8 drv_imp_d2;
134 	u8 drv_imp_d1;
135 	u8 drv_imp_d0;
136 	u32 ibias;
137 	u32 ibias_up;
138 };
139 
140 static const u8 PREDIV[3][4] = {
141 	{0x0, 0x0, 0x0, 0x0},	/* 27Mhz */
142 	{0x1, 0x1, 0x1, 0x1},	/* 74Mhz */
143 	{0x1, 0x1, 0x1, 0x1}	/* 148Mhz */
144 };
145 
146 static const u8 TXDIV[3][4] = {
147 	{0x3, 0x3, 0x3, 0x2},	/* 27Mhz */
148 	{0x2, 0x1, 0x1, 0x1},	/* 74Mhz */
149 	{0x1, 0x0, 0x0, 0x0}	/* 148Mhz */
150 };
151 
152 static const u8 FBKSEL[3][4] = {
153 	{0x1, 0x1, 0x1, 0x1},	/* 27Mhz */
154 	{0x1, 0x0, 0x1, 0x1},	/* 74Mhz */
155 	{0x1, 0x0, 0x1, 0x1}	/* 148Mhz */
156 };
157 
158 static const u8 FBKDIV[3][4] = {
159 	{19, 24, 29, 19},	/* 27Mhz */
160 	{19, 24, 14, 19},	/* 74Mhz */
161 	{19, 24, 14, 19}	/* 148Mhz */
162 };
163 
164 static const u8 DIVEN[3][4] = {
165 	{0x2, 0x1, 0x1, 0x2},	/* 27Mhz */
166 	{0x2, 0x2, 0x2, 0x2},	/* 74Mhz */
167 	{0x2, 0x2, 0x2, 0x2}	/* 148Mhz */
168 };
169 
170 static const u8 HTPLLBP[3][4] = {
171 	{0xc, 0xc, 0x8, 0xc},	/* 27Mhz */
172 	{0xc, 0xf, 0xf, 0xc},	/* 74Mhz */
173 	{0xc, 0xf, 0xf, 0xc}	/* 148Mhz */
174 };
175 
176 static const u8 HTPLLBC[3][4] = {
177 	{0x2, 0x3, 0x3, 0x2},	/* 27Mhz */
178 	{0x2, 0x3, 0x3, 0x2},	/* 74Mhz */
179 	{0x2, 0x3, 0x3, 0x2}	/* 148Mhz */
180 };
181 
182 static const u8 HTPLLBR[3][4] = {
183 	{0x1, 0x1, 0x0, 0x1},	/* 27Mhz */
184 	{0x1, 0x2, 0x2, 0x1},	/* 74Mhz */
185 	{0x1, 0x2, 0x2, 0x1}	/* 148Mhz */
186 };
187 
mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy * hdmi_phy,u32 offset,u32 bits)188 static void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
189 				    u32 bits)
190 {
191 	void __iomem *reg = hdmi_phy->regs + offset;
192 	u32 tmp;
193 
194 	tmp = readl(reg);
195 	tmp &= ~bits;
196 	writel(tmp, reg);
197 }
198 
mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy * hdmi_phy,u32 offset,u32 bits)199 static void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
200 				  u32 bits)
201 {
202 	void __iomem *reg = hdmi_phy->regs + offset;
203 	u32 tmp;
204 
205 	tmp = readl(reg);
206 	tmp |= bits;
207 	writel(tmp, reg);
208 }
209 
mtk_hdmi_phy_mask(struct mtk_hdmi_phy * hdmi_phy,u32 offset,u32 val,u32 mask)210 static void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
211 			      u32 val, u32 mask)
212 {
213 	void __iomem *reg = hdmi_phy->regs + offset;
214 	u32 tmp;
215 
216 	tmp = readl(reg);
217 	tmp = (tmp & ~mask) | (val & mask);
218 	writel(tmp, reg);
219 }
220 
to_mtk_hdmi_phy(struct clk_hw * hw)221 static inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
222 {
223 	return container_of(hw, struct mtk_hdmi_phy, pll_hw);
224 }
225 
mtk_hdmi_pll_prepare(struct clk_hw * hw)226 static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
227 {
228 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
229 
230 	dev_dbg(hdmi_phy->dev, "%s\n", __func__);
231 
232 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
233 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
234 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_MHLCK_EN);
235 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
236 	usleep_range(100, 150);
237 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
238 	usleep_range(100, 150);
239 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
240 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
241 
242 	return 0;
243 }
244 
mtk_hdmi_pll_unprepare(struct clk_hw * hw)245 static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
246 {
247 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
248 
249 	dev_dbg(hdmi_phy->dev, "%s\n", __func__);
250 
251 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
252 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
253 	usleep_range(100, 150);
254 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
255 	usleep_range(100, 150);
256 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
257 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
258 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
259 	usleep_range(100, 150);
260 }
261 
mtk_hdmi_pll_set_rate(struct clk_hw * hw,unsigned long rate,unsigned long parent_rate)262 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
263 				 unsigned long parent_rate)
264 {
265 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
266 	unsigned int pre_div;
267 	unsigned int div;
268 	unsigned int pre_ibias;
269 	unsigned int hdmi_ibias;
270 	unsigned int imp_en;
271 
272 	dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__,
273 		rate, parent_rate);
274 
275 	if (rate <= 27000000) {
276 		pre_div = 0;
277 		div = 3;
278 	} else if (rate <= 74250000) {
279 		pre_div = 1;
280 		div = 2;
281 	} else {
282 		pre_div = 1;
283 		div = 1;
284 	}
285 
286 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
287 			  (pre_div << PREDIV_SHIFT), RG_HDMITX_PLL_PREDIV);
288 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
289 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
290 			  (0x1 << PLL_IC_SHIFT) | (0x1 << PLL_IR_SHIFT),
291 			  RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR);
292 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
293 			  (div << PLL_TXDIV_SHIFT), RG_HDMITX_PLL_TXDIV);
294 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
295 			  (0x1 << PLL_FBKSEL_SHIFT) | (19 << PLL_FBKDIV_SHIFT),
296 			  RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV);
297 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
298 			  (0x2 << PLL_DIVEN_SHIFT), RG_HDMITX_PLL_DIVEN);
299 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
300 			  (0xc << PLL_BP_SHIFT) | (0x2 << PLL_BC_SHIFT) |
301 			  (0x1 << PLL_BR_SHIFT),
302 			  RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
303 			  RG_HDMITX_PLL_BR);
304 	if (rate < 165000000) {
305 		mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
306 					RG_HDMITX_PRD_IMP_EN);
307 		pre_ibias = 0x3;
308 		imp_en = 0x0;
309 		hdmi_ibias = hdmi_phy->ibias;
310 	} else {
311 		mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
312 				      RG_HDMITX_PRD_IMP_EN);
313 		pre_ibias = 0x6;
314 		imp_en = 0xf;
315 		hdmi_ibias = hdmi_phy->ibias_up;
316 	}
317 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
318 			  (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
319 			  (pre_ibias << PRD_IBIAS_D2_SHIFT) |
320 			  (pre_ibias << PRD_IBIAS_D1_SHIFT) |
321 			  (pre_ibias << PRD_IBIAS_D0_SHIFT),
322 			  RG_HDMITX_PRD_IBIAS_CLK |
323 			  RG_HDMITX_PRD_IBIAS_D2 |
324 			  RG_HDMITX_PRD_IBIAS_D1 |
325 			  RG_HDMITX_PRD_IBIAS_D0);
326 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
327 			  (imp_en << DRV_IMP_EN_SHIFT),
328 			  RG_HDMITX_DRV_IMP_EN);
329 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
330 			  (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
331 			  (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
332 			  (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
333 			  (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT),
334 			  RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
335 			  RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
336 	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
337 			  (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
338 			  (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
339 			  (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
340 			  (hdmi_ibias << DRV_IBIAS_D0_SHIFT),
341 			  RG_HDMITX_DRV_IBIAS_CLK |
342 			  RG_HDMITX_DRV_IBIAS_D2 |
343 			  RG_HDMITX_DRV_IBIAS_D1 |
344 			  RG_HDMITX_DRV_IBIAS_D0);
345 	return 0;
346 }
347 
mtk_hdmi_pll_round_rate(struct clk_hw * hw,unsigned long rate,unsigned long * parent_rate)348 static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
349 				    unsigned long *parent_rate)
350 {
351 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
352 
353 	hdmi_phy->pll_rate = rate;
354 	if (rate <= 74250000)
355 		*parent_rate = rate;
356 	else
357 		*parent_rate = rate / 2;
358 
359 	return rate;
360 }
361 
mtk_hdmi_pll_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)362 static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
363 					      unsigned long parent_rate)
364 {
365 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
366 
367 	return hdmi_phy->pll_rate;
368 }
369 
370 static const struct clk_ops mtk_hdmi_pll_ops = {
371 	.prepare = mtk_hdmi_pll_prepare,
372 	.unprepare = mtk_hdmi_pll_unprepare,
373 	.set_rate = mtk_hdmi_pll_set_rate,
374 	.round_rate = mtk_hdmi_pll_round_rate,
375 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
376 };
377 
mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy * hdmi_phy)378 static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
379 {
380 	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
381 			      RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN |
382 			      RG_HDMITX_DRV_EN);
383 	usleep_range(100, 150);
384 }
385 
mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy * hdmi_phy)386 static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
387 {
388 	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
389 				RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN |
390 				RG_HDMITX_SER_EN);
391 }
392 
mtk_hdmi_phy_power_on(struct phy * phy)393 static int mtk_hdmi_phy_power_on(struct phy *phy)
394 {
395 	struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy);
396 	int ret;
397 
398 	ret = clk_prepare_enable(hdmi_phy->pll);
399 	if (ret < 0)
400 		return ret;
401 
402 	mtk_hdmi_phy_enable_tmds(hdmi_phy);
403 
404 	return 0;
405 }
406 
mtk_hdmi_phy_power_off(struct phy * phy)407 static int mtk_hdmi_phy_power_off(struct phy *phy)
408 {
409 	struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy);
410 
411 	mtk_hdmi_phy_disable_tmds(hdmi_phy);
412 	clk_disable_unprepare(hdmi_phy->pll);
413 
414 	return 0;
415 }
416 
417 static const struct phy_ops mtk_hdmi_phy_ops = {
418 	.power_on = mtk_hdmi_phy_power_on,
419 	.power_off = mtk_hdmi_phy_power_off,
420 	.owner = THIS_MODULE,
421 };
422 
mtk_hdmi_phy_probe(struct platform_device * pdev)423 static int mtk_hdmi_phy_probe(struct platform_device *pdev)
424 {
425 	struct device *dev = &pdev->dev;
426 	struct mtk_hdmi_phy *hdmi_phy;
427 	struct resource *mem;
428 	struct clk *ref_clk;
429 	const char *ref_clk_name;
430 	struct clk_init_data clk_init = {
431 		.ops = &mtk_hdmi_pll_ops,
432 		.num_parents = 1,
433 		.parent_names = (const char * const *)&ref_clk_name,
434 		.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
435 	};
436 	struct phy *phy;
437 	struct phy_provider *phy_provider;
438 	int ret;
439 
440 	hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL);
441 	if (!hdmi_phy)
442 		return -ENOMEM;
443 
444 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
445 	hdmi_phy->regs = devm_ioremap_resource(dev, mem);
446 	if (IS_ERR(hdmi_phy->regs)) {
447 		ret = PTR_ERR(hdmi_phy->regs);
448 		dev_err(dev, "Failed to get memory resource: %d\n", ret);
449 		return ret;
450 	}
451 
452 	ref_clk = devm_clk_get(dev, "pll_ref");
453 	if (IS_ERR(ref_clk)) {
454 		ret = PTR_ERR(ref_clk);
455 		dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n",
456 			ret);
457 		return ret;
458 	}
459 	ref_clk_name = __clk_get_name(ref_clk);
460 
461 	ret = of_property_read_string(dev->of_node, "clock-output-names",
462 				      &clk_init.name);
463 	if (ret < 0) {
464 		dev_err(dev, "Failed to read clock-output-names: %d\n", ret);
465 		return ret;
466 	}
467 
468 	hdmi_phy->pll_hw.init = &clk_init;
469 	hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
470 	if (IS_ERR(hdmi_phy->pll)) {
471 		ret = PTR_ERR(hdmi_phy->pll);
472 		dev_err(dev, "Failed to register PLL: %d\n", ret);
473 		return ret;
474 	}
475 
476 	ret = of_property_read_u32(dev->of_node, "mediatek,ibias",
477 				   &hdmi_phy->ibias);
478 	if (ret < 0) {
479 		dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret);
480 		return ret;
481 	}
482 
483 	ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up",
484 				   &hdmi_phy->ibias_up);
485 	if (ret < 0) {
486 		dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret);
487 		return ret;
488 	}
489 
490 	dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n");
491 	hdmi_phy->drv_imp_clk = 0x30;
492 	hdmi_phy->drv_imp_d2 = 0x30;
493 	hdmi_phy->drv_imp_d1 = 0x30;
494 	hdmi_phy->drv_imp_d0 = 0x30;
495 
496 	phy = devm_phy_create(dev, NULL, &mtk_hdmi_phy_ops);
497 	if (IS_ERR(phy)) {
498 		dev_err(dev, "Failed to create HDMI PHY\n");
499 		return PTR_ERR(phy);
500 	}
501 	phy_set_drvdata(phy, hdmi_phy);
502 
503 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
504 	if (IS_ERR(phy_provider))
505 		return PTR_ERR(phy_provider);
506 
507 	hdmi_phy->dev = dev;
508 	return of_clk_add_provider(dev->of_node, of_clk_src_simple_get,
509 				   hdmi_phy->pll);
510 }
511 
mtk_hdmi_phy_remove(struct platform_device * pdev)512 static int mtk_hdmi_phy_remove(struct platform_device *pdev)
513 {
514 	return 0;
515 }
516 
517 static const struct of_device_id mtk_hdmi_phy_match[] = {
518 	{ .compatible = "mediatek,mt8173-hdmi-phy", },
519 	{},
520 };
521 
522 struct platform_driver mtk_hdmi_phy_driver = {
523 	.probe = mtk_hdmi_phy_probe,
524 	.remove = mtk_hdmi_phy_remove,
525 	.driver = {
526 		.name = "mediatek-hdmi-phy",
527 		.of_match_table = mtk_hdmi_phy_match,
528 	},
529 };
530 
531 MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>");
532 MODULE_DESCRIPTION("MediaTek MT8173 HDMI PHY Driver");
533 MODULE_LICENSE("GPL v2");
534