1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Zheng Yang <zhengyang@rock-chips.com>
6 * Heiko Stuebner <heiko@sntech.de>
7 */
8
9#include <linux/clk.h>
10#include <linux/clk-provider.h>
11#include <linux/delay.h>
12#include <linux/io.h>
13#include <linux/interrupt.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/nvmem-consumer.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/regmap.h>
20#include <linux/phy/phy.h>
21#include <linux/slab.h>
22
23#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
24
25/* REG: 0x00 */
26#define RK3228_PRE_PLL_REFCLK_SEL_PCLK BIT(0)
27/* REG: 0x01 */
28#define RK3228_BYPASS_RXSENSE_EN BIT(2)
29#define RK3228_BYPASS_PWRON_EN BIT(1)
30#define RK3228_BYPASS_PLLPD_EN BIT(0)
31/* REG: 0x02 */
32#define RK3228_BYPASS_PDATA_EN BIT(4)
33#define RK3228_PDATAEN_DISABLE BIT(0)
34/* REG: 0x03 */
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)
37/* REG: 0x04 */
38#define RK3228_AUTO_TERM_RES_CAL_SPEED_7_0(x) UPDATE(x, 7, 0)
39/* REG: 0xaa */
40#define RK3228_POST_PLL_CTRL_MANUAL BIT(0)
41/* REG: 0xe0 */
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)
48/* REG: 0xe1 */
49#define RK3228_BANDGAP_ENABLE BIT(4)
50#define RK3228_TMDS_DRIVER_ENABLE GENMASK(3, 0)
51/* REG: 0xe2 */
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)
58/* REG: 0xe3 */
59#define RK3228_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
60/* REG: 0xe4 */
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)
66/* REG: 0xe5 */
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)
71/* REG: 0xe6 */
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)
78/* REG: 0xe8 */
79#define RK3228_PRE_PLL_LOCK_STATUS BIT(0)
80/* REG: 0xe9 */
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)
84/* REG: 0xea */
85#define RK3228_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
86/* REG: 0xeb */
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)
92/* REG: 0xee */
93#define RK3228_TMDS_CH_TA_ENABLE GENMASK(7, 4)
94/* REG: 0xef */
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)
99/* REG: 0xf0 */
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)
106/* REG: 0xf1 */
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)
109/* REG: 0xf2 */
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)
112
113/* REG: 0x01 */
114#define RK3328_BYPASS_RXSENSE_EN BIT(2)
115#define RK3328_BYPASS_POWERON_EN BIT(1)
116#define RK3328_BYPASS_PLLPD_EN BIT(0)
117/* REG: 0x02 */
118#define RK3328_INT_POL_HIGH BIT(7)
119#define RK3328_BYPASS_PDATA_EN BIT(4)
120#define RK3328_PDATA_EN BIT(0)
121/* REG:0x05 */
122#define RK3328_INT_TMDS_CLK(x) UPDATE(x, 7, 4)
123#define RK3328_INT_TMDS_D2(x) UPDATE(x, 3, 0)
124/* REG:0x07 */
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)
132/* REG: 0xa0 */
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)
136/* REG: 0xa1 */
137#define RK3328_PRE_PLL_PRE_DIV_MASK GENMASK(5, 0)
138#define RK3328_PRE_PLL_PRE_DIV(x) UPDATE(x, 5, 0)
139/* REG: 0xa2 */
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)
146/* REG: 0xa3 */
147#define RK3328_PRE_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
148/* REG: 0xa4*/
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)
155/* REG: 0xa5 */
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)
161/* REG: 0xa6 */
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)
167/* REG: 0xa9 */
168#define RK3328_PRE_PLL_LOCK_STATUS BIT(0)
169/* REG: 0xaa */
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)
173/* REG:0xab */
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)
176/* REG: 0xac */
177#define RK3328_POST_PLL_FB_DIV_7_0(x) UPDATE(x, 7, 0)
178/* REG: 0xad */
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
183/* REG: 0xaf */
184#define RK3328_POST_PLL_LOCK_STATUS BIT(0)
185/* REG: 0xb0 */
186#define RK3328_BANDGAP_ENABLE BIT(2)
187/* REG: 0xb2 */
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)
196/* REG:0xc5 */
197#define RK3328_BYPASS_TERM_RESISTOR_CALIB BIT(7)
198#define RK3328_TERM_RESISTOR_CALIB_SPEED_14_8(x) UPDATE((x) >> 8, 6, 0)
199/* REG:0xc6 */
200#define RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(x) UPDATE(x, 7, 0)
201/* REG:0xc7 */
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)
220/* REG: 0xd1 */
221#define RK3328_PRE_PLL_FRAC_DIV_23_16(x) UPDATE((x) >> 16, 7, 0)
222/* REG: 0xd2 */
223#define RK3328_PRE_PLL_FRAC_DIV_15_8(x) UPDATE((x) >> 8, 7, 0)
224/* REG: 0xd3 */
225#define RK3328_PRE_PLL_FRAC_DIV_7_0(x) UPDATE(x, 7, 0)
226
227struct inno_hdmi_phy_drv_data;
228
229struct inno_hdmi_phy {
230 struct device *dev;
231 struct regmap *regmap;
232 int irq;
233
234 struct phy *phy;
235 struct clk *sysclk;
236 struct clk *refoclk;
237 struct clk *refpclk;
238
239 /* platform data */
240 const struct inno_hdmi_phy_drv_data *plat_data;
241 int chip_version;
242
243 /* clk provider */
244 struct clk_hw hw;
245 struct clk *phyclk;
246 unsigned long pixclock;
247 unsigned long tmdsclock;
248};
249
250struct pre_pll_config {
251 unsigned long pixclock;
252 unsigned long tmdsclock;
253 u8 prediv;
254 u16 fbdiv;
255 u8 tmds_div_a;
256 u8 tmds_div_b;
257 u8 tmds_div_c;
258 u8 pclk_div_a;
259 u8 pclk_div_b;
260 u8 pclk_div_c;
261 u8 pclk_div_d;
262 u8 vco_div_5_en;
263 u32 fracdiv;
264};
265
266struct post_pll_config {
267 unsigned long tmdsclock;
268 u8 prediv;
269 u16 fbdiv;
270 u8 postdiv;
271 u8 version;
272};
273
274struct phy_config {
275 unsigned long tmdsclock;
276 u8 regs[14];
277};
278
279struct 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);
285};
286
287struct 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;
291};
292
293static 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},
467 { /* sentinel */ }
468};
469
470static 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},
478 { /* sentinel */ }
479};
480
481/* phy tuning values for an undocumented set of registers */
482static const struct phy_config rk3228_phy_cfg[] = {
483 { 165000000, {
484 0xaa, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00,
486 },
487 }, {
488 340000000, {
489 0xaa, 0x15, 0x6a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00,
491 },
492 }, {
493 594000000, {
494 0xaa, 0x15, 0x7a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00,
496 },
497 }, { /* sentinel */ },
498};
499
500/* phy tuning values for an undocumented set of registers */
501static const struct phy_config rk3328_phy_cfg[] = {
502 { 165000000, {
503 0x07, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x08, 0x08,
504 0x00, 0xac, 0xcc, 0xcc, 0xcc,
505 },
506 }, {
507 340000000, {
508 0x0b, 0x0d, 0x0d, 0x0d, 0x07, 0x15, 0x08, 0x08, 0x08,
509 0x3f, 0xac, 0xcc, 0xcd, 0xdd,
510 },
511 }, {
512 594000000, {
513 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08,
514 0x00, 0xac, 0xcc, 0xcc, 0xcc,
515 },
516 }, { /* sentinel */ },
517};
518
519static inline struct inno_hdmi_phy *to_inno_hdmi_phy(struct clk_hw *hw)
520{
521 return container_of(hw, struct inno_hdmi_phy, hw);
522}
523
524/*
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.
529 */
530static inline void inno_write(struct inno_hdmi_phy *inno, u32 reg, u8 val)
531{
532 regmap_write(map: inno->regmap, reg: reg * 4, val);
533}
534
535static inline u8 inno_read(struct inno_hdmi_phy *inno, u32 reg)
536{
537 u32 val;
538
539 regmap_read(map: inno->regmap, reg: reg * 4, val: &val);
540
541 return val;
542}
543
544static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
545 u8 mask, u8 val)
546{
547 regmap_update_bits(map: inno->regmap, reg: reg * 4, mask, val);
548}
549
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)
553
554static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
555 unsigned long rate)
556{
557 int bus_width = phy_get_bus_width(phy: inno->phy);
558
559 switch (bus_width) {
560 case 4:
561 case 5:
562 case 6:
563 case 10:
564 case 12:
565 case 16:
566 return (u64)rate * bus_width / 8;
567 default:
568 return rate;
569 }
570}
571
572static irqreturn_t inno_hdmi_phy_rk3328_hardirq(int irq, void *dev_id)
573{
574 struct inno_hdmi_phy *inno = dev_id;
575 int intr_stat1, intr_stat2, intr_stat3;
576
577 intr_stat1 = inno_read(inno, reg: 0x04);
578 intr_stat2 = inno_read(inno, reg: 0x06);
579 intr_stat3 = inno_read(inno, reg: 0x08);
580
581 if (intr_stat1)
582 inno_write(inno, reg: 0x04, val: intr_stat1);
583 if (intr_stat2)
584 inno_write(inno, reg: 0x06, val: intr_stat2);
585 if (intr_stat3)
586 inno_write(inno, reg: 0x08, val: intr_stat3);
587
588 if (intr_stat1 || intr_stat2 || intr_stat3)
589 return IRQ_WAKE_THREAD;
590
591 return IRQ_HANDLED;
592}
593
594static irqreturn_t inno_hdmi_phy_rk3328_irq(int irq, void *dev_id)
595{
596 struct inno_hdmi_phy *inno = dev_id;
597
598 inno_update_bits(inno, reg: 0x02, RK3328_PDATA_EN, val: 0);
599 usleep_range(min: 10, max: 20);
600 inno_update_bits(inno, reg: 0x02, RK3328_PDATA_EN, RK3328_PDATA_EN);
601
602 return IRQ_HANDLED;
603}
604
605static int inno_hdmi_phy_power_on(struct phy *phy)
606{
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,
611 rate: inno->pixclock);
612 int ret;
613
614 if (!tmdsclock) {
615 dev_err(inno->dev, "TMDS clock is zero!\n");
616 return -EINVAL;
617 }
618
619 if (!inno->plat_data->ops->power_on)
620 return -EINVAL;
621
622 for (; cfg->tmdsclock != 0; cfg++)
623 if (tmdsclock <= cfg->tmdsclock &&
624 cfg->version & inno->chip_version)
625 break;
626
627 for (; phy_cfg->tmdsclock != 0; phy_cfg++)
628 if (tmdsclock <= phy_cfg->tmdsclock)
629 break;
630
631 if (cfg->tmdsclock == 0 || phy_cfg->tmdsclock == 0)
632 return -EINVAL;
633
634 dev_dbg(inno->dev, "Inno HDMI PHY Power On\n");
635
636 inno->plat_data->clk_ops->set_rate(&inno->hw, inno->pixclock, 24000000);
637
638 ret = clk_prepare_enable(clk: inno->phyclk);
639 if (ret)
640 return ret;
641
642 ret = inno->plat_data->ops->power_on(inno, cfg, phy_cfg);
643 if (ret) {
644 clk_disable_unprepare(clk: inno->phyclk);
645 return ret;
646 }
647
648 return 0;
649}
650
651static int inno_hdmi_phy_power_off(struct phy *phy)
652{
653 struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
654
655 if (!inno->plat_data->ops->power_off)
656 return -EINVAL;
657
658 inno->plat_data->ops->power_off(inno);
659
660 clk_disable_unprepare(clk: inno->phyclk);
661
662 inno->tmdsclock = 0;
663
664 dev_dbg(inno->dev, "Inno HDMI PHY Power Off\n");
665
666 return 0;
667}
668
669static 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,
673};
674
675static const
676struct pre_pll_config *inno_hdmi_phy_get_pre_pll_cfg(struct inno_hdmi_phy *inno,
677 unsigned long rate)
678{
679 const struct pre_pll_config *cfg = pre_pll_cfg_table;
680 unsigned long tmdsclock = inno_hdmi_phy_get_tmdsclk(inno, rate);
681
682 for (; cfg->pixclock != 0; cfg++)
683 if (cfg->pixclock == rate && cfg->tmdsclock == tmdsclock)
684 break;
685
686 if (cfg->pixclock == 0)
687 return ERR_PTR(error: -EINVAL);
688
689 return cfg;
690}
691
692static int inno_hdmi_phy_rk3228_clk_is_prepared(struct clk_hw *hw)
693{
694 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
695 u8 status;
696
697 status = inno_read(inno, reg: 0xe0) & RK3228_PRE_PLL_POWER_DOWN;
698 return status ? 0 : 1;
699}
700
701static int inno_hdmi_phy_rk3228_clk_prepare(struct clk_hw *hw)
702{
703 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
704
705 inno_update_bits(inno, reg: 0xe0, RK3228_PRE_PLL_POWER_DOWN, val: 0);
706 return 0;
707}
708
709static void inno_hdmi_phy_rk3228_clk_unprepare(struct clk_hw *hw)
710{
711 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
712
713 inno_update_bits(inno, reg: 0xe0, RK3228_PRE_PLL_POWER_DOWN,
714 RK3228_PRE_PLL_POWER_DOWN);
715}
716
717static
718unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw *hw,
719 unsigned long parent_rate)
720{
721 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
722 u8 nd, no_a, no_b, no_d;
723 u64 vco;
724 u16 nf;
725
726 nd = inno_read(inno, reg: 0xe2) & RK3228_PRE_PLL_PRE_DIV_MASK;
727 nf = (inno_read(inno, reg: 0xe2) & RK3228_PRE_PLL_FB_DIV_8_MASK) << 1;
728 nf |= inno_read(inno, reg: 0xe3);
729 vco = parent_rate * nf;
730
731 if (inno_read(inno, reg: 0xe2) & RK3228_PCLK_VCO_DIV_5_MASK) {
732 do_div(vco, nd * 5);
733 } else {
734 no_a = inno_read(inno, reg: 0xe4) & RK3228_PRE_PLL_PCLK_DIV_A_MASK;
735 if (!no_a)
736 no_a = 1;
737 no_b = inno_read(inno, reg: 0xe4) & RK3228_PRE_PLL_PCLK_DIV_B_MASK;
738 no_b >>= RK3228_PRE_PLL_PCLK_DIV_B_SHIFT;
739 no_b += 2;
740 no_d = inno_read(inno, reg: 0xe5) & RK3228_PRE_PLL_PCLK_DIV_D_MASK;
741
742 do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
743 }
744
745 inno->pixclock = vco;
746
747 dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock);
748
749 return vco;
750}
751
752static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
753 unsigned long rate,
754 unsigned long *parent_rate)
755{
756 const struct pre_pll_config *cfg = pre_pll_cfg_table;
757
758 rate = (rate / 1000) * 1000;
759
760 for (; cfg->pixclock != 0; cfg++)
761 if (cfg->pixclock == rate && !cfg->fracdiv)
762 break;
763
764 if (cfg->pixclock == 0)
765 return -EINVAL;
766
767 return cfg->pixclock;
768}
769
770static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
771 unsigned long rate,
772 unsigned long parent_rate)
773{
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);
777 u32 v;
778 int ret;
779
780 dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
781 __func__, rate, tmdsclock);
782
783 if (inno->pixclock == rate && inno->tmdsclock == tmdsclock)
784 return 0;
785
786 cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate);
787 if (IS_ERR(ptr: cfg))
788 return PTR_ERR(ptr: cfg);
789
790 /* Power down PRE-PLL */
791 inno_update_bits(inno, reg: 0xe0, RK3228_PRE_PLL_POWER_DOWN,
792 RK3228_PRE_PLL_POWER_DOWN);
793
794 inno_update_bits(inno, reg: 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, reg: 0xe3, RK3228_PRE_PLL_FB_DIV_7_0(cfg->fbdiv));
801 inno_update_bits(inno, reg: 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, reg: 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, reg: 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));
815
816 /* Power up PRE-PLL */
817 inno_update_bits(inno, reg: 0xe0, RK3228_PRE_PLL_POWER_DOWN, val: 0);
818
819 /* Wait for Pre-PLL lock */
820 ret = inno_poll(inno, 0xe8, v, v & RK3228_PRE_PLL_LOCK_STATUS,
821 100, 100000);
822 if (ret) {
823 dev_err(inno->dev, "Pre-PLL locking failed\n");
824 return ret;
825 }
826
827 inno->pixclock = rate;
828 inno->tmdsclock = tmdsclock;
829
830 return 0;
831}
832
833static 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,
840};
841
842static int inno_hdmi_phy_rk3328_clk_is_prepared(struct clk_hw *hw)
843{
844 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
845 u8 status;
846
847 status = inno_read(inno, reg: 0xa0) & RK3328_PRE_PLL_POWER_DOWN;
848 return status ? 0 : 1;
849}
850
851static int inno_hdmi_phy_rk3328_clk_prepare(struct clk_hw *hw)
852{
853 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
854
855 inno_update_bits(inno, reg: 0xa0, RK3328_PRE_PLL_POWER_DOWN, val: 0);
856 return 0;
857}
858
859static void inno_hdmi_phy_rk3328_clk_unprepare(struct clk_hw *hw)
860{
861 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
862
863 inno_update_bits(inno, reg: 0xa0, RK3328_PRE_PLL_POWER_DOWN,
864 RK3328_PRE_PLL_POWER_DOWN);
865}
866
867static
868unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
869 unsigned long parent_rate)
870{
871 struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw);
872 unsigned long frac;
873 u8 nd, no_a, no_b, no_d;
874 u64 vco;
875 u16 nf;
876
877 nd = inno_read(inno, reg: 0xa1) & RK3328_PRE_PLL_PRE_DIV_MASK;
878 nf = ((inno_read(inno, reg: 0xa2) & RK3328_PRE_PLL_FB_DIV_11_8_MASK) << 8);
879 nf |= inno_read(inno, reg: 0xa3);
880 vco = parent_rate * nf;
881
882 if (!(inno_read(inno, reg: 0xa2) & RK3328_PRE_PLL_FRAC_DIV_DISABLE)) {
883 frac = inno_read(inno, reg: 0xd3) |
884 (inno_read(inno, reg: 0xd2) << 8) |
885 (inno_read(inno, reg: 0xd1) << 16);
886 vco += DIV_ROUND_CLOSEST(parent_rate * frac, (1 << 24));
887 }
888
889 if (inno_read(inno, reg: 0xa0) & RK3328_PCLK_VCO_DIV_5_MASK) {
890 do_div(vco, nd * 5);
891 } else {
892 no_a = inno_read(inno, reg: 0xa5) & RK3328_PRE_PLL_PCLK_DIV_A_MASK;
893 no_b = inno_read(inno, reg: 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK;
894 no_b >>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT;
895 no_b += 2;
896 no_d = inno_read(inno, reg: 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK;
897
898 do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2));
899 }
900
901 inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000;
902
903 dev_dbg(inno->dev, "%s rate %lu vco %llu\n",
904 __func__, inno->pixclock, vco);
905
906 return inno->pixclock;
907}
908
909static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
910 unsigned long rate,
911 unsigned long *parent_rate)
912{
913 const struct pre_pll_config *cfg = pre_pll_cfg_table;
914
915 rate = (rate / 1000) * 1000;
916
917 for (; cfg->pixclock != 0; cfg++)
918 if (cfg->pixclock == rate)
919 break;
920
921 if (cfg->pixclock == 0)
922 return -EINVAL;
923
924 return cfg->pixclock;
925}
926
927static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
928 unsigned long rate,
929 unsigned long parent_rate)
930{
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);
934 u32 val;
935 int ret;
936
937 dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
938 __func__, rate, tmdsclock);
939
940 if (inno->pixclock == rate && inno->tmdsclock == tmdsclock)
941 return 0;
942
943 cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate);
944 if (IS_ERR(ptr: cfg))
945 return PTR_ERR(ptr: cfg);
946
947 inno_update_bits(inno, reg: 0xa0, RK3328_PRE_PLL_POWER_DOWN,
948 RK3328_PRE_PLL_POWER_DOWN);
949
950 /* Configure pre-pll */
951 inno_update_bits(inno, reg: 0xa0, RK3328_PCLK_VCO_DIV_5_MASK,
952 RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en));
953 inno_write(inno, reg: 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv));
954
955 val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE;
956 if (!cfg->fracdiv)
957 val |= RK3328_PRE_PLL_FRAC_DIV_DISABLE;
958 inno_write(inno, reg: 0xa2, RK3328_PRE_PLL_FB_DIV_11_8(cfg->fbdiv) | val);
959 inno_write(inno, reg: 0xa3, RK3328_PRE_PLL_FB_DIV_7_0(cfg->fbdiv));
960 inno_write(inno, reg: 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, reg: 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, reg: 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, reg: 0xd3, RK3328_PRE_PLL_FRAC_DIV_7_0(cfg->fracdiv));
968 inno_write(inno, reg: 0xd2, RK3328_PRE_PLL_FRAC_DIV_15_8(cfg->fracdiv));
969 inno_write(inno, reg: 0xd1, RK3328_PRE_PLL_FRAC_DIV_23_16(cfg->fracdiv));
970
971 inno_update_bits(inno, reg: 0xa0, RK3328_PRE_PLL_POWER_DOWN, val: 0);
972
973 /* Wait for Pre-PLL lock */
974 ret = inno_poll(inno, 0xa9, val, val & RK3328_PRE_PLL_LOCK_STATUS,
975 1000, 10000);
976 if (ret) {
977 dev_err(inno->dev, "Pre-PLL locking failed\n");
978 return ret;
979 }
980
981 inno->pixclock = rate;
982 inno->tmdsclock = tmdsclock;
983
984 return 0;
985}
986
987static 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,
994};
995
996static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno)
997{
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;
1002 int ret;
1003
1004 parent_name = __clk_get_name(clk: inno->refoclk);
1005
1006 init.parent_names = &parent_name;
1007 init.num_parents = 1;
1008 init.flags = 0;
1009 init.name = "pin_hd20_pclk";
1010 init.ops = inno->plat_data->clk_ops;
1011
1012 /* optional override of the clock name */
1013 of_property_read_string(np, propname: "clock-output-names", out_string: &init.name);
1014
1015 inno->hw.init = &init;
1016
1017 inno->phyclk = devm_clk_register(dev, hw: &inno->hw);
1018 if (IS_ERR(ptr: inno->phyclk)) {
1019 ret = PTR_ERR(ptr: inno->phyclk);
1020 dev_err(dev, "failed to register clock: %d\n", ret);
1021 return ret;
1022 }
1023
1024 ret = of_clk_add_provider(np, clk_src_get: of_clk_src_simple_get, data: inno->phyclk);
1025 if (ret) {
1026 dev_err(dev, "failed to register clock provider: %d\n", ret);
1027 return ret;
1028 }
1029
1030 return 0;
1031}
1032
1033static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno)
1034{
1035 /*
1036 * Use phy internal register control
1037 * rxsense/poweron/pllpd/pdataen signal.
1038 */
1039 inno_write(inno, reg: 0x01, RK3228_BYPASS_RXSENSE_EN |
1040 RK3228_BYPASS_PWRON_EN |
1041 RK3228_BYPASS_PLLPD_EN);
1042 inno_update_bits(inno, reg: 0x02, RK3228_BYPASS_PDATA_EN,
1043 RK3228_BYPASS_PDATA_EN);
1044
1045 /* manual power down post-PLL */
1046 inno_update_bits(inno, reg: 0xaa, RK3228_POST_PLL_CTRL_MANUAL,
1047 RK3228_POST_PLL_CTRL_MANUAL);
1048
1049 inno->chip_version = 1;
1050
1051 return 0;
1052}
1053
1054static int
1055inno_hdmi_phy_rk3228_power_on(struct inno_hdmi_phy *inno,
1056 const struct post_pll_config *cfg,
1057 const struct phy_config *phy_cfg)
1058{
1059 int ret;
1060 u32 v;
1061
1062 inno_update_bits(inno, reg: 0x02, RK3228_PDATAEN_DISABLE,
1063 RK3228_PDATAEN_DISABLE);
1064 inno_update_bits(inno, reg: 0xe0, RK3228_PRE_PLL_POWER_DOWN |
1065 RK3228_POST_PLL_POWER_DOWN,
1066 RK3228_PRE_PLL_POWER_DOWN |
1067 RK3228_POST_PLL_POWER_DOWN);
1068
1069 /* Post-PLL update */
1070 inno_update_bits(inno, reg: 0xe9, RK3228_POST_PLL_PRE_DIV_MASK,
1071 RK3228_POST_PLL_PRE_DIV(cfg->prediv));
1072 inno_update_bits(inno, reg: 0xeb, RK3228_POST_PLL_FB_DIV_8_MASK,
1073 RK3228_POST_PLL_FB_DIV_8(cfg->fbdiv));
1074 inno_write(inno, reg: 0xea, RK3228_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
1075
1076 if (cfg->postdiv == 1) {
1077 inno_update_bits(inno, reg: 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE,
1078 val: 0);
1079 } else {
1080 int div = cfg->postdiv / 2 - 1;
1081
1082 inno_update_bits(inno, reg: 0xe9, RK3228_POST_PLL_POST_DIV_ENABLE,
1083 RK3228_POST_PLL_POST_DIV_ENABLE);
1084 inno_update_bits(inno, reg: 0xeb, RK3228_POST_PLL_POST_DIV_MASK,
1085 RK3228_POST_PLL_POST_DIV(div));
1086 }
1087
1088 for (v = 0; v < 4; v++)
1089 inno_write(inno, reg: 0xef + v, val: phy_cfg->regs[v]);
1090
1091 inno_update_bits(inno, reg: 0xe0, RK3228_PRE_PLL_POWER_DOWN |
1092 RK3228_POST_PLL_POWER_DOWN, val: 0);
1093 inno_update_bits(inno, reg: 0xe1, RK3228_BANDGAP_ENABLE,
1094 RK3228_BANDGAP_ENABLE);
1095 inno_update_bits(inno, reg: 0xe1, RK3228_TMDS_DRIVER_ENABLE,
1096 RK3228_TMDS_DRIVER_ENABLE);
1097
1098 /* Wait for post PLL lock */
1099 ret = inno_poll(inno, 0xeb, v, v & RK3228_POST_PLL_LOCK_STATUS,
1100 100, 100000);
1101 if (ret) {
1102 dev_err(inno->dev, "Post-PLL locking failed\n");
1103 return ret;
1104 }
1105
1106 if (cfg->tmdsclock > 340000000)
1107 msleep(msecs: 100);
1108
1109 inno_update_bits(inno, reg: 0x02, RK3228_PDATAEN_DISABLE, val: 0);
1110 return 0;
1111}
1112
1113static void inno_hdmi_phy_rk3228_power_off(struct inno_hdmi_phy *inno)
1114{
1115 inno_update_bits(inno, reg: 0xe1, RK3228_TMDS_DRIVER_ENABLE, val: 0);
1116 inno_update_bits(inno, reg: 0xe1, RK3228_BANDGAP_ENABLE, val: 0);
1117 inno_update_bits(inno, reg: 0xe0, RK3228_POST_PLL_POWER_DOWN,
1118 RK3228_POST_PLL_POWER_DOWN);
1119}
1120
1121static 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,
1125};
1126
1127static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno)
1128{
1129 struct nvmem_cell *cell;
1130 unsigned char *efuse_buf;
1131 size_t len;
1132
1133 /*
1134 * Use phy internal register control
1135 * rxsense/poweron/pllpd/pdataen signal.
1136 */
1137 inno_write(inno, reg: 0x01, RK3328_BYPASS_RXSENSE_EN |
1138 RK3328_BYPASS_POWERON_EN |
1139 RK3328_BYPASS_PLLPD_EN);
1140 inno_write(inno, reg: 0x02, RK3328_INT_POL_HIGH | RK3328_BYPASS_PDATA_EN |
1141 RK3328_PDATA_EN);
1142
1143 /* Disable phy irq */
1144 inno_write(inno, reg: 0x05, val: 0);
1145 inno_write(inno, reg: 0x07, val: 0);
1146
1147 /* try to read the chip-version */
1148 inno->chip_version = 1;
1149 cell = nvmem_cell_get(dev: inno->dev, id: "cpu-version");
1150 if (IS_ERR(ptr: cell)) {
1151 if (PTR_ERR(ptr: cell) == -EPROBE_DEFER)
1152 return -EPROBE_DEFER;
1153
1154 return 0;
1155 }
1156
1157 efuse_buf = nvmem_cell_read(cell, len: &len);
1158 nvmem_cell_put(cell);
1159
1160 if (IS_ERR(ptr: efuse_buf))
1161 return 0;
1162 if (len == 1)
1163 inno->chip_version = efuse_buf[0] + 1;
1164 kfree(objp: efuse_buf);
1165
1166 return 0;
1167}
1168
1169static int
1170inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno,
1171 const struct post_pll_config *cfg,
1172 const struct phy_config *phy_cfg)
1173{
1174 int ret;
1175 u32 v;
1176
1177 inno_update_bits(inno, reg: 0x02, RK3328_PDATA_EN, val: 0);
1178 inno_update_bits(inno, reg: 0xaa, RK3328_POST_PLL_POWER_DOWN,
1179 RK3328_POST_PLL_POWER_DOWN);
1180
1181 inno_write(inno, reg: 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv));
1182 if (cfg->postdiv == 1) {
1183 inno_write(inno, reg: 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
1184 RK3328_POST_PLL_PRE_DIV(cfg->prediv));
1185 inno_write(inno, reg: 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS |
1186 RK3328_POST_PLL_POWER_DOWN);
1187 } else {
1188 v = (cfg->postdiv / 2) - 1;
1189 v &= RK3328_POST_PLL_POST_DIV_MASK;
1190 inno_write(inno, reg: 0xad, val: v);
1191 inno_write(inno, reg: 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) |
1192 RK3328_POST_PLL_PRE_DIV(cfg->prediv));
1193 inno_write(inno, reg: 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE |
1194 RK3328_POST_PLL_REFCLK_SEL_TMDS |
1195 RK3328_POST_PLL_POWER_DOWN);
1196 }
1197
1198 for (v = 0; v < 14; v++)
1199 inno_write(inno, reg: 0xb5 + v, val: phy_cfg->regs[v]);
1200
1201 /* set ESD detection threshold for TMDS CLK, D2, D1 and D0 */
1202 for (v = 0; v < 4; v++)
1203 inno_update_bits(inno, reg: 0xc8 + v, RK3328_ESD_DETECT_MASK,
1204 RK3328_ESD_DETECT_340MV);
1205
1206 if (phy_cfg->tmdsclock > 340000000) {
1207 /* Set termination resistor to 100ohm */
1208 v = clk_get_rate(clk: inno->sysclk) / 100000;
1209 inno_write(inno, reg: 0xc5, RK3328_TERM_RESISTOR_CALIB_SPEED_14_8(v)
1210 | RK3328_BYPASS_TERM_RESISTOR_CALIB);
1211 inno_write(inno, reg: 0xc6, RK3328_TERM_RESISTOR_CALIB_SPEED_7_0(v));
1212 inno_write(inno, reg: 0xc7, RK3328_TERM_RESISTOR_100);
1213 inno_update_bits(inno, reg: 0xc5,
1214 RK3328_BYPASS_TERM_RESISTOR_CALIB, val: 0);
1215 } else {
1216 inno_write(inno, reg: 0xc5, RK3328_BYPASS_TERM_RESISTOR_CALIB);
1217
1218 /* clk termination resistor is 50ohm (parallel resistors) */
1219 if (phy_cfg->tmdsclock > 165000000)
1220 inno_update_bits(inno, reg: 0xc8,
1221 RK3328_TMDS_TERM_RESIST_MASK,
1222 RK3328_TMDS_TERM_RESIST_75 |
1223 RK3328_TMDS_TERM_RESIST_150);
1224
1225 /* data termination resistor for D2, D1 and D0 is 150ohm */
1226 for (v = 0; v < 3; v++)
1227 inno_update_bits(inno, reg: 0xc9 + v,
1228 RK3328_TMDS_TERM_RESIST_MASK,
1229 RK3328_TMDS_TERM_RESIST_150);
1230 }
1231
1232 inno_update_bits(inno, reg: 0xaa, RK3328_POST_PLL_POWER_DOWN, val: 0);
1233 inno_update_bits(inno, reg: 0xb0, RK3328_BANDGAP_ENABLE,
1234 RK3328_BANDGAP_ENABLE);
1235 inno_update_bits(inno, reg: 0xb2, RK3328_TMDS_DRIVER_ENABLE,
1236 RK3328_TMDS_DRIVER_ENABLE);
1237
1238 /* Wait for post PLL lock */
1239 ret = inno_poll(inno, 0xaf, v, v & RK3328_POST_PLL_LOCK_STATUS,
1240 1000, 10000);
1241 if (ret) {
1242 dev_err(inno->dev, "Post-PLL locking failed\n");
1243 return ret;
1244 }
1245
1246 if (phy_cfg->tmdsclock > 340000000)
1247 msleep(msecs: 100);
1248
1249 inno_update_bits(inno, reg: 0x02, RK3328_PDATA_EN, RK3328_PDATA_EN);
1250
1251 /* Enable PHY IRQ */
1252 inno_write(inno, reg: 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, reg: 0x07, RK3328_INT_TMDS_D1(RK3328_INT_VSS_AGND_ESD_DET)
1255 | RK3328_INT_TMDS_D0(RK3328_INT_VSS_AGND_ESD_DET));
1256 return 0;
1257}
1258
1259static void inno_hdmi_phy_rk3328_power_off(struct inno_hdmi_phy *inno)
1260{
1261 inno_update_bits(inno, reg: 0xb2, RK3328_TMDS_DRIVER_ENABLE, val: 0);
1262 inno_update_bits(inno, reg: 0xb0, RK3328_BANDGAP_ENABLE, val: 0);
1263 inno_update_bits(inno, reg: 0xaa, RK3328_POST_PLL_POWER_DOWN,
1264 RK3328_POST_PLL_POWER_DOWN);
1265
1266 /* Disable PHY IRQ */
1267 inno_write(inno, reg: 0x05, val: 0);
1268 inno_write(inno, reg: 0x07, val: 0);
1269}
1270
1271static 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,
1275};
1276
1277static 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,
1281};
1282
1283static 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,
1287};
1288
1289static const struct regmap_config inno_hdmi_phy_regmap_config = {
1290 .reg_bits = 32,
1291 .val_bits = 32,
1292 .reg_stride = 4,
1293 .max_register = 0x400,
1294};
1295
1296static void inno_hdmi_phy_action(void *data)
1297{
1298 struct inno_hdmi_phy *inno = data;
1299
1300 clk_disable_unprepare(clk: inno->refpclk);
1301 clk_disable_unprepare(clk: inno->sysclk);
1302}
1303
1304static int inno_hdmi_phy_probe(struct platform_device *pdev)
1305{
1306 struct inno_hdmi_phy *inno;
1307 struct phy_provider *phy_provider;
1308 void __iomem *regs;
1309 int ret;
1310
1311 inno = devm_kzalloc(dev: &pdev->dev, size: sizeof(*inno), GFP_KERNEL);
1312 if (!inno)
1313 return -ENOMEM;
1314
1315 inno->dev = &pdev->dev;
1316
1317 inno->plat_data = of_device_get_match_data(dev: inno->dev);
1318 if (!inno->plat_data || !inno->plat_data->ops)
1319 return -EINVAL;
1320
1321 regs = devm_platform_ioremap_resource(pdev, index: 0);
1322 if (IS_ERR(ptr: regs))
1323 return PTR_ERR(ptr: regs);
1324
1325 inno->sysclk = devm_clk_get(dev: inno->dev, id: "sysclk");
1326 if (IS_ERR(ptr: inno->sysclk)) {
1327 ret = PTR_ERR(ptr: inno->sysclk);
1328 dev_err(inno->dev, "failed to get sysclk: %d\n", ret);
1329 return ret;
1330 }
1331
1332 inno->refpclk = devm_clk_get(dev: inno->dev, id: "refpclk");
1333 if (IS_ERR(ptr: inno->refpclk)) {
1334 ret = PTR_ERR(ptr: inno->refpclk);
1335 dev_err(inno->dev, "failed to get ref clock: %d\n", ret);
1336 return ret;
1337 }
1338
1339 inno->refoclk = devm_clk_get(dev: inno->dev, id: "refoclk");
1340 if (IS_ERR(ptr: inno->refoclk)) {
1341 ret = PTR_ERR(ptr: inno->refoclk);
1342 dev_err(inno->dev, "failed to get oscillator-ref clock: %d\n",
1343 ret);
1344 return ret;
1345 }
1346
1347 ret = clk_prepare_enable(clk: inno->sysclk);
1348 if (ret) {
1349 dev_err(inno->dev, "Cannot enable inno phy sysclk: %d\n", ret);
1350 return ret;
1351 }
1352
1353 /*
1354 * Refpclk needs to be on, on at least the rk3328 for still
1355 * unknown reasons.
1356 */
1357 ret = clk_prepare_enable(clk: inno->refpclk);
1358 if (ret) {
1359 dev_err(inno->dev, "failed to enable refpclk\n");
1360 clk_disable_unprepare(clk: inno->sysclk);
1361 return ret;
1362 }
1363
1364 ret = devm_add_action_or_reset(inno->dev, inno_hdmi_phy_action,
1365 inno);
1366 if (ret)
1367 return ret;
1368
1369 inno->regmap = devm_regmap_init_mmio(inno->dev, regs,
1370 &inno_hdmi_phy_regmap_config);
1371 if (IS_ERR(ptr: inno->regmap))
1372 return PTR_ERR(ptr: inno->regmap);
1373
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(dev: inno->dev, irq: inno->irq,
1378 handler: inno_hdmi_phy_rk3328_hardirq,
1379 thread_fn: inno_hdmi_phy_rk3328_irq,
1380 IRQF_SHARED,
1381 devname: dev_name(dev: inno->dev), dev_id: inno);
1382 if (ret)
1383 return ret;
1384 }
1385
1386 inno->phy = devm_phy_create(dev: inno->dev, NULL, ops: &inno_hdmi_phy_ops);
1387 if (IS_ERR(ptr: inno->phy)) {
1388 dev_err(inno->dev, "failed to create HDMI PHY\n");
1389 return PTR_ERR(ptr: inno->phy);
1390 }
1391
1392 phy_set_drvdata(phy: inno->phy, data: inno);
1393 phy_set_bus_width(phy: inno->phy, bus_width: 8);
1394
1395 if (inno->plat_data->ops->init) {
1396 ret = inno->plat_data->ops->init(inno);
1397 if (ret)
1398 return ret;
1399 }
1400
1401 ret = inno_hdmi_phy_clk_register(inno);
1402 if (ret)
1403 return ret;
1404
1405 phy_provider = devm_of_phy_provider_register(inno->dev,
1406 of_phy_simple_xlate);
1407 return PTR_ERR_OR_ZERO(ptr: phy_provider);
1408}
1409
1410static void inno_hdmi_phy_remove(struct platform_device *pdev)
1411{
1412 of_clk_del_provider(np: pdev->dev.of_node);
1413}
1414
1415static const struct of_device_id inno_hdmi_phy_of_match[] = {
1416 {
1417 .compatible = "rockchip,rk3228-hdmi-phy",
1418 .data = &rk3228_hdmi_phy_drv_data
1419 }, {
1420 .compatible = "rockchip,rk3328-hdmi-phy",
1421 .data = &rk3328_hdmi_phy_drv_data
1422 }, { /* sentinel */ }
1423};
1424MODULE_DEVICE_TABLE(of, inno_hdmi_phy_of_match);
1425
1426static struct platform_driver inno_hdmi_phy_driver = {
1427 .probe = inno_hdmi_phy_probe,
1428 .remove_new = inno_hdmi_phy_remove,
1429 .driver = {
1430 .name = "inno-hdmi-phy",
1431 .of_match_table = inno_hdmi_phy_of_match,
1432 },
1433};
1434module_platform_driver(inno_hdmi_phy_driver);
1435
1436MODULE_AUTHOR("Zheng Yang <zhengyang@rock-chips.com>");
1437MODULE_DESCRIPTION("Innosilion HDMI 2.0 Transmitter PHY Driver");
1438MODULE_LICENSE("GPL v2");
1439

source code of linux/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c