1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
5 * Author: Zheng Yang <zhengyang@rock-chips.com>
6 * Heiko Stuebner <heiko@sntech.de>
10 #include <linux/clk-provider.h>
11 #include <linux/delay.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/nvmem-consumer.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
20 #include <linux/phy/phy.h>
21 #include <linux/slab.h>
23 #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
26 #define RK3228_PRE_PLL_REFCLK_SEL_PCLK BIT(0)
28 #define RK3228_BYPASS_RXSENSE_EN BIT(2)
29 #define RK3228_BYPASS_PWRON_EN BIT(1)
30 #define RK3228_BYPASS_PLLPD_EN BIT(0)
32 #define RK3228_BYPASS_PDATA_EN BIT(4)
33 #define RK3228_PDATAEN_DISABLE BIT(0)
35 #define RK3228_BYPASS_AUTO_TERM_RES_CAL BIT(7)
36 #define RK3228_AUTO_TERM_RES_CAL_SPEED_14_8(x) UPDATE(x, 6, 0)
38 #define RK3228_AUTO_TERM_RES_CAL_SPEED_7_0(x) UPDATE(x, 7, 0)
40 #define RK3228_POST_PLL_CTRL_MANUAL BIT(0)
42 #define RK3228_POST_PLL_POWER_DOWN BIT(5)
43 #define RK3228_PRE_PLL_POWER_DOWN BIT(4)
44 #define RK3228_RXSENSE_CLK_CH_ENABLE BIT(3)
45 #define RK3228_RXSENSE_DATA_CH2_ENABLE BIT(2)
46 #define RK3228_RXSENSE_DATA_CH1_ENABLE BIT(1)
47 #define RK3228_RXSENSE_DATA_CH0_ENABLE BIT(0)
49 #define RK3228_BANDGAP_ENABLE BIT(4)
50 #define RK3228_TMDS_DRIVER_ENABLE GENMASK(3, 0)
52 #define RK3228_PRE_PLL_FB_DIV_8_MASK BIT(7)
53 #define RK3228_PRE_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7)
54 #define RK3228_PCLK_VCO_DIV_5_MASK BIT(5)
55 #define RK3228_PCLK_VCO_DIV_5(x) UPDATE(x, 5, 5)
56 #define RK3228_PRE_PLL_PRE_DIV_MASK GENMASK(4, 0)
57 #define RK3228_PRE_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
59 #define RK3228_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
61 #define RK3228_PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5)
62 #define RK3228_PRE_PLL_PCLK_DIV_B_SHIFT 5
63 #define RK3228_PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5)
64 #define RK3228_PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0)
65 #define RK3228_PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0)
67 #define RK3228_PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5)
68 #define RK3228_PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5)
69 #define RK3228_PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0)
70 #define RK3228_PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0)
72 #define RK3228_PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(5, 4)
73 #define RK3228_PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 5, 4)
74 #define RK3228_PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(3, 2)
75 #define RK3228_PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 3, 2)
76 #define RK3228_PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(1, 0)
77 #define RK3228_PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 1, 0)
79 #define RK3228_PRE_PLL_LOCK_STATUS BIT(0)
81 #define RK3228_POST_PLL_POST_DIV_ENABLE UPDATE(3, 7, 6)
82 #define RK3228_POST_PLL_PRE_DIV_MASK GENMASK(4, 0)
83 #define RK3228_POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
85 #define RK3228_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
87 #define RK3228_POST_PLL_FB_DIV_8_MASK BIT(7)
88 #define RK3228_POST_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7)
89 #define RK3228_POST_PLL_POST_DIV_MASK GENMASK(5, 4)
90 #define RK3228_POST_PLL_POST_DIV(x) UPDATE(x, 5, 4)
91 #define RK3228_POST_PLL_LOCK_STATUS BIT(0)
93 #define RK3228_TMDS_CH_TA_ENABLE GENMASK(7, 4)
95 #define RK3228_TMDS_CLK_CH_TA(x) UPDATE(x, 7, 6)
96 #define RK3228_TMDS_DATA_CH2_TA(x) UPDATE(x, 5, 4)
97 #define RK3228_TMDS_DATA_CH1_TA(x) UPDATE(x, 3, 2)
98 #define RK3228_TMDS_DATA_CH0_TA(x) UPDATE(x, 1, 0)
100 #define RK3228_TMDS_DATA_CH2_PRE_EMPHASIS_MASK GENMASK(5, 4)
101 #define RK3228_TMDS_DATA_CH2_PRE_EMPHASIS(x) UPDATE(x, 5, 4)
102 #define RK3228_TMDS_DATA_CH1_PRE_EMPHASIS_MASK GENMASK(3, 2)
103 #define RK3228_TMDS_DATA_CH1_PRE_EMPHASIS(x) UPDATE(x, 3, 2)
104 #define RK3228_TMDS_DATA_CH0_PRE_EMPHASIS_MASK GENMASK(1, 0)
105 #define RK3228_TMDS_DATA_CH0_PRE_EMPHASIS(x) UPDATE(x, 1, 0)
107 #define RK3228_TMDS_CLK_CH_OUTPUT_SWING(x) UPDATE(x, 7, 4)
108 #define RK3228_TMDS_DATA_CH2_OUTPUT_SWING(x) UPDATE(x, 3, 0)
110 #define RK3228_TMDS_DATA_CH1_OUTPUT_SWING(x) UPDATE(x, 7, 4)
111 #define RK3228_TMDS_DATA_CH0_OUTPUT_SWING(x) UPDATE(x, 3, 0)
114 #define RK3328_BYPASS_RXSENSE_EN BIT(2)
115 #define RK3328_BYPASS_POWERON_EN BIT(1)
116 #define RK3328_BYPASS_PLLPD_EN BIT(0)
118 #define RK3328_INT_POL_HIGH BIT(7)
119 #define RK3328_BYPASS_PDATA_EN BIT(4)
120 #define RK3328_PDATA_EN BIT(0)
122 #define RK3328_INT_TMDS_CLK(x) UPDATE(x, 7, 4)
123 #define RK3328_INT_TMDS_D2(x) UPDATE(x, 3, 0)
125 #define RK3328_INT_TMDS_D1(x) UPDATE(x, 7, 4)
126 #define RK3328_INT_TMDS_D0(x) UPDATE(x, 3, 0)
127 /* for all RK3328_INT_TMDS_*, ESD_DET as defined in 0xc8-0xcb */
128 #define RK3328_INT_AGND_LOW_PULSE_LOCKED BIT(3)
129 #define RK3328_INT_RXSENSE_LOW_PULSE_LOCKED BIT(2)
130 #define RK3328_INT_VSS_AGND_ESD_DET BIT(1)
131 #define RK3328_INT_AGND_VSS_ESD_DET BIT(0)
133 #define RK3328_PCLK_VCO_DIV_5_MASK BIT(1)
134 #define RK3328_PCLK_VCO_DIV_5(x) UPDATE(x, 1, 1)
135 #define RK3328_PRE_PLL_POWER_DOWN BIT(0)
137 #define RK3328_PRE_PLL_PRE_DIV_MASK GENMASK(5, 0)
138 #define RK3328_PRE_PLL_PRE_DIV(x) UPDATE(x, 5, 0)
140 /* unset means center spread */
141 #define RK3328_SPREAD_SPECTRUM_MOD_DOWN BIT(7)
142 #define RK3328_SPREAD_SPECTRUM_MOD_DISABLE BIT(6)
143 #define RK3328_PRE_PLL_FRAC_DIV_DISABLE UPDATE(3, 5, 4)
144 #define RK3328_PRE_PLL_FB_DIV_11_8_MASK GENMASK(3, 0)
145 #define RK3328_PRE_PLL_FB_DIV_11_8(x) UPDATE((x) >> 8, 3, 0)
147 #define RK3328_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
149 #define RK3328_PRE_PLL_TMDSCLK_DIV_C_MASK GENMASK(1, 0)
150 #define RK3328_PRE_PLL_TMDSCLK_DIV_C(x) UPDATE(x, 1, 0)
151 #define RK3328_PRE_PLL_TMDSCLK_DIV_B_MASK GENMASK(3, 2)
152 #define RK3328_PRE_PLL_TMDSCLK_DIV_B(x) UPDATE(x, 3, 2)
153 #define RK3328_PRE_PLL_TMDSCLK_DIV_A_MASK GENMASK(5, 4)
154 #define RK3328_PRE_PLL_TMDSCLK_DIV_A(x) UPDATE(x, 5, 4)
156 #define RK3328_PRE_PLL_PCLK_DIV_B_SHIFT 5
157 #define RK3328_PRE_PLL_PCLK_DIV_B_MASK GENMASK(6, 5)
158 #define RK3328_PRE_PLL_PCLK_DIV_B(x) UPDATE(x, 6, 5)
159 #define RK3328_PRE_PLL_PCLK_DIV_A_MASK GENMASK(4, 0)
160 #define RK3328_PRE_PLL_PCLK_DIV_A(x) UPDATE(x, 4, 0)
162 #define RK3328_PRE_PLL_PCLK_DIV_C_SHIFT 5
163 #define RK3328_PRE_PLL_PCLK_DIV_C_MASK GENMASK(6, 5)
164 #define RK3328_PRE_PLL_PCLK_DIV_C(x) UPDATE(x, 6, 5)
165 #define RK3328_PRE_PLL_PCLK_DIV_D_MASK GENMASK(4, 0)
166 #define RK3328_PRE_PLL_PCLK_DIV_D(x) UPDATE(x, 4, 0)
168 #define RK3328_PRE_PLL_LOCK_STATUS BIT(0)
170 #define RK3328_POST_PLL_POST_DIV_ENABLE GENMASK(3, 2)
171 #define RK3328_POST_PLL_REFCLK_SEL_TMDS BIT(1)
172 #define RK3328_POST_PLL_POWER_DOWN BIT(0)
174 #define RK3328_POST_PLL_FB_DIV_8(x) UPDATE((x) >> 8, 7, 7)
175 #define RK3328_POST_PLL_PRE_DIV(x) UPDATE(x, 4, 0)
177 #define RK3328_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
179 #define RK3328_POST_PLL_POST_DIV_MASK GENMASK(1, 0)
180 #define RK3328_POST_PLL_POST_DIV_2 0x0
181 #define RK3328_POST_PLL_POST_DIV_4 0x1
182 #define RK3328_POST_PLL_POST_DIV_8 0x3
184 #define RK3328_POST_PLL_LOCK_STATUS BIT(0)
186 #define RK3328_BANDGAP_ENABLE BIT(2)
188 #define RK3328_TMDS_CLK_DRIVER_EN BIT(3)
189 #define RK3328_TMDS_D2_DRIVER_EN BIT(2)
190 #define RK3328_TMDS_D1_DRIVER_EN BIT(1)
191 #define RK3328_TMDS_D0_DRIVER_EN BIT(0)
192 #define RK3328_TMDS_DRIVER_ENABLE (RK3328_TMDS_CLK_DRIVER_EN | \
193 RK3328_TMDS_D2_DRIVER_EN | \
194 RK3328_TMDS_D1_DRIVER_EN | \
195 RK3328_TMDS_D0_DRIVER_EN)
197 #define RK3328_BYPASS_TERM_RESISTOR_CALIB BIT(7)
198 #define RK3328_TERM_RESISTOR_CALIB_SPEED_14_8(x) UPDATE((x) >> 8, 6, 0)
200 #define RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(x) UPDATE(x, 7, 0)
202 #define RK3328_TERM_RESISTOR_50 UPDATE(0, 2, 1)
203 #define RK3328_TERM_RESISTOR_62_5 UPDATE(1, 2, 1)
204 #define RK3328_TERM_RESISTOR_75 UPDATE(2, 2, 1)
205 #define RK3328_TERM_RESISTOR_100 UPDATE(3, 2, 1)
206 /* REG 0xc8 - 0xcb */
207 #define RK3328_ESD_DETECT_MASK GENMASK(7, 6)
208 #define RK3328_ESD_DETECT_340MV (0x0 << 6)
209 #define RK3328_ESD_DETECT_280MV (0x1 << 6)
210 #define RK3328_ESD_DETECT_260MV (0x2 << 6)
211 #define RK3328_ESD_DETECT_240MV (0x3 << 6)
212 /* resistors can be used in parallel */
213 #define RK3328_TMDS_TERM_RESIST_MASK GENMASK(5, 0)
214 #define RK3328_TMDS_TERM_RESIST_75 BIT(5)
215 #define RK3328_TMDS_TERM_RESIST_150 BIT(4)
216 #define RK3328_TMDS_TERM_RESIST_300 BIT(3)
217 #define RK3328_TMDS_TERM_RESIST_600 BIT(2)
218 #define RK3328_TMDS_TERM_RESIST_1000 BIT(1)
219 #define RK3328_TMDS_TERM_RESIST_2000 BIT(0)
221 #define RK3328_PRE_PLL_FRAC_DIV_23_16(x) UPDATE((x) >> 16, 7, 0)
223 #define RK3328_PRE_PLL_FRAC_DIV_15_8(x) UPDATE((x) >> 8, 7, 0)
225 #define RK3328_PRE_PLL_FRAC_DIV_7_0(x) UPDATE(x, 7, 0)
227 struct inno_hdmi_phy_drv_data
;
229 struct inno_hdmi_phy
{
231 struct regmap
*regmap
;
240 const struct inno_hdmi_phy_drv_data
*plat_data
;
246 unsigned long pixclock
;
247 unsigned long tmdsclock
;
250 struct pre_pll_config
{
251 unsigned long pixclock
;
252 unsigned long tmdsclock
;
266 struct post_pll_config
{
267 unsigned long tmdsclock
;
275 unsigned long tmdsclock
;
279 struct inno_hdmi_phy_ops
{
280 int (*init
)(struct inno_hdmi_phy
*inno
);
281 int (*power_on
)(struct inno_hdmi_phy
*inno
,
282 const struct post_pll_config
*cfg
,
283 const struct phy_config
*phy_cfg
);
284 void (*power_off
)(struct inno_hdmi_phy
*inno
);
287 struct inno_hdmi_phy_drv_data
{
288 const struct inno_hdmi_phy_ops
*ops
;
289 const struct clk_ops
*clk_ops
;
290 const struct phy_config
*phy_cfg_table
;
293 static const struct pre_pll_config pre_pll_cfg_table
[] = {
294 { 25175000, 25175000, 3, 125, 3, 1, 1, 1, 3, 3, 4, 0, 0xe00000},
295 { 25175000, 31468750, 1, 41, 0, 3, 3, 1, 3, 3, 4, 0, 0xf5554f},
296 { 27000000, 27000000, 1, 36, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
297 { 27000000, 33750000, 1, 45, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
298 { 31500000, 31500000, 1, 42, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
299 { 31500000, 39375000, 1, 105, 1, 3, 3, 10, 0, 3, 4, 0, 0x0},
300 { 33750000, 33750000, 1, 45, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
301 { 33750000, 42187500, 1, 169, 2, 3, 3, 15, 0, 3, 4, 0, 0x0},
302 { 35500000, 35500000, 1, 71, 2, 2, 2, 6, 0, 3, 4, 0, 0x0},
303 { 35500000, 44375000, 1, 74, 3, 1, 1, 25, 0, 1, 1, 0, 0x0},
304 { 36000000, 36000000, 1, 36, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
305 { 36000000, 45000000, 1, 45, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
306 { 40000000, 40000000, 1, 40, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
307 { 40000000, 50000000, 1, 50, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
308 { 49500000, 49500000, 1, 66, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
309 { 49500000, 61875000, 1, 165, 1, 3, 3, 10, 0, 3, 4, 0, 0x0},
310 { 50000000, 50000000, 1, 50, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
311 { 50000000, 62500000, 1, 125, 2, 2, 2, 15, 0, 2, 2, 0, 0x0},
312 { 54000000, 54000000, 1, 36, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
313 { 54000000, 67500000, 1, 45, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
314 { 56250000, 56250000, 1, 75, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
315 { 56250000, 70312500, 1, 117, 3, 1, 1, 25, 0, 1, 1, 0, 0x0},
316 { 59341000, 59341000, 1, 118, 2, 2, 2, 6, 0, 3, 4, 0, 0xae978d},
317 { 59341000, 74176250, 2, 148, 2, 1, 1, 15, 0, 1, 1, 0, 0x5a3d70},
318 { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0x0},
319 { 59400000, 74250000, 1, 99, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
320 { 65000000, 65000000, 1, 65, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
321 { 65000000, 81250000, 3, 325, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
322 { 68250000, 68250000, 1, 91, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
323 { 68250000, 85312500, 1, 142, 3, 1, 1, 25, 0, 1, 1, 0, 0x0},
324 { 71000000, 71000000, 1, 71, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
325 { 71000000, 88750000, 3, 355, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
326 { 72000000, 72000000, 1, 36, 2, 0, 0, 1, 1, 2, 2, 0, 0x0},
327 { 72000000, 90000000, 1, 60, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
328 { 73250000, 73250000, 3, 293, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
329 { 73250000, 91562500, 1, 61, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
330 { 74176000, 74176000, 1, 37, 2, 0, 0, 1, 1, 2, 2, 0, 0x16872b},
331 { 74176000, 92720000, 2, 185, 2, 1, 1, 15, 0, 1, 1, 0, 0x70a3d7},
332 { 74250000, 74250000, 1, 99, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
333 { 74250000, 92812500, 4, 495, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
334 { 75000000, 75000000, 1, 50, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
335 { 75000000, 93750000, 1, 125, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
336 { 78750000, 78750000, 1, 105, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
337 { 78750000, 98437500, 1, 164, 3, 1, 1, 25, 0, 1, 1, 0, 0x0},
338 { 79500000, 79500000, 1, 53, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
339 { 79500000, 99375000, 1, 199, 2, 2, 2, 15, 0, 2, 2, 0, 0x0},
340 { 83500000, 83500000, 2, 167, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
341 { 83500000, 104375000, 1, 104, 2, 1, 1, 15, 0, 1, 1, 0, 0x600000},
342 { 85500000, 85500000, 1, 57, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
343 { 85500000, 106875000, 1, 178, 3, 1, 1, 25, 0, 1, 1, 0, 0x0},
344 { 85750000, 85750000, 3, 343, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
345 { 85750000, 107187500, 1, 143, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
346 { 88750000, 88750000, 3, 355, 0, 3, 3, 1, 2, 3, 4, 0, 0x0},
347 { 88750000, 110937500, 1, 110, 2, 1, 1, 15, 0, 1, 1, 0, 0xf00000},
348 { 94500000, 94500000, 1, 63, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
349 { 94500000, 118125000, 1, 197, 3, 1, 1, 25, 0, 1, 1, 0, 0x0},
350 {101000000, 101000000, 1, 101, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
351 {101000000, 126250000, 1, 42, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
352 {102250000, 102250000, 4, 409, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
353 {102250000, 127812500, 1, 128, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
354 {106500000, 106500000, 1, 71, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
355 {106500000, 133125000, 1, 133, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
356 {108000000, 108000000, 1, 36, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
357 {108000000, 135000000, 1, 45, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
358 {115500000, 115500000, 1, 77, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
359 {115500000, 144375000, 1, 48, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
360 {117500000, 117500000, 2, 235, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
361 {117500000, 146875000, 1, 49, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
362 {119000000, 119000000, 1, 119, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
363 {119000000, 148750000, 3, 148, 0, 1, 1, 1, 3, 1, 1, 0, 0xc00000},
364 {121750000, 121750000, 4, 487, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
365 {121750000, 152187500, 1, 203, 0, 3, 3, 1, 3, 3, 4, 0, 0x0},
366 {122500000, 122500000, 2, 245, 2, 1, 1, 1, 1, 3, 4, 0, 0x0},
367 {122500000, 153125000, 1, 51, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
368 {135000000, 135000000, 1, 45, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
369 {135000000, 168750000, 1, 169, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
370 {136750000, 136750000, 1, 68, 2, 0, 0, 1, 1, 2, 2, 0, 0x600000},
371 {136750000, 170937500, 1, 113, 0, 2, 2, 1, 3, 2, 2, 0, 0xf5554f},
372 {140250000, 140250000, 2, 187, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
373 {140250000, 175312500, 1, 117, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
374 {146250000, 146250000, 2, 195, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
375 {146250000, 182812500, 1, 61, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
376 {148250000, 148250000, 3, 222, 2, 0, 0, 1, 1, 2, 2, 0, 0x600000},
377 {148250000, 185312500, 1, 123, 0, 2, 2, 1, 3, 2, 2, 0, 0x8aaab0},
378 {148352000, 148352000, 2, 148, 2, 0, 0, 1, 1, 2, 2, 0, 0x5a1cac},
379 {148352000, 185440000, 3, 185, 0, 1, 1, 1, 3, 1, 1, 0, 0x70a3d7},
380 {148500000, 148500000, 1, 99, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
381 {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
382 {154000000, 154000000, 1, 77, 2, 0, 0, 1, 1, 2, 2, 0, 0x0},
383 {154000000, 192500000, 1, 64, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
384 {156000000, 156000000, 1, 52, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
385 {156000000, 195000000, 1, 65, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
386 {156750000, 156750000, 2, 209, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
387 {156750000, 195937500, 1, 196, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
388 {157000000, 157000000, 2, 157, 2, 0, 0, 1, 1, 2, 2, 0, 0x0},
389 {157000000, 196250000, 1, 131, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
390 {157500000, 157500000, 1, 105, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
391 {157500000, 196875000, 1, 197, 2, 1, 1, 15, 0, 1, 1, 0, 0x0},
392 {162000000, 162000000, 1, 54, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
393 {162000000, 202500000, 2, 135, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
394 {175500000, 175500000, 1, 117, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
395 {175500000, 219375000, 1, 73, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
396 {179500000, 179500000, 3, 359, 0, 2, 2, 1, 0, 3, 4, 0, 0x0},
397 {179500000, 224375000, 1, 75, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
398 {182750000, 182750000, 1, 91, 2, 0, 0, 1, 1, 2, 2, 0, 0x600000},
399 {182750000, 228437500, 1, 152, 0, 2, 2, 1, 3, 2, 2, 0, 0x4aaab0},
400 {182750000, 228437500, 1, 152, 0, 2, 2, 1, 3, 2, 2, 0, 0x4aaab0},
401 {187000000, 187000000, 2, 187, 2, 0, 0, 1, 1, 2, 2, 0, 0x0},
402 {187000000, 233750000, 1, 39, 0, 0, 0, 1, 3, 0, 0, 1, 0x0},
403 {187250000, 187250000, 3, 280, 2, 0, 0, 1, 1, 2, 2, 0, 0xe00000},
404 {187250000, 234062500, 1, 156, 0, 2, 2, 1, 3, 2, 2, 0, 0xaaab0},
405 {189000000, 189000000, 1, 63, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
406 {189000000, 236250000, 1, 79, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
407 {193250000, 193250000, 3, 289, 2, 0, 0, 1, 1, 2, 2, 0, 0xe00000},
408 {193250000, 241562500, 1, 161, 0, 2, 2, 1, 3, 2, 2, 0, 0xaaab0},
409 {202500000, 202500000, 2, 135, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
410 {202500000, 253125000, 1, 169, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
411 {204750000, 204750000, 4, 273, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
412 {204750000, 255937500, 1, 171, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
413 {208000000, 208000000, 1, 104, 2, 0, 0, 1, 1, 2, 2, 0, 0x0},
414 {208000000, 260000000, 1, 173, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
415 {214750000, 214750000, 1, 107, 2, 0, 0, 1, 1, 2, 2, 0, 0x600000},
416 {214750000, 268437500, 1, 178, 0, 2, 2, 1, 3, 2, 2, 0, 0xf5554f},
417 {218250000, 218250000, 4, 291, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
418 {218250000, 272812500, 1, 91, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
419 {229500000, 229500000, 2, 153, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
420 {229500000, 286875000, 1, 191, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
421 {234000000, 234000000, 1, 39, 0, 0, 0, 1, 0, 1, 1, 0, 0x0},
422 {234000000, 292500000, 1, 195, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
423 {241500000, 241500000, 2, 161, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
424 {241500000, 301875000, 1, 201, 0, 2, 2, 1, 3, 2, 2, 0, 0x0},
425 {245250000, 245250000, 4, 327, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
426 {245250000, 306562500, 1, 51, 0, 0, 0, 1, 3, 0, 0, 1, 0x0},
427 {245500000, 245500000, 4, 491, 2, 0, 0, 1, 1, 2, 2, 0, 0x0},
428 {245500000, 306875000, 1, 51, 0, 0, 0, 1, 3, 0, 0, 1, 0x0},
429 {261000000, 261000000, 1, 87, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
430 {261000000, 326250000, 1, 109, 0, 1, 1, 1, 3, 1, 1, 0, 0x0},
431 {268250000, 268250000, 9, 402, 0, 0, 0, 1, 0, 1, 1, 0, 0x600000},
432 {268250000, 335312500, 1, 111, 0, 1, 1, 1, 3, 1, 1, 0, 0xc5554f},
433 {268500000, 268500000, 2, 179, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
434 {268500000, 335625000, 1, 56, 0, 0, 0, 1, 3, 0, 0, 1, 0x0},
435 {281250000, 281250000, 4, 375, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
436 {281250000, 351562500, 1, 117, 0, 3, 1, 1, 3, 1, 1, 0, 0x0},
437 {288000000, 288000000, 1, 48, 0, 0, 0, 1, 0, 1, 1, 0, 0x0},
438 {288000000, 360000000, 1, 60, 0, 2, 0, 1, 3, 0, 0, 1, 0x0},
439 {296703000, 296703000, 1, 49, 0, 0, 0, 1, 0, 1, 1, 0, 0x7353f7},
440 {296703000, 370878750, 1, 123, 0, 3, 1, 1, 3, 1, 1, 0, 0xa051eb},
441 {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
442 {297000000, 371250000, 4, 495, 0, 3, 1, 1, 3, 1, 1, 0, 0x0},
443 {312250000, 312250000, 9, 468, 0, 0, 0, 1, 0, 1, 1, 0, 0x600000},
444 {312250000, 390312500, 1, 130, 0, 3, 1, 1, 3, 1, 1, 0, 0x1aaab0},
445 {317000000, 317000000, 3, 317, 0, 1, 1, 1, 0, 2, 2, 0, 0x0},
446 {317000000, 396250000, 1, 66, 0, 2, 0, 1, 3, 0, 0, 1, 0x0},
447 {319750000, 319750000, 3, 159, 0, 0, 0, 1, 0, 1, 1, 0, 0xe00000},
448 {319750000, 399687500, 3, 199, 0, 2, 0, 1, 3, 0, 0, 1, 0xd80000},
449 {333250000, 333250000, 9, 499, 0, 0, 0, 1, 0, 1, 1, 0, 0xe00000},
450 {333250000, 416562500, 1, 138, 0, 3, 1, 1, 3, 1, 1, 0, 0xdaaab0},
451 {348500000, 348500000, 9, 522, 0, 2, 0, 1, 0, 1, 1, 0, 0xc00000},
452 {348500000, 435625000, 1, 145, 0, 3, 1, 1, 3, 1, 1, 0, 0x35554f},
453 {356500000, 356500000, 9, 534, 0, 2, 0, 1, 0, 1, 1, 0, 0xc00000},
454 {356500000, 445625000, 1, 148, 0, 3, 1, 1, 3, 1, 1, 0, 0x8aaab0},
455 {380500000, 380500000, 9, 570, 0, 2, 0, 1, 0, 1, 1, 0, 0xc00000},
456 {380500000, 475625000, 1, 158, 0, 3, 1, 1, 3, 1, 1, 0, 0x8aaab0},
457 {443250000, 443250000, 1, 73, 0, 2, 0, 1, 0, 1, 1, 0, 0xe00000},
458 {443250000, 554062500, 1, 92, 0, 2, 0, 1, 3, 0, 0, 1, 0x580000},
459 {505250000, 505250000, 9, 757, 0, 2, 0, 1, 0, 1, 1, 0, 0xe00000},
460 {552750000, 552750000, 3, 276, 0, 2, 0, 1, 0, 1, 1, 0, 0x600000},
461 {593407000, 296703500, 3, 296, 0, 1, 1, 1, 0, 1, 1, 0, 0xb41893},
462 {593407000, 370879375, 4, 494, 0, 3, 1, 1, 3, 0, 0, 1, 0x817e4a},
463 {593407000, 593407000, 3, 296, 0, 2, 0, 1, 0, 1, 1, 0, 0xb41893},
464 {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 1, 1, 0, 0x0},
465 {594000000, 371250000, 4, 495, 0, 3, 1, 1, 3, 0, 0, 1, 0x0},
466 {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0x0},
470 static const struct post_pll_config post_pll_cfg_table
[] = {
471 {33750000, 1, 40, 8, 1},
472 {33750000, 1, 80, 8, 2},
473 {74250000, 1, 40, 8, 1},
474 {74250000, 18, 80, 8, 2},
475 {148500000, 2, 40, 4, 3},
476 {297000000, 4, 40, 2, 3},
477 {594000000, 8, 40, 1, 3},
481 /* phy tuning values for an undocumented set of registers */
482 static const struct phy_config rk3228_phy_cfg
[] = {
484 0xaa, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00,
489 0xaa, 0x15, 0x6a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00,
494 0xaa, 0x15, 0x7a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00,
497 }, { /* sentinel */ },
500 /* phy tuning values for an undocumented set of registers */
501 static const struct phy_config rk3328_phy_cfg
[] = {
503 0x07, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x08, 0x08,
504 0x00, 0xac, 0xcc, 0xcc, 0xcc,
508 0x0b, 0x0d, 0x0d, 0x0d, 0x07, 0x15, 0x08, 0x08, 0x08,
509 0x3f, 0xac, 0xcc, 0xcd, 0xdd,
513 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08,
514 0x00, 0xac, 0xcc, 0xcc, 0xcc,
516 }, { /* sentinel */ },
519 static inline struct inno_hdmi_phy
*to_inno_hdmi_phy(struct clk_hw
*hw
)
521 return container_of(hw
, struct inno_hdmi_phy
, hw
);
525 * The register description of the IP block does not use any distinct names
526 * but instead the databook simply numbers the registers in one-increments.
527 * As the registers are obviously 32bit sized, the inno_* functions
528 * translate the databook register names to the actual registers addresses.
530 static inline void inno_write(struct inno_hdmi_phy
*inno
, u32 reg
, u8 val
)
532 regmap_write(inno
->regmap
, reg
* 4, val
);
535 static inline u8
inno_read(struct inno_hdmi_phy
*inno
, u32 reg
)
539 regmap_read(inno
->regmap
, reg
* 4, &val
);
544 static inline void inno_update_bits(struct inno_hdmi_phy
*inno
, u8 reg
,
547 regmap_update_bits(inno
->regmap
, reg
* 4, mask
, val
);
550 #define inno_poll(inno, reg, val, cond, sleep_us, timeout_us) \
551 regmap_read_poll_timeout((inno)->regmap, (reg) * 4, val, cond, \
552 sleep_us, timeout_us)
554 static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy
*inno
,
557 int bus_width
= phy_get_bus_width(inno
->phy
);
566 return (u64
)rate
* bus_width
/ 8;
572 static irqreturn_t
inno_hdmi_phy_rk3328_hardirq(int irq
, void *dev_id
)
574 struct inno_hdmi_phy
*inno
= dev_id
;
575 int intr_stat1
, intr_stat2
, intr_stat3
;
577 intr_stat1
= inno_read(inno
, 0x04);
578 intr_stat2
= inno_read(inno
, 0x06);
579 intr_stat3
= inno_read(inno
, 0x08);
582 inno_write(inno
, 0x04, intr_stat1
);
584 inno_write(inno
, 0x06, intr_stat2
);
586 inno_write(inno
, 0x08, intr_stat3
);
588 if (intr_stat1
|| intr_stat2
|| intr_stat3
)
589 return IRQ_WAKE_THREAD
;
594 static irqreturn_t
inno_hdmi_phy_rk3328_irq(int irq
, void *dev_id
)
596 struct inno_hdmi_phy
*inno
= dev_id
;
598 inno_update_bits(inno
, 0x02, RK3328_PDATA_EN
, 0);
599 usleep_range(10, 20);
600 inno_update_bits(inno
, 0x02, RK3328_PDATA_EN
, RK3328_PDATA_EN
);
605 static int inno_hdmi_phy_power_on(struct phy
*phy
)
607 struct inno_hdmi_phy
*inno
= phy_get_drvdata(phy
);
608 const struct post_pll_config
*cfg
= post_pll_cfg_table
;
609 const struct phy_config
*phy_cfg
= inno
->plat_data
->phy_cfg_table
;
610 unsigned long tmdsclock
= inno_hdmi_phy_get_tmdsclk(inno
,
615 dev_err(inno
->dev
, "TMDS clock is zero!\n");
619 if (!inno
->plat_data
->ops
->power_on
)
622 for (; cfg
->tmdsclock
!= 0; cfg
++)
623 if (tmdsclock
<= cfg
->tmdsclock
&&
624 cfg
->version
& inno
->chip_version
)
627 for (; phy_cfg
->tmdsclock
!= 0; phy_cfg
++)
628 if (tmdsclock
<= phy_cfg
->tmdsclock
)
631 if (cfg
->tmdsclock
== 0 || phy_cfg
->tmdsclock
== 0)
634 dev_dbg(inno
->dev
, "Inno HDMI PHY Power On\n");
636 inno
->plat_data
->clk_ops
->set_rate(&inno
->hw
, inno
->pixclock
, 24000000);
638 ret
= clk_prepare_enable(inno
->phyclk
);
642 ret
= inno
->plat_data
->ops
->power_on(inno
, cfg
, phy_cfg
);
644 clk_disable_unprepare(inno
->phyclk
);
651 static int inno_hdmi_phy_power_off(struct phy
*phy
)
653 struct inno_hdmi_phy
*inno
= phy_get_drvdata(phy
);
655 if (!inno
->plat_data
->ops
->power_off
)
658 inno
->plat_data
->ops
->power_off(inno
);
660 clk_disable_unprepare(inno
->phyclk
);
664 dev_dbg(inno
->dev
, "Inno HDMI PHY Power Off\n");
669 static const struct phy_ops inno_hdmi_phy_ops
= {
670 .owner
= THIS_MODULE
,
671 .power_on
= inno_hdmi_phy_power_on
,
672 .power_off
= inno_hdmi_phy_power_off
,
676 struct pre_pll_config
*inno_hdmi_phy_get_pre_pll_cfg(struct inno_hdmi_phy
*inno
,
679 const struct pre_pll_config
*cfg
= pre_pll_cfg_table
;
680 unsigned long tmdsclock
= inno_hdmi_phy_get_tmdsclk(inno
, rate
);
682 for (; cfg
->pixclock
!= 0; cfg
++)
683 if (cfg
->pixclock
== rate
&& cfg
->tmdsclock
== tmdsclock
)
686 if (cfg
->pixclock
== 0)
687 return ERR_PTR(-EINVAL
);
692 static int inno_hdmi_phy_rk3228_clk_is_prepared(struct clk_hw
*hw
)
694 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
697 status
= inno_read(inno
, 0xe0) & RK3228_PRE_PLL_POWER_DOWN
;
698 return status
? 0 : 1;
701 static int inno_hdmi_phy_rk3228_clk_prepare(struct clk_hw
*hw
)
703 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
705 inno_update_bits(inno
, 0xe0, RK3228_PRE_PLL_POWER_DOWN
, 0);
709 static void inno_hdmi_phy_rk3228_clk_unprepare(struct clk_hw
*hw
)
711 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
713 inno_update_bits(inno
, 0xe0, RK3228_PRE_PLL_POWER_DOWN
,
714 RK3228_PRE_PLL_POWER_DOWN
);
718 unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw
*hw
,
719 unsigned long parent_rate
)
721 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
722 u8 nd
, no_a
, no_b
, no_d
;
726 nd
= inno_read(inno
, 0xe2) & RK3228_PRE_PLL_PRE_DIV_MASK
;
727 nf
= (inno_read(inno
, 0xe2) & RK3228_PRE_PLL_FB_DIV_8_MASK
) << 1;
728 nf
|= inno_read(inno
, 0xe3);
729 vco
= parent_rate
* nf
;
731 if (inno_read(inno
, 0xe2) & RK3228_PCLK_VCO_DIV_5_MASK
) {
734 no_a
= inno_read(inno
, 0xe4) & RK3228_PRE_PLL_PCLK_DIV_A_MASK
;
737 no_b
= inno_read(inno
, 0xe4) & RK3228_PRE_PLL_PCLK_DIV_B_MASK
;
738 no_b
>>= RK3228_PRE_PLL_PCLK_DIV_B_SHIFT
;
740 no_d
= inno_read(inno
, 0xe5) & RK3228_PRE_PLL_PCLK_DIV_D_MASK
;
742 do_div(vco
, (nd
* (no_a
== 1 ? no_b
: no_a
) * no_d
* 2));
745 inno
->pixclock
= vco
;
747 dev_dbg(inno
->dev
, "%s rate %lu\n", __func__
, inno
->pixclock
);
752 static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw
*hw
,
754 unsigned long *parent_rate
)
756 const struct pre_pll_config
*cfg
= pre_pll_cfg_table
;
758 rate
= (rate
/ 1000) * 1000;
760 for (; cfg
->pixclock
!= 0; cfg
++)
761 if (cfg
->pixclock
== rate
&& !cfg
->fracdiv
)
764 if (cfg
->pixclock
== 0)
767 return cfg
->pixclock
;
770 static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw
*hw
,
772 unsigned long parent_rate
)
774 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
775 const struct pre_pll_config
*cfg
;
776 unsigned long tmdsclock
= inno_hdmi_phy_get_tmdsclk(inno
, rate
);
780 dev_dbg(inno
->dev
, "%s rate %lu tmdsclk %lu\n",
781 __func__
, rate
, tmdsclock
);
783 if (inno
->pixclock
== rate
&& inno
->tmdsclock
== tmdsclock
)
786 cfg
= inno_hdmi_phy_get_pre_pll_cfg(inno
, rate
);
790 /* Power down PRE-PLL */
791 inno_update_bits(inno
, 0xe0, RK3228_PRE_PLL_POWER_DOWN
,
792 RK3228_PRE_PLL_POWER_DOWN
);
794 inno_update_bits(inno
, 0xe2, RK3228_PRE_PLL_FB_DIV_8_MASK
|
795 RK3228_PCLK_VCO_DIV_5_MASK
|
796 RK3228_PRE_PLL_PRE_DIV_MASK
,
797 RK3228_PRE_PLL_FB_DIV_8(cfg
->fbdiv
) |
798 RK3228_PCLK_VCO_DIV_5(cfg
->vco_div_5_en
) |
799 RK3228_PRE_PLL_PRE_DIV(cfg
->prediv
));
800 inno_write(inno
, 0xe3, RK3228_PRE_PLL_FB_DIV_7_0(cfg
->fbdiv
));
801 inno_update_bits(inno
, 0xe4, RK3228_PRE_PLL_PCLK_DIV_B_MASK
|
802 RK3228_PRE_PLL_PCLK_DIV_A_MASK
,
803 RK3228_PRE_PLL_PCLK_DIV_B(cfg
->pclk_div_b
) |
804 RK3228_PRE_PLL_PCLK_DIV_A(cfg
->pclk_div_a
));
805 inno_update_bits(inno
, 0xe5, RK3228_PRE_PLL_PCLK_DIV_C_MASK
|
806 RK3228_PRE_PLL_PCLK_DIV_D_MASK
,
807 RK3228_PRE_PLL_PCLK_DIV_C(cfg
->pclk_div_c
) |
808 RK3228_PRE_PLL_PCLK_DIV_D(cfg
->pclk_div_d
));
809 inno_update_bits(inno
, 0xe6, RK3228_PRE_PLL_TMDSCLK_DIV_C_MASK
|
810 RK3228_PRE_PLL_TMDSCLK_DIV_A_MASK
|
811 RK3228_PRE_PLL_TMDSCLK_DIV_B_MASK
,
812 RK3228_PRE_PLL_TMDSCLK_DIV_C(cfg
->tmds_div_c
) |
813 RK3228_PRE_PLL_TMDSCLK_DIV_A(cfg
->tmds_div_a
) |
814 RK3228_PRE_PLL_TMDSCLK_DIV_B(cfg
->tmds_div_b
));
816 /* Power up PRE-PLL */
817 inno_update_bits(inno
, 0xe0, RK3228_PRE_PLL_POWER_DOWN
, 0);
819 /* Wait for Pre-PLL lock */
820 ret
= inno_poll(inno
, 0xe8, v
, v
& RK3228_PRE_PLL_LOCK_STATUS
,
823 dev_err(inno
->dev
, "Pre-PLL locking failed\n");
827 inno
->pixclock
= rate
;
828 inno
->tmdsclock
= tmdsclock
;
833 static const struct clk_ops inno_hdmi_phy_rk3228_clk_ops
= {
834 .prepare
= inno_hdmi_phy_rk3228_clk_prepare
,
835 .unprepare
= inno_hdmi_phy_rk3228_clk_unprepare
,
836 .is_prepared
= inno_hdmi_phy_rk3228_clk_is_prepared
,
837 .recalc_rate
= inno_hdmi_phy_rk3228_clk_recalc_rate
,
838 .round_rate
= inno_hdmi_phy_rk3228_clk_round_rate
,
839 .set_rate
= inno_hdmi_phy_rk3228_clk_set_rate
,
842 static int inno_hdmi_phy_rk3328_clk_is_prepared(struct clk_hw
*hw
)
844 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
847 status
= inno_read(inno
, 0xa0) & RK3328_PRE_PLL_POWER_DOWN
;
848 return status
? 0 : 1;
851 static int inno_hdmi_phy_rk3328_clk_prepare(struct clk_hw
*hw
)
853 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
855 inno_update_bits(inno
, 0xa0, RK3328_PRE_PLL_POWER_DOWN
, 0);
859 static void inno_hdmi_phy_rk3328_clk_unprepare(struct clk_hw
*hw
)
861 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
863 inno_update_bits(inno
, 0xa0, RK3328_PRE_PLL_POWER_DOWN
,
864 RK3328_PRE_PLL_POWER_DOWN
);
868 unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw
*hw
,
869 unsigned long parent_rate
)
871 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
873 u8 nd
, no_a
, no_b
, no_d
;
877 nd
= inno_read(inno
, 0xa1) & RK3328_PRE_PLL_PRE_DIV_MASK
;
878 nf
= ((inno_read(inno
, 0xa2) & RK3328_PRE_PLL_FB_DIV_11_8_MASK
) << 8);
879 nf
|= inno_read(inno
, 0xa3);
880 vco
= parent_rate
* nf
;
882 if (!(inno_read(inno
, 0xa2) & RK3328_PRE_PLL_FRAC_DIV_DISABLE
)) {
883 frac
= inno_read(inno
, 0xd3) |
884 (inno_read(inno
, 0xd2) << 8) |
885 (inno_read(inno
, 0xd1) << 16);
886 vco
+= DIV_ROUND_CLOSEST(parent_rate
* frac
, (1 << 24));
889 if (inno_read(inno
, 0xa0) & RK3328_PCLK_VCO_DIV_5_MASK
) {
892 no_a
= inno_read(inno
, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_A_MASK
;
893 no_b
= inno_read(inno
, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK
;
894 no_b
>>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT
;
896 no_d
= inno_read(inno
, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK
;
898 do_div(vco
, (nd
* (no_a
== 1 ? no_b
: no_a
) * no_d
* 2));
901 inno
->pixclock
= DIV_ROUND_CLOSEST((unsigned long)vco
, 1000) * 1000;
903 dev_dbg(inno
->dev
, "%s rate %lu vco %llu\n",
904 __func__
, inno
->pixclock
, vco
);
906 return inno
->pixclock
;
909 static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw
*hw
,
911 unsigned long *parent_rate
)
913 const struct pre_pll_config
*cfg
= pre_pll_cfg_table
;
915 rate
= (rate
/ 1000) * 1000;
917 for (; cfg
->pixclock
!= 0; cfg
++)
918 if (cfg
->pixclock
== rate
)
921 if (cfg
->pixclock
== 0)
924 return cfg
->pixclock
;
927 static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw
*hw
,
929 unsigned long parent_rate
)
931 struct inno_hdmi_phy
*inno
= to_inno_hdmi_phy(hw
);
932 const struct pre_pll_config
*cfg
;
933 unsigned long tmdsclock
= inno_hdmi_phy_get_tmdsclk(inno
, rate
);
937 dev_dbg(inno
->dev
, "%s rate %lu tmdsclk %lu\n",
938 __func__
, rate
, tmdsclock
);
940 if (inno
->pixclock
== rate
&& inno
->tmdsclock
== tmdsclock
)
943 cfg
= inno_hdmi_phy_get_pre_pll_cfg(inno
, rate
);
947 inno_update_bits(inno
, 0xa0, RK3328_PRE_PLL_POWER_DOWN
,
948 RK3328_PRE_PLL_POWER_DOWN
);
950 /* Configure pre-pll */
951 inno_update_bits(inno
, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK
,
952 RK3328_PCLK_VCO_DIV_5(cfg
->vco_div_5_en
));
953 inno_write(inno
, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg
->prediv
));
955 val
= RK3328_SPREAD_SPECTRUM_MOD_DISABLE
;
957 val
|= RK3328_PRE_PLL_FRAC_DIV_DISABLE
;
958 inno_write(inno
, 0xa2, RK3328_PRE_PLL_FB_DIV_11_8(cfg
->fbdiv
) | val
);
959 inno_write(inno
, 0xa3, RK3328_PRE_PLL_FB_DIV_7_0(cfg
->fbdiv
));
960 inno_write(inno
, 0xa5, RK3328_PRE_PLL_PCLK_DIV_A(cfg
->pclk_div_a
) |
961 RK3328_PRE_PLL_PCLK_DIV_B(cfg
->pclk_div_b
));
962 inno_write(inno
, 0xa6, RK3328_PRE_PLL_PCLK_DIV_C(cfg
->pclk_div_c
) |
963 RK3328_PRE_PLL_PCLK_DIV_D(cfg
->pclk_div_d
));
964 inno_write(inno
, 0xa4, RK3328_PRE_PLL_TMDSCLK_DIV_C(cfg
->tmds_div_c
) |
965 RK3328_PRE_PLL_TMDSCLK_DIV_A(cfg
->tmds_div_a
) |
966 RK3328_PRE_PLL_TMDSCLK_DIV_B(cfg
->tmds_div_b
));
967 inno_write(inno
, 0xd3, RK3328_PRE_PLL_FRAC_DIV_7_0(cfg
->fracdiv
));
968 inno_write(inno
, 0xd2, RK3328_PRE_PLL_FRAC_DIV_15_8(cfg
->fracdiv
));
969 inno_write(inno
, 0xd1, RK3328_PRE_PLL_FRAC_DIV_23_16(cfg
->fracdiv
));
971 inno_update_bits(inno
, 0xa0, RK3328_PRE_PLL_POWER_DOWN
, 0);
973 /* Wait for Pre-PLL lock */
974 ret
= inno_poll(inno
, 0xa9, val
, val
& RK3328_PRE_PLL_LOCK_STATUS
,
977 dev_err(inno
->dev
, "Pre-PLL locking failed\n");
981 inno
->pixclock
= rate
;
982 inno
->tmdsclock
= tmdsclock
;
987 static const struct clk_ops inno_hdmi_phy_rk3328_clk_ops
= {
988 .prepare
= inno_hdmi_phy_rk3328_clk_prepare
,
989 .unprepare
= inno_hdmi_phy_rk3328_clk_unprepare
,
990 .is_prepared
= inno_hdmi_phy_rk3328_clk_is_prepared
,
991 .recalc_rate
= inno_hdmi_phy_rk3328_clk_recalc_rate
,
992 .round_rate
= inno_hdmi_phy_rk3328_clk_round_rate
,
993 .set_rate
= inno_hdmi_phy_rk3328_clk_set_rate
,
996 static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy
*inno
)
998 struct device
*dev
= inno
->dev
;
999 struct device_node
*np
= dev
->of_node
;
1000 struct clk_init_data init
;
1001 const char *parent_name
;
1004 parent_name
= __clk_get_name(inno
->refoclk
);
1006 init
.parent_names
= &parent_name
;
1007 init
.num_parents
= 1;
1009 init
.name
= "pin_hd20_pclk";
1010 init
.ops
= inno
->plat_data
->clk_ops
;
1012 /* optional override of the clock name */
1013 of_property_read_string(np
, "clock-output-names", &init
.name
);
1015 inno
->hw
.init
= &init
;
1017 inno
->phyclk
= devm_clk_register(dev
, &inno
->hw
);
1018 if (IS_ERR(inno
->phyclk
)) {
1019 ret
= PTR_ERR(inno
->phyclk
);
1020 dev_err(dev
, "failed to register clock: %d\n", ret
);
1024 ret
= of_clk_add_provider(np
, of_clk_src_simple_get
, inno
->phyclk
);
1026 dev_err(dev
, "failed to register clock provider: %d\n", ret
);
1033 static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy
*inno
)
1036 * Use phy internal register control
1037 * rxsense/poweron/pllpd/pdataen signal.
1039 inno_write(inno
, 0x01, RK3228_BYPASS_RXSENSE_EN
|
1040 RK3228_BYPASS_PWRON_EN
|
1041 RK3228_BYPASS_PLLPD_EN
);
1042 inno_update_bits(inno
, 0x02, RK3228_BYPASS_PDATA_EN
,
1043 RK3228_BYPASS_PDATA_EN
);
1045 /* manual power down post-PLL */
1046 inno_update_bits(inno
, 0xaa, RK3228_POST_PLL_CTRL_MANUAL
,
1047 RK3228_POST_PLL_CTRL_MANUAL
);
1049 inno
->chip_version
= 1;
1055 inno_hdmi_phy_rk3228_power_on(struct inno_hdmi_phy
*inno
,
1056 const struct post_pll_config
*cfg
,
1057 const struct phy_config
*phy_cfg
)
1062 inno_update_bits(inno
, 0x02, RK3228_PDATAEN_DISABLE
,
1063 RK3228_PDATAEN_DISABLE
);
1064 inno_update_bits(inno
, 0xe0, RK3228_PRE_PLL_POWER_DOWN
|
1065 RK3228_POST_PLL_POWER_DOWN
,
1066 RK3228_PRE_PLL_POWER_DOWN
|
1067 RK3228_POST_PLL_POWER_DOWN
);
1069 /* Post-PLL update */
1070 inno_update_bits(inno
, 0xe9, RK3228_POST_PLL_PRE_DIV_MASK
,
1071 RK3228_POST_PLL_PRE_DIV(cfg
->prediv
));
1072 inno_update_bits(inno
, 0xeb, RK3228_POST_PLL_FB_DIV_8_MASK
,
1073 RK3228_POST_PLL_FB_DIV_8(cfg
->fbdiv
));
1074 inno_write(inno
, 0xea, RK3228_POST_PLL_FB_DIV_7_0(cfg
->fbdiv
));
1076 if (cfg
->postdiv
== 1) {
1077 inno_update_bits(inno
, 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE
,
1080 int div
= cfg
->postdiv
/ 2 - 1;
1082 inno_update_bits(inno
, 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE
,
1083 RK3228_POST_PLL_POST_DIV_ENABLE
);
1084 inno_update_bits(inno
, 0xeb, RK3228_POST_PLL_POST_DIV_MASK
,
1085 RK3228_POST_PLL_POST_DIV(div
));
1088 for (v
= 0; v
< 4; v
++)
1089 inno_write(inno
, 0xef + v
, phy_cfg
->regs
[v
]);
1091 inno_update_bits(inno
, 0xe0, RK3228_PRE_PLL_POWER_DOWN
|
1092 RK3228_POST_PLL_POWER_DOWN
, 0);
1093 inno_update_bits(inno
, 0xe1, RK3228_BANDGAP_ENABLE
,
1094 RK3228_BANDGAP_ENABLE
);
1095 inno_update_bits(inno
, 0xe1, RK3228_TMDS_DRIVER_ENABLE
,
1096 RK3228_TMDS_DRIVER_ENABLE
);
1098 /* Wait for post PLL lock */
1099 ret
= inno_poll(inno
, 0xeb, v
, v
& RK3228_POST_PLL_LOCK_STATUS
,
1102 dev_err(inno
->dev
, "Post-PLL locking failed\n");
1106 if (cfg
->tmdsclock
> 340000000)
1109 inno_update_bits(inno
, 0x02, RK3228_PDATAEN_DISABLE
, 0);
1113 static void inno_hdmi_phy_rk3228_power_off(struct inno_hdmi_phy
*inno
)
1115 inno_update_bits(inno
, 0xe1, RK3228_TMDS_DRIVER_ENABLE
, 0);
1116 inno_update_bits(inno
, 0xe1, RK3228_BANDGAP_ENABLE
, 0);
1117 inno_update_bits(inno
, 0xe0, RK3228_POST_PLL_POWER_DOWN
,
1118 RK3228_POST_PLL_POWER_DOWN
);
1121 static const struct inno_hdmi_phy_ops rk3228_hdmi_phy_ops
= {
1122 .init
= inno_hdmi_phy_rk3228_init
,
1123 .power_on
= inno_hdmi_phy_rk3228_power_on
,
1124 .power_off
= inno_hdmi_phy_rk3228_power_off
,
1127 static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy
*inno
)
1129 struct nvmem_cell
*cell
;
1130 unsigned char *efuse_buf
;
1134 * Use phy internal register control
1135 * rxsense/poweron/pllpd/pdataen signal.
1137 inno_write(inno
, 0x01, RK3328_BYPASS_RXSENSE_EN
|
1138 RK3328_BYPASS_POWERON_EN
|
1139 RK3328_BYPASS_PLLPD_EN
);
1140 inno_write(inno
, 0x02, RK3328_INT_POL_HIGH
| RK3328_BYPASS_PDATA_EN
|
1143 /* Disable phy irq */
1144 inno_write(inno
, 0x05, 0);
1145 inno_write(inno
, 0x07, 0);
1147 /* try to read the chip-version */
1148 inno
->chip_version
= 1;
1149 cell
= nvmem_cell_get(inno
->dev
, "cpu-version");
1151 if (PTR_ERR(cell
) == -EPROBE_DEFER
)
1152 return -EPROBE_DEFER
;
1157 efuse_buf
= nvmem_cell_read(cell
, &len
);
1158 nvmem_cell_put(cell
);
1160 if (IS_ERR(efuse_buf
))
1163 inno
->chip_version
= efuse_buf
[0] + 1;
1170 inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy
*inno
,
1171 const struct post_pll_config
*cfg
,
1172 const struct phy_config
*phy_cfg
)
1177 inno_update_bits(inno
, 0x02, RK3328_PDATA_EN
, 0);
1178 inno_update_bits(inno
, 0xaa, RK3328_POST_PLL_POWER_DOWN
,
1179 RK3328_POST_PLL_POWER_DOWN
);
1181 inno_write(inno
, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg
->fbdiv
));
1182 if (cfg
->postdiv
== 1) {
1183 inno_write(inno
, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg
->fbdiv
) |
1184 RK3328_POST_PLL_PRE_DIV(cfg
->prediv
));
1185 inno_write(inno
, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS
|
1186 RK3328_POST_PLL_POWER_DOWN
);
1188 v
= (cfg
->postdiv
/ 2) - 1;
1189 v
&= RK3328_POST_PLL_POST_DIV_MASK
;
1190 inno_write(inno
, 0xad, v
);
1191 inno_write(inno
, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg
->fbdiv
) |
1192 RK3328_POST_PLL_PRE_DIV(cfg
->prediv
));
1193 inno_write(inno
, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE
|
1194 RK3328_POST_PLL_REFCLK_SEL_TMDS
|
1195 RK3328_POST_PLL_POWER_DOWN
);
1198 for (v
= 0; v
< 14; v
++)
1199 inno_write(inno
, 0xb5 + v
, phy_cfg
->regs
[v
]);
1201 /* set ESD detection threshold for TMDS CLK, D2, D1 and D0 */
1202 for (v
= 0; v
< 4; v
++)
1203 inno_update_bits(inno
, 0xc8 + v
, RK3328_ESD_DETECT_MASK
,
1204 RK3328_ESD_DETECT_340MV
);
1206 if (phy_cfg
->tmdsclock
> 340000000) {
1207 /* Set termination resistor to 100ohm */
1208 v
= clk_get_rate(inno
->sysclk
) / 100000;
1209 inno_write(inno
, 0xc5, RK3328_TERM_RESISTOR_CALIB_SPEED_14_8(v
)
1210 | RK3328_BYPASS_TERM_RESISTOR_CALIB
);
1211 inno_write(inno
, 0xc6, RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(v
));
1212 inno_write(inno
, 0xc7, RK3328_TERM_RESISTOR_100
);
1213 inno_update_bits(inno
, 0xc5,
1214 RK3328_BYPASS_TERM_RESISTOR_CALIB
, 0);
1216 inno_write(inno
, 0xc5, RK3328_BYPASS_TERM_RESISTOR_CALIB
);
1218 /* clk termination resistor is 50ohm (parallel resistors) */
1219 if (phy_cfg
->tmdsclock
> 165000000)
1220 inno_update_bits(inno
, 0xc8,
1221 RK3328_TMDS_TERM_RESIST_MASK
,
1222 RK3328_TMDS_TERM_RESIST_75
|
1223 RK3328_TMDS_TERM_RESIST_150
);
1225 /* data termination resistor for D2, D1 and D0 is 150ohm */
1226 for (v
= 0; v
< 3; v
++)
1227 inno_update_bits(inno
, 0xc9 + v
,
1228 RK3328_TMDS_TERM_RESIST_MASK
,
1229 RK3328_TMDS_TERM_RESIST_150
);
1232 inno_update_bits(inno
, 0xaa, RK3328_POST_PLL_POWER_DOWN
, 0);
1233 inno_update_bits(inno
, 0xb0, RK3328_BANDGAP_ENABLE
,
1234 RK3328_BANDGAP_ENABLE
);
1235 inno_update_bits(inno
, 0xb2, RK3328_TMDS_DRIVER_ENABLE
,
1236 RK3328_TMDS_DRIVER_ENABLE
);
1238 /* Wait for post PLL lock */
1239 ret
= inno_poll(inno
, 0xaf, v
, v
& RK3328_POST_PLL_LOCK_STATUS
,
1242 dev_err(inno
->dev
, "Post-PLL locking failed\n");
1246 if (phy_cfg
->tmdsclock
> 340000000)
1249 inno_update_bits(inno
, 0x02, RK3328_PDATA_EN
, RK3328_PDATA_EN
);
1251 /* Enable PHY IRQ */
1252 inno_write(inno
, 0x05, RK3328_INT_TMDS_CLK(RK3328_INT_VSS_AGND_ESD_DET
)
1253 | RK3328_INT_TMDS_D2(RK3328_INT_VSS_AGND_ESD_DET
));
1254 inno_write(inno
, 0x07, RK3328_INT_TMDS_D1(RK3328_INT_VSS_AGND_ESD_DET
)
1255 | RK3328_INT_TMDS_D0(RK3328_INT_VSS_AGND_ESD_DET
));
1259 static void inno_hdmi_phy_rk3328_power_off(struct inno_hdmi_phy
*inno
)
1261 inno_update_bits(inno
, 0xb2, RK3328_TMDS_DRIVER_ENABLE
, 0);
1262 inno_update_bits(inno
, 0xb0, RK3328_BANDGAP_ENABLE
, 0);
1263 inno_update_bits(inno
, 0xaa, RK3328_POST_PLL_POWER_DOWN
,
1264 RK3328_POST_PLL_POWER_DOWN
);
1266 /* Disable PHY IRQ */
1267 inno_write(inno
, 0x05, 0);
1268 inno_write(inno
, 0x07, 0);
1271 static const struct inno_hdmi_phy_ops rk3328_hdmi_phy_ops
= {
1272 .init
= inno_hdmi_phy_rk3328_init
,
1273 .power_on
= inno_hdmi_phy_rk3328_power_on
,
1274 .power_off
= inno_hdmi_phy_rk3328_power_off
,
1277 static const struct inno_hdmi_phy_drv_data rk3228_hdmi_phy_drv_data
= {
1278 .ops
= &rk3228_hdmi_phy_ops
,
1279 .clk_ops
= &inno_hdmi_phy_rk3228_clk_ops
,
1280 .phy_cfg_table
= rk3228_phy_cfg
,
1283 static const struct inno_hdmi_phy_drv_data rk3328_hdmi_phy_drv_data
= {
1284 .ops
= &rk3328_hdmi_phy_ops
,
1285 .clk_ops
= &inno_hdmi_phy_rk3328_clk_ops
,
1286 .phy_cfg_table
= rk3328_phy_cfg
,
1289 static const struct regmap_config inno_hdmi_phy_regmap_config
= {
1293 .max_register
= 0x400,
1296 static void inno_hdmi_phy_action(void *data
)
1298 struct inno_hdmi_phy
*inno
= data
;
1300 clk_disable_unprepare(inno
->refpclk
);
1301 clk_disable_unprepare(inno
->sysclk
);
1304 static int inno_hdmi_phy_probe(struct platform_device
*pdev
)
1306 struct inno_hdmi_phy
*inno
;
1307 struct phy_provider
*phy_provider
;
1311 inno
= devm_kzalloc(&pdev
->dev
, sizeof(*inno
), GFP_KERNEL
);
1315 inno
->dev
= &pdev
->dev
;
1317 inno
->plat_data
= of_device_get_match_data(inno
->dev
);
1318 if (!inno
->plat_data
|| !inno
->plat_data
->ops
)
1321 regs
= devm_platform_ioremap_resource(pdev
, 0);
1323 return PTR_ERR(regs
);
1325 inno
->sysclk
= devm_clk_get(inno
->dev
, "sysclk");
1326 if (IS_ERR(inno
->sysclk
)) {
1327 ret
= PTR_ERR(inno
->sysclk
);
1328 dev_err(inno
->dev
, "failed to get sysclk: %d\n", ret
);
1332 inno
->refpclk
= devm_clk_get(inno
->dev
, "refpclk");
1333 if (IS_ERR(inno
->refpclk
)) {
1334 ret
= PTR_ERR(inno
->refpclk
);
1335 dev_err(inno
->dev
, "failed to get ref clock: %d\n", ret
);
1339 inno
->refoclk
= devm_clk_get(inno
->dev
, "refoclk");
1340 if (IS_ERR(inno
->refoclk
)) {
1341 ret
= PTR_ERR(inno
->refoclk
);
1342 dev_err(inno
->dev
, "failed to get oscillator-ref clock: %d\n",
1347 ret
= clk_prepare_enable(inno
->sysclk
);
1349 dev_err(inno
->dev
, "Cannot enable inno phy sysclk: %d\n", ret
);
1354 * Refpclk needs to be on, on at least the rk3328 for still
1357 ret
= clk_prepare_enable(inno
->refpclk
);
1359 dev_err(inno
->dev
, "failed to enable refpclk\n");
1360 clk_disable_unprepare(inno
->sysclk
);
1364 ret
= devm_add_action_or_reset(inno
->dev
, inno_hdmi_phy_action
,
1369 inno
->regmap
= devm_regmap_init_mmio(inno
->dev
, regs
,
1370 &inno_hdmi_phy_regmap_config
);
1371 if (IS_ERR(inno
->regmap
))
1372 return PTR_ERR(inno
->regmap
);
1374 /* only the newer rk3328 hdmiphy has an interrupt */
1375 inno
->irq
= platform_get_irq(pdev
, 0);
1376 if (inno
->irq
> 0) {
1377 ret
= devm_request_threaded_irq(inno
->dev
, inno
->irq
,
1378 inno_hdmi_phy_rk3328_hardirq
,
1379 inno_hdmi_phy_rk3328_irq
,
1381 dev_name(inno
->dev
), inno
);
1386 inno
->phy
= devm_phy_create(inno
->dev
, NULL
, &inno_hdmi_phy_ops
);
1387 if (IS_ERR(inno
->phy
)) {
1388 dev_err(inno
->dev
, "failed to create HDMI PHY\n");
1389 return PTR_ERR(inno
->phy
);
1392 phy_set_drvdata(inno
->phy
, inno
);
1393 phy_set_bus_width(inno
->phy
, 8);
1395 if (inno
->plat_data
->ops
->init
) {
1396 ret
= inno
->plat_data
->ops
->init(inno
);
1401 ret
= inno_hdmi_phy_clk_register(inno
);
1405 phy_provider
= devm_of_phy_provider_register(inno
->dev
,
1406 of_phy_simple_xlate
);
1407 return PTR_ERR_OR_ZERO(phy_provider
);
1410 static void inno_hdmi_phy_remove(struct platform_device
*pdev
)
1412 of_clk_del_provider(pdev
->dev
.of_node
);
1415 static const struct of_device_id inno_hdmi_phy_of_match
[] = {
1417 .compatible
= "rockchip,rk3228-hdmi-phy",
1418 .data
= &rk3228_hdmi_phy_drv_data
1420 .compatible
= "rockchip,rk3328-hdmi-phy",
1421 .data
= &rk3328_hdmi_phy_drv_data
1422 }, { /* sentinel */ }
1424 MODULE_DEVICE_TABLE(of
, inno_hdmi_phy_of_match
);
1426 static struct platform_driver inno_hdmi_phy_driver
= {
1427 .probe
= inno_hdmi_phy_probe
,
1428 .remove
= inno_hdmi_phy_remove
,
1430 .name
= "inno-hdmi-phy",
1431 .of_match_table
= inno_hdmi_phy_of_match
,
1434 module_platform_driver(inno_hdmi_phy_driver
);
1436 MODULE_AUTHOR("Zheng Yang <zhengyang@rock-chips.com>");
1437 MODULE_DESCRIPTION("Innosilion HDMI 2.0 Transmitter PHY Driver");
1438 MODULE_LICENSE("GPL v2");