1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Chen Shunqing <csq@rock-chips.com>
6 */
7 #include <linux/gpio/consumer.h>
8 #include <linux/of_device.h>
9
10 #include "rk628.h"
11 #include "rk628_combrxphy.h"
12 #include "rk628_config.h"
13 #include "rk628_hdmirx.h"
14
15 #define POLL_INTERVAL_MS 1000
16 #define MODETCLK_CNT_NUM 1000
17 #define MODETCLK_HZ 49500000
18 #define RXPHY_CFG_MAX_TIMES 1
19
20 static u8 debug;
21
22 static u8 edid_init_data[] = {
23 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
24 0x49, 0x78, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
25 0x12, 0x1E, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78,
26 0x0A, 0x0D, 0xC9, 0xA0, 0x57, 0x47, 0x98, 0x27,
27 0x12, 0x48, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x01,
28 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
29 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A,
30 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
31 0x45, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E,
32 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x50,
35 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x6F, 0x72,
36 0x0A, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFD,
37 0x00, 0x14, 0x78, 0x01, 0xFF, 0x1D, 0x00, 0x0A,
38 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x18,
39
40 0x02, 0x03, 0x13, 0x71, 0x40, 0x23, 0x09, 0x07,
41 0x01, 0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0C,
42 0x00, 0x10, 0x00, 0x02, 0x3A, 0x80, 0x18, 0x71,
43 0x38, 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x20,
44 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
56
57 };
58
59 struct rk628_hdmi_mode {
60 u32 hdisplay;
61 u32 hstart;
62 u32 hend;
63 u32 htotal;
64 u32 vdisplay;
65 u32 vstart;
66 u32 vend;
67 u32 vtotal;
68 u32 clock;
69 unsigned int flags;
70 };
71
72 struct rk628_hdmirx {
73 bool plugin;
74 bool res_change;
75 struct rk628_hdmi_mode mode;
76 u32 input_format;
77 u32 fs_audio;
78 bool audio_present;
79 bool hpd_output_inverted;
80 bool src_mode_4K_yuv420;
81 bool phy_lock;
82 };
83
rk628_hdmirx_ctrl_enable(struct rk628 * rk628)84 static void rk628_hdmirx_ctrl_enable(struct rk628 *rk628)
85 {
86
87 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
88 SW_INPUT_MODE_MASK,
89 SW_INPUT_MODE(INPUT_MODE_HDMI));
90
91 rk628_i2c_write(rk628, HDMI_RX_HDMI20_CONTROL, 0x10001f10);
92 rk628_i2c_write(rk628, HDMI_RX_HDMI_MODE_RECOVER, 0x00000021);
93 rk628_i2c_write(rk628, HDMI_RX_PDEC_CTRL, 0xbfff8011);
94 rk628_i2c_write(rk628, HDMI_RX_PDEC_ASP_CTRL, 0x00000040);
95 rk628_i2c_write(rk628, HDMI_RX_HDMI_RESMPL_CTRL, 0x00000001);
96 rk628_i2c_write(rk628, HDMI_RX_HDMI_SYNC_CTRL, 0x00000014);
97 rk628_i2c_write(rk628, HDMI_RX_PDEC_ERR_FILTER, 0x00000008);
98 rk628_i2c_write(rk628, HDMI_RX_SCDC_I2CCONFIG, 0x01000000);
99 rk628_i2c_write(rk628, HDMI_RX_SCDC_CONFIG, 0x00000001);
100 rk628_i2c_write(rk628, HDMI_RX_SCDC_WRDATA0, 0xabcdef01);
101 rk628_i2c_write(rk628, HDMI_RX_CHLOCK_CONFIG, 0x0030c15c);
102 rk628_i2c_write(rk628, HDMI_RX_HDMI_ERROR_PROTECT, 0x000d0c98);
103 rk628_i2c_write(rk628, HDMI_RX_MD_HCTRL1, 0x00000010);
104 rk628_i2c_write(rk628, HDMI_RX_MD_HCTRL2, 0x00001738);
105 rk628_i2c_write(rk628, HDMI_RX_MD_VCTRL, 0x00000002);
106 rk628_i2c_write(rk628, HDMI_RX_MD_VTH, 0x0000073a);
107 rk628_i2c_write(rk628, HDMI_RX_MD_IL_POL, 0x00000004);
108 rk628_i2c_write(rk628, HDMI_RX_PDEC_ACRM_CTRL, 0x00000000);
109 rk628_i2c_write(rk628, HDMI_RX_HDMI_DCM_CTRL, 0x00040414);
110 rk628_i2c_write(rk628, HDMI_RX_HDMI_CKM_EVLTM, 0x00103e70);
111 rk628_i2c_write(rk628, HDMI_RX_HDMI_CKM_F, 0x0c1c0b54);
112 rk628_i2c_write(rk628, HDMI_RX_HDMI_RESMPL_CTRL, 0x00000001);
113
114 rk628_i2c_update_bits(rk628, HDMI_RX_HDCP_SETTINGS,
115 HDMI_RESERVED_MASK |
116 FAST_I2C_MASK |
117 ONE_DOT_ONE_MASK |
118 FAST_REAUTH_MASK,
119 HDMI_RESERVED(1) |
120 FAST_I2C(0) |
121 ONE_DOT_ONE(1) |
122 FAST_REAUTH(1));
123 }
124
rk628_hdmirx_video_unmute(struct rk628 * rk628,u8 unmute)125 static void rk628_hdmirx_video_unmute(struct rk628 *rk628, u8 unmute)
126 {
127 rk628_i2c_update_bits(rk628, HDMI_RX_DMI_DISABLE_IF, VID_ENABLE_MASK, VID_ENABLE(unmute));
128 }
129
rk628_hdmirx_hpd_ctrl(struct rk628 * rk628,bool en)130 static void rk628_hdmirx_hpd_ctrl(struct rk628 *rk628, bool en)
131 {
132 u8 en_level, set_level;
133 struct rk628_hdmirx *hdmirx = rk628->hdmirx;
134
135 dev_dbg(rk628->dev, "%s: %sable, hpd invert:%d\n", __func__,
136 en ? "en" : "dis", hdmirx->hpd_output_inverted);
137 en_level = hdmirx->hpd_output_inverted ? 0 : 1;
138 set_level = en ? en_level : !en_level;
139 rk628_i2c_update_bits(rk628, HDMI_RX_HDMI_SETUP_CTRL,
140 HOT_PLUG_DETECT_MASK, HOT_PLUG_DETECT(set_level));
141 }
142
rk628_hdmirx_disable_edid(struct rk628 * rk628)143 static void rk628_hdmirx_disable_edid(struct rk628 *rk628)
144 {
145 rk628_hdmirx_hpd_ctrl(rk628, false);
146 rk628_hdmirx_video_unmute(rk628, 0);
147 }
148
rk628_hdmirx_enable_edid(struct rk628 * rk628)149 static void rk628_hdmirx_enable_edid(struct rk628 *rk628)
150 {
151 rk628_hdmirx_hpd_ctrl(rk628, true);
152 }
153
tx_5v_power_present(struct rk628 * rk628)154 static int tx_5v_power_present(struct rk628 *rk628)
155 {
156 bool ret;
157 int val, i, cnt;
158
159 /* Direct Mode */
160 if (!rk628->plugin_det_gpio)
161 return 1;
162
163 cnt = 0;
164 for (i = 0; i < 5; i++) {
165 val = gpiod_get_value(rk628->plugin_det_gpio);
166 if (val > 0)
167 cnt++;
168 usleep_range(500, 600);
169 }
170
171 ret = (cnt >= 3) ? 1 : 0;
172 dev_dbg(rk628->dev, "%s: %d\n", __func__, ret);
173
174 return ret;
175 }
176
rk628_hdmirx_init_edid(struct rk628 * rk628)177 static int rk628_hdmirx_init_edid(struct rk628 *rk628)
178 {
179 struct rk628_display_mode *src_mode;
180 struct rk628_hdmirx *hdmirx = rk628->hdmirx;
181 u32 val;
182 u8 csum = 0;
183 int i, base, j;
184
185 src_mode = rk628_display_get_src_mode(rk628);
186 for (j = 0, base = 0x36; j < 2; j++) {
187 csum = 0;
188 /* clock-frequency */
189 edid_init_data[base + 1] = ((src_mode->clock / 10) & 0xff00) >> 8;
190 edid_init_data[base] = (src_mode->clock / 10) & 0xff;
191 /* hactive low 8 bits */
192 edid_init_data[base + 2] = src_mode->hdisplay & 0xff;
193
194 /* hblanking low 8 bits */
195 val = src_mode->htotal - src_mode->hdisplay;
196 edid_init_data[base + 3] = val & 0xff;
197
198 /* hactive high 4 bits & hblanking low 4 bits */
199 edid_init_data[base + 4] =
200 ((src_mode->hdisplay & 0xf00) >> 4) + ((val & 0xf00) >> 8);
201
202 /* vactive low 8 bits */
203 edid_init_data[base + 5] = src_mode->vdisplay & 0xff;
204
205 /* vblanking low 8 bits */
206 val = src_mode->vtotal - src_mode->vdisplay;
207 edid_init_data[base + 6] = val & 0xff;
208
209 /* vactive high 4 bits & vblanking low 4 bits */
210 edid_init_data[base + 7] =
211 ((src_mode->vdisplay & 0xf00) >> 4) + ((val & 0xf00) >> 8);
212
213 /* hsync pulse offset low 8 bits */
214 val = src_mode->hsync_start - src_mode->hdisplay;
215 edid_init_data[base + 8] = val & 0xff;
216
217 /* hsync pulse width low 8 bits */
218 val = src_mode->hsync_end - src_mode->hsync_start;
219 edid_init_data[base + 9] = val & 0xff;
220
221 /* vsync pulse offset low 4 bits & vsync pulse width low 4 bits */
222 val = ((src_mode->vsync_start - src_mode->vdisplay) & 0xf) << 4;
223 edid_init_data[base + 10] = val;
224 edid_init_data[base + 10] += (src_mode->vsync_end - src_mode->vsync_start) & 0xf;
225
226 /* 6~7bits:hsync pulse offset;
227 * 4~6bits:hsync pulse width;
228 * 2~3bits:vsync pulse offset;
229 * 0~1bits:vsync pulse width
230 */
231 edid_init_data[base + 11] =
232 ((src_mode->hsync_start - src_mode->hdisplay) & 0x300) >> 2;
233 edid_init_data[base + 11] +=
234 ((src_mode->hsync_end - src_mode->hsync_start) & 0x700) >> 4;
235 edid_init_data[base + 11] +=
236 ((src_mode->vsync_start - src_mode->vdisplay) & 0x30) >> 2;
237 edid_init_data[base + 11] +=
238 ((src_mode->vsync_end - src_mode->vsync_start) & 0x30) >> 4;
239
240 edid_init_data[base + 17] = 0x18;
241 if (src_mode->flags & DRM_MODE_FLAG_PHSYNC)
242 edid_init_data[base + 17] |= 0x2;
243
244 if (src_mode->flags & DRM_MODE_FLAG_PVSYNC)
245 edid_init_data[base + 17] |= 0x4;
246
247 if (hdmirx->src_mode_4K_yuv420 && src_mode->clock == 594000) {
248 edid_init_data[0x80 + 0x2] = 0x16;
249 edid_init_data[0x80 + 0x13] = 0xe2;
250 edid_init_data[0x80 + 0x14] = 0x0E;
251 edid_init_data[0x80 + 0x15] = 0x61;
252 base += (0x5d + 0x3);
253 } else {
254 base += 0x5d;
255 }
256
257 for (i = 0; i < 127; i++)
258 csum += edid_init_data[i + j * 128];
259
260 edid_init_data[127 + j * 128] = (u8)0 - csum;
261 }
262
263 return 0;
264 }
265
rk628_hdmirx_set_edid(struct rk628 * rk628)266 static int rk628_hdmirx_set_edid(struct rk628 *rk628)
267 {
268 int i;
269 u32 val;
270 u16 edid_len;
271
272 rk628_hdmirx_disable_edid(rk628);
273
274 if (!rk628->plugin_det_gpio)
275 return 0;
276
277 /* edid access by apb when write, i2c slave addr: 0x0 */
278 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
279 SW_ADAPTER_I2CSLADR_MASK |
280 SW_EDID_MODE_MASK,
281 SW_ADAPTER_I2CSLADR(0) |
282 SW_EDID_MODE(1));
283
284 rk628_hdmirx_init_edid(rk628);
285
286 edid_len = ARRAY_SIZE(edid_init_data);
287 for (i = 0; i < edid_len; i++)
288 rk628_i2c_write(rk628, EDID_BASE + i * 4, edid_init_data[i]);
289
290 /* read out for debug */
291 if (debug >= 3) {
292 pr_info("====== Read EDID: ======\n");
293 for (i = 0; i < edid_len; i++) {
294 rk628_i2c_read(rk628, EDID_BASE + i * 4, &val);
295 pr_info("0x%02x ", val);
296 if ((i + 1) % 8 == 0)
297 pr_info("\n");
298 }
299 pr_info("============\n");
300 }
301
302 /* edid access by RX's i2c, i2c slave addr: 0x0 */
303 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
304 SW_ADAPTER_I2CSLADR_MASK |
305 SW_EDID_MODE_MASK,
306 SW_ADAPTER_I2CSLADR(0) |
307 SW_EDID_MODE(0));
308
309 mdelay(1);
310
311 return 0;
312 }
313
rk628_hdmirx_phy_power_on(struct rk628 * rk628,int f)314 static int rk628_hdmirx_phy_power_on(struct rk628 *rk628, int f)
315 {
316 int ret;
317 bool rxphy_pwron = false;
318
319 if (rxphy_pwron) {
320 dev_info(rk628->dev, "rxphy already power on, power off!\n");
321 ret = rk628_combrxphy_power_off(rk628);
322 if (ret)
323 dev_info(rk628->dev, "hdmi rxphy power off failed!\n");
324 else
325 rxphy_pwron = false;
326 }
327
328 udelay(1000);
329 if (rxphy_pwron == false) {
330 ret = rk628_combrxphy_power_on(rk628, f);
331 if (ret) {
332 rxphy_pwron = false;
333 dev_info(rk628->dev, "hdmi rxphy power on failed\n");
334 } else {
335 rxphy_pwron = true;
336 dev_info(rk628->dev, "hdmi rxphy power on success\n");
337 }
338 }
339
340 dev_info(rk628->dev, "%s:rxphy_pwron=%d\n", __func__, rxphy_pwron);
341 return ret;
342 }
343
rk628_hdmirx_get_timing(struct rk628 * rk628)344 static void rk628_hdmirx_get_timing(struct rk628 *rk628)
345 {
346 u32 hact, vact, htotal, vtotal, fps, status;
347 u32 val;
348 u32 modetclk_cnt_hs, modetclk_cnt_vs, hs, vs;
349 u32 hofs_pix, hbp, hfp, vbp, vfp;
350 u32 tmds_clk, tmdsclk_cnt;
351 u64 tmp_data;
352 u32 interlaced;
353 u32 hfrontporch, hsync, hbackporch, vfrontporch, vsync, vbackporch;
354 unsigned long long pixelclock;
355 unsigned long flags = 0;
356 struct rk628_hdmirx *hdmirx = rk628->hdmirx;
357
358 rk628_i2c_read(rk628, HDMI_RX_SCDC_REGS1, &val);
359 status = val;
360
361 rk628_i2c_read(rk628, HDMI_RX_MD_STS, &val);
362 interlaced = val & ILACE_STS ? 1 : 0;
363
364 rk628_i2c_read(rk628, HDMI_RX_MD_HACT_PX, &val);
365 hact = val & 0xffff;
366 rk628_i2c_read(rk628, HDMI_RX_MD_VAL, &val);
367 vact = val & 0xffff;
368 rk628_i2c_read(rk628, HDMI_RX_MD_HT1, &val);
369 htotal = (val >> 16) & 0xffff;
370 rk628_i2c_read(rk628, HDMI_RX_MD_VTL, &val);
371 vtotal = val & 0xffff;
372 rk628_i2c_read(rk628, HDMI_RX_MD_HT1, &val);
373 hofs_pix = val & 0xffff;
374 rk628_i2c_read(rk628, HDMI_RX_MD_VOL, &val);
375 vbp = (val & 0xffff) + 1;
376
377 rk628_i2c_read(rk628, HDMI_RX_HDMI_CKM_RESULT, &val);
378 tmdsclk_cnt = val & 0xffff;
379 tmp_data = tmdsclk_cnt;
380 tmp_data = ((tmp_data * MODETCLK_HZ) + MODETCLK_CNT_NUM / 2);
381 do_div(tmp_data, MODETCLK_CNT_NUM);
382 tmds_clk = tmp_data;
383 if (!(htotal && vtotal)) {
384 dev_info(rk628->dev, "timing err, htotal:%d, vtotal:%d\n", htotal, vtotal);
385 return;
386 }
387 fps = (tmds_clk + (htotal * vtotal) / 2) / (htotal * vtotal);
388
389 rk628_i2c_read(rk628, HDMI_RX_MD_HT0, &val);
390 modetclk_cnt_hs = val & 0xffff;
391 hs = (tmdsclk_cnt * modetclk_cnt_hs + MODETCLK_CNT_NUM / 2) /
392 MODETCLK_CNT_NUM;
393
394 rk628_i2c_read(rk628, HDMI_RX_MD_VSC, &val);
395 modetclk_cnt_vs = val & 0xffff;
396 vs = (tmdsclk_cnt * modetclk_cnt_vs + MODETCLK_CNT_NUM / 2) /
397 MODETCLK_CNT_NUM;
398 vs = (vs + htotal / 2) / htotal;
399
400 rk628_i2c_read(rk628, HDMI_RX_HDMI_STS, &val);
401 if (val & BIT(8))
402 flags |= DRM_MODE_FLAG_PHSYNC;
403 else
404 flags |= DRM_MODE_FLAG_NHSYNC;
405 if (val & BIT(9))
406 flags |= DRM_MODE_FLAG_PVSYNC;
407 else
408 flags |= DRM_MODE_FLAG_NVSYNC;
409
410 if ((hofs_pix < hs) || (htotal < (hact + hofs_pix)) ||
411 (vtotal < (vact + vs + vbp))) {
412 dev_info(rk628->dev,
413 "timing err, total:%dx%d, act:%dx%d, hofs:%d, hs:%d, vs:%d, vbp:%d\n",
414 htotal, vtotal, hact, vact, hofs_pix, hs, vs, vbp);
415 return;
416 }
417 hbp = hofs_pix - hs;
418 hfp = htotal - hact - hofs_pix;
419 vfp = vtotal - vact - vs - vbp;
420
421 dev_info(rk628->dev, "cnt_num:%d, tmds_cnt:%d, hs_cnt:%d, vs_cnt:%d, hofs:%d\n",
422 MODETCLK_CNT_NUM, tmdsclk_cnt, modetclk_cnt_hs, modetclk_cnt_vs, hofs_pix);
423
424 hfrontporch = hfp;
425 hsync = hs;
426 hbackporch = hbp;
427 vfrontporch = vfp;
428 vsync = vs;
429 vbackporch = vbp;
430 pixelclock = htotal * vtotal * fps;
431
432 if (interlaced == 1) {
433 vsync = vsync + 1;
434 pixelclock /= 2;
435 }
436
437 hdmirx->mode.clock = pixelclock / 1000;
438 hdmirx->mode.hdisplay = hact;
439 hdmirx->mode.hstart = hdmirx->mode.hdisplay + hfrontporch;
440 hdmirx->mode.hend = hdmirx->mode.hstart + hsync;
441 hdmirx->mode.htotal = hdmirx->mode.hend + hbackporch;
442
443 hdmirx->mode.vdisplay = vact;
444 hdmirx->mode.vstart = hdmirx->mode.vdisplay + vfrontporch;
445 hdmirx->mode.vend = hdmirx->mode.vstart + vsync;
446 hdmirx->mode.vtotal = hdmirx->mode.vend + vbackporch;
447 hdmirx->mode.flags = flags;
448
449 dev_info(rk628->dev, "SCDC_REGS1:%#x, act:%dx%d, total:%dx%d, fps:%d, pixclk:%llu\n",
450 status, hact, vact, htotal, vtotal, fps, pixelclock);
451 dev_info(rk628->dev, "hfp:%d, hs:%d, hbp:%d, vfp:%d, vs:%d, vbp:%d, interlace:%d\n",
452 hfrontporch, hsync, hbackporch, vfrontporch, vsync, vbackporch, interlaced);
453 }
454
rk628_hdmirx_phy_setup(struct rk628 * rk628)455 static int rk628_hdmirx_phy_setup(struct rk628 *rk628)
456 {
457 u32 i, cnt, val;
458 u32 width, height, frame_width, frame_height, status;
459 struct rk628_display_mode *src_mode;
460 struct rk628_hdmirx *hdmirx = rk628->hdmirx;
461 int f;
462 struct rk628_display_mode *dst_mode;
463
464 /* Bit31 is used to distinguish HDMI cable mode and direct connection
465 * mode in the rk628_combrxphy driver.
466 * Bit31: 0 -direct connection mode;
467 * 1 -cable mode;
468 * The cable mode is to know the input clock frequency through cdr_mode
469 * in the rk628_combrxphy driver, and the cable mode supports up to
470 * 297M, so 297M is passed uniformly here.
471 */
472 f = (297000 | BIT(31));
473 dst_mode = rk628_display_get_dst_mode(rk628);
474 /*
475 * force 594m mode to yuv420 format.
476 * bit30 is used to indicate whether it is yuv420 format.
477 */
478 if (hdmirx->src_mode_4K_yuv420 && dst_mode->clock == 594000)
479 f |= BIT(30);
480
481 for (i = 0; i < RXPHY_CFG_MAX_TIMES; i++) {
482 rk628_hdmirx_phy_power_on(rk628, f);
483 cnt = 0;
484
485 do {
486 cnt++;
487 udelay(2000);
488 rk628_i2c_read(rk628, HDMI_RX_MD_HACT_PX, &val);
489 width = val & 0xffff;
490 rk628_i2c_read(rk628, HDMI_RX_MD_HT1, &val);
491 frame_width = (val >> 16) & 0xffff;
492
493 rk628_i2c_read(rk628, HDMI_RX_MD_VAL, &val);
494 height = val & 0xffff;
495 rk628_i2c_read(rk628, HDMI_RX_MD_VTL, &val);
496 frame_height = val & 0xffff;
497
498 rk628_i2c_read(rk628, HDMI_RX_SCDC_REGS1, &val);
499 status = val;
500
501 dev_info(rk628->dev,
502 "%s read wxh:%dx%d, total:%dx%d, SCDC_REGS1:%#x, cnt:%d\n",
503 __func__, width, height, frame_width,
504 frame_height, status, cnt);
505
506 if (cnt >= 15)
507 break;
508 } while ((status & 0xfff) != 0xf00);
509
510 if ((status & 0xfff) != 0xf00) {
511 dev_info(rk628->dev, "%s hdmi rxphy lock failed, retry:%d\n",
512 __func__, i);
513 continue;
514 } else {
515 rk628_hdmirx_get_timing(rk628);
516
517 src_mode = rk628_display_get_src_mode(rk628);
518 src_mode->clock = hdmirx->mode.clock;
519 src_mode->hdisplay = hdmirx->mode.hdisplay;
520 src_mode->hsync_start = hdmirx->mode.hstart;
521 src_mode->hsync_end = hdmirx->mode.hend;
522 src_mode->htotal = hdmirx->mode.htotal;
523
524 src_mode->vdisplay = hdmirx->mode.vdisplay;
525 src_mode->vsync_start = hdmirx->mode.vstart;
526 src_mode->vsync_end = hdmirx->mode.vend;
527 src_mode->vtotal = hdmirx->mode.vtotal;
528 src_mode->flags = hdmirx->mode.flags;
529 if (hdmirx->src_mode_4K_yuv420 && dst_mode->clock == 594000) {
530 rk628_mode_copy(src_mode, dst_mode);
531 src_mode->flags = DRM_MODE_FLAG_PHSYNC|DRM_MODE_FLAG_PVSYNC;
532 }
533
534 break;
535 }
536 }
537
538 if (i == RXPHY_CFG_MAX_TIMES) {
539 hdmirx->phy_lock = false;
540 return -1;
541 }
542 hdmirx->phy_lock = true;
543
544 return 0;
545 }
546
rk628_hdmirx_get_input_format(struct rk628 * rk628)547 static u32 rk628_hdmirx_get_input_format(struct rk628 *rk628)
548 {
549 u32 val, format, avi_pb = 0;
550 u8 i;
551 u8 cnt = 0, max_cnt = 2;
552 struct rk628_hdmirx *hdmirx = rk628->hdmirx;
553
554 rk628_i2c_read(rk628, HDMI_RX_PDEC_ISTS, &val);
555 if (val & AVI_RCV_ISTS) {
556 for (i = 0; i < 100; i++) {
557 rk628_i2c_read(rk628, HDMI_RX_PDEC_AVI_PB, &format);
558 dev_dbg(rk628->dev, "%s PDEC_AVI_PB:%#x\n", __func__, format);
559 if (format && format == avi_pb) {
560 if (++cnt >= max_cnt)
561 break;
562 } else {
563 cnt = 0;
564 avi_pb = format;
565 }
566 msleep(30);
567 }
568 format = (avi_pb & VIDEO_FORMAT) >> 5;
569 switch (format) {
570 case 0:
571 hdmirx->input_format = BUS_FMT_RGB;
572 break;
573 case 1:
574 hdmirx->input_format = BUS_FMT_YUV422;
575 break;
576 case 2:
577 hdmirx->input_format = BUS_FMT_YUV444;
578 break;
579 case 3:
580 hdmirx->input_format = BUS_FMT_YUV420;
581 break;
582 default:
583 hdmirx->input_format = BUS_FMT_RGB;
584 break;
585 }
586 rk628_i2c_write(rk628, HDMI_RX_PDEC_ICLR, AVI_RCV_ISTS);
587 }
588
589 return hdmirx->input_format;
590 }
591
rk628_check_signal(struct rk628 * rk628)592 static int rk628_check_signal(struct rk628 *rk628)
593 {
594 u32 hact, vact, val;
595
596 rk628_i2c_read(rk628, HDMI_RX_MD_HACT_PX, &val);
597 hact = val & 0xffff;
598 rk628_i2c_read(rk628, HDMI_RX_MD_VAL, &val);
599 vact = val & 0xffff;
600
601 if (!hact || !vact) {
602 dev_info(rk628->dev, "no signal\n");
603 return 0;
604 }
605
606 return 1;
607 }
608
rk628_hdmirx_status_change(struct rk628 * rk628)609 static bool rk628_hdmirx_status_change(struct rk628 *rk628)
610 {
611 u32 hact, vact, val;
612 struct rk628_hdmirx *hdmirx = rk628->hdmirx;
613
614 rk628_i2c_read(rk628, HDMI_RX_MD_HACT_PX, &val);
615 hact = val & 0xffff;
616 rk628_i2c_read(rk628, HDMI_RX_MD_VAL, &val);
617 vact = val & 0xffff;
618 if (!rk628->plugin_det_gpio && !hact && !vact)
619 return true;
620
621 if (hact != hdmirx->mode.hdisplay || vact != hdmirx->mode.vdisplay) {
622 dev_info(rk628->dev, "new: hdisplay=%d, vdisplay=%d\n", hact, vact);
623 dev_info(rk628->dev, "old: hdisplay=%d, vdisplay=%d\n",
624 hdmirx->mode.hdisplay, hdmirx->mode.vdisplay);
625 return true;
626 }
627
628 rk628_hdmirx_get_input_format(rk628);
629 if (hdmirx->input_format != rk628_get_input_bus_format(rk628))
630 return true;
631
632 return false;
633 }
634
rk628_hdmirx_init(struct rk628 * rk628)635 static int rk628_hdmirx_init(struct rk628 *rk628)
636 {
637 struct rk628_hdmirx *hdmirx;
638 struct device *dev = rk628->dev;
639
640 hdmirx = devm_kzalloc(rk628->dev, sizeof(*hdmirx), GFP_KERNEL);
641 if (!hdmirx)
642 return -ENOMEM;
643 rk628->hdmirx = hdmirx;
644
645 hdmirx->hpd_output_inverted = of_property_read_bool(dev->of_node,
646 "hpd-output-inverted");
647
648 hdmirx->src_mode_4K_yuv420 = of_property_read_bool(dev->of_node,
649 "src-mode-4k-yuv420");
650
651 /* HDMIRX IOMUX */
652 rk628_i2c_write(rk628, GRF_GPIO1AB_SEL_CON, HIWORD_UPDATE(0x7, 10, 8));
653 //i2s pinctrl
654 rk628_i2c_write(rk628, GRF_GPIO0AB_SEL_CON, 0x155c155c);
655
656 /* if GVI and HDMITX OUT, HDMIRX missing signal */
657 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
658 SW_OUTPUT_MODE_MASK, SW_OUTPUT_MODE(OUTPUT_MODE_RGB));
659 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0,
660 SW_INPUT_MODE_MASK, SW_INPUT_MODE(INPUT_MODE_HDMI));
661 rk628_hdmirx_set_edid(rk628);
662 /* clear avi rcv interrupt */
663 rk628_i2c_write(rk628, HDMI_RX_PDEC_ICLR, AVI_RCV_ISTS);
664
665 dev_info(rk628->dev, "hdmirx driver version: %s\n", DRIVER_VERSION);
666
667 return 0;
668 }
669
rk628_hdmirx_enable_interrupts(struct rk628 * rk628,bool en)670 void rk628_hdmirx_enable_interrupts(struct rk628 *rk628, bool en)
671 {
672 u32 pdec_ien, md_ien;
673 u32 md_mask = 0;
674
675 md_mask = VACT_LIN_ENSET | HACT_PIX_ENSET | HS_CLK_ENSET;
676 dev_dbg(rk628->dev, "%s: %sable\n", __func__, en ? "en" : "dis");
677 /* clr irq */
678 rk628_i2c_write(rk628, HDMI_RX_MD_ICLR, md_mask);
679 if (en) {
680 rk628_i2c_write(rk628, HDMI_RX_MD_IEN_SET, md_mask);
681 } else {
682 rk628_i2c_write(rk628, HDMI_RX_MD_IEN_CLR, md_mask);
683 rk628_i2c_write(rk628, HDMI_RX_AUD_FIFO_IEN_CLR, 0x1f);
684 }
685 usleep_range(5000, 5000);
686 rk628_i2c_read(rk628, HDMI_RX_MD_IEN, &md_ien);
687 rk628_i2c_read(rk628, HDMI_RX_PDEC_IEN, &pdec_ien);
688 dev_dbg(rk628->dev, "%s MD_IEN:%#x, PDEC_IEN:%#x\n", __func__, md_ien, pdec_ien);
689 }
690
rk628_hdmirx_enable(struct rk628 * rk628)691 int rk628_hdmirx_enable(struct rk628 *rk628)
692 {
693 int ret;
694 struct rk628_hdmirx *hdmirx;
695
696 if (!rk628->hdmirx) {
697 ret = rk628_hdmirx_init(rk628);
698 if (ret < 0)
699 return HDMIRX_PLUGOUT;
700 }
701
702 hdmirx = rk628->hdmirx;
703 if (tx_5v_power_present(rk628)) {
704 hdmirx->plugin = true;
705 rk628_hdmirx_enable_edid(rk628);
706 rk628_hdmirx_ctrl_enable(rk628);
707 rk628_hdmirx_phy_setup(rk628);
708 rk628_hdmirx_get_input_format(rk628);
709 rk628_set_input_bus_format(rk628, hdmirx->input_format);
710 dev_info(rk628->dev, "hdmirx plug in\n");
711 dev_info(rk628->dev, "input: %d, output: %d\n", hdmirx->input_format,
712 rk628_get_output_bus_format(rk628));
713 if (!rk628_check_signal(rk628))
714 return HDMIRX_PLUGIN | HDMIRX_NOSIGNAL;
715
716 rk628_hdmirx_video_unmute(rk628, 1);
717 return HDMIRX_PLUGIN;
718 }
719
720 hdmirx->plugin = false;
721 rk628_hdmirx_disable_edid(rk628);
722 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_I2S_DATA_OEN_MASK, SW_I2S_DATA_OEN(1));
723
724 return HDMIRX_PLUGOUT;
725 }
726
rk628_hdmirx_disable(struct rk628 * rk628)727 void rk628_hdmirx_disable(struct rk628 *rk628)
728 {
729 int ret;
730 struct rk628_hdmirx *hdmirx;
731
732 if (!rk628->hdmirx) {
733 ret = rk628_hdmirx_init(rk628);
734 if (ret < 0)
735 return;
736 }
737
738 hdmirx = rk628->hdmirx;
739 if (!tx_5v_power_present(rk628)) {
740 hdmirx->plugin = false;
741 rk628_hdmirx_disable_edid(rk628);
742 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_I2S_DATA_OEN_MASK,
743 SW_I2S_DATA_OEN(1));
744 dev_info(rk628->dev, "hdmirx plug out\n");
745 }
746 }
747
rk628_hdmirx_detect(struct rk628 * rk628)748 int rk628_hdmirx_detect(struct rk628 *rk628)
749 {
750 int ret = 0;
751 struct rk628_hdmirx *hdmirx;
752
753 if (!rk628->hdmirx) {
754 ret = rk628_hdmirx_init(rk628);
755 if (ret < 0 || !rk628->hdmirx)
756 return HDMIRX_PLUGOUT;
757 }
758 hdmirx = rk628->hdmirx;
759
760 if (tx_5v_power_present(rk628)) {
761 ret |= HDMIRX_PLUGIN;
762 if (!hdmirx->plugin)
763 ret |= HDMIRX_CHANGED;
764 if (rk628_hdmirx_status_change(rk628))
765 ret |= HDMIRX_CHANGED;
766 if (!hdmirx->phy_lock)
767 ret |= HDMIRX_NOLOCK;
768 hdmirx->plugin = true;
769 } else {
770 ret |= HDMIRX_PLUGOUT;
771 if (hdmirx->plugin)
772 ret |= HDMIRX_CHANGED;
773 hdmirx->plugin = false;
774 }
775
776 return ret;
777 }
778