1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Chen Shunqing <csq@rock-chips.com>
6 */
7
8 #include "rk628.h"
9 #include <linux/irq.h>
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/err.h>
13 #include <linux/extcon.h>
14 #include <linux/extcon-provider.h>
15 #include <linux/hdmi.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
19 #include <linux/of_device.h>
20 #include <linux/regmap.h>
21 #ifdef CONFIG_SWITCH
22 #include <linux/switch.h>
23 #endif
24 #include <drm/drm_atomic_helper.h>
25 #include <drm/drm_of.h>
26 #include <drm/drm_probe_helper.h>
27 #include <drm/drm_edid.h>
28 #include <sound/hdmi-codec.h>
29
30 #include "../../gpu/drm/rockchip/rockchip_drm_drv.h"
31 #include "rk628_config.h"
32 #include "rk628_hdmitx.h"
33 #include "rk628_post_process.h"
34
35 #include <linux/extcon.h>
36 #include <linux/extcon-provider.h>
37
38
39 struct audio_info {
40 int sample_rate;
41 int channels;
42 int sample_width;
43 };
44
45 struct hdmi_data_info {
46 int vic;
47 bool sink_is_hdmi;
48 bool sink_has_audio;
49 unsigned int enc_in_format;
50 unsigned int enc_out_format;
51 unsigned int colorimetry;
52 };
53
54 struct rk628_hdmi_i2c {
55 struct i2c_adapter adap;
56 u8 ddc_addr;
57 u8 segment_addr;
58 /* i2c lock */
59 struct mutex lock;
60 };
61
62 struct rk628_hdmi_phy_config {
63 unsigned long mpixelclock;
64 u8 pre_emphasis; /* pre-emphasis value */
65 u8 vlev_ctr; /* voltage level control */
66 };
67
68 struct rk628_hdmi {
69 struct rk628 *rk628;
70 struct device *dev;
71 int irq;
72
73 struct drm_bridge bridge;
74 struct drm_connector connector;
75
76 struct rk628_hdmi_i2c *i2c;
77 struct i2c_adapter *ddc;
78
79 unsigned int tmds_rate;
80
81 struct platform_device *audio_pdev;
82 bool audio_enable;
83
84 struct hdmi_data_info hdmi_data;
85 struct drm_display_mode previous_mode;
86
87 struct rockchip_drm_sub_dev sub_dev;
88 struct extcon_dev *extcon;
89 };
90
91 static const unsigned int rk628_hdmi_cable[] = {
92 EXTCON_DISP_HDMI,
93 EXTCON_NONE,
94 };
95
96 enum {
97 CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
98 CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
99 CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
100 CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
101 CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
102 CSC_RGB_0_255_TO_RGB_16_235_8BIT,
103 };
104
105 static const char coeff_csc[][24] = {
106 /*
107 * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
108 * R = 1.164*Y + 1.596*V - 204
109 * G = 1.164*Y - 0.391*U - 0.813*V + 154
110 * B = 1.164*Y + 2.018*U - 258
111 */
112 {
113 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
114 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
115 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
116 },
117 /*
118 * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
119 * R = Y + 1.402*V - 248
120 * G = Y - 0.344*U - 0.714*V + 135
121 * B = Y + 1.772*U - 227
122 */
123 {
124 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
125 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
126 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
127 },
128 /*
129 * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
130 * R = 1.164*Y + 1.793*V - 248
131 * G = 1.164*Y - 0.213*U - 0.534*V + 77
132 * B = 1.164*Y + 2.115*U - 289
133 */
134 {
135 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
136 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
137 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
138 },
139
140 /*
141 * RGB2YUV:601 SD mode:
142 * Cb = -0.291G - 0.148R + 0.439B + 128
143 * Y = 0.504G + 0.257R + 0.098B + 16
144 * Cr = -0.368G + 0.439R - 0.071B + 128
145 */
146 {
147 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
148 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
149 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
150 },
151 /*
152 * RGB2YUV:709 HD mode:
153 * Cb = - 0.338G - 0.101R + 0.439B + 128
154 * Y = 0.614G + 0.183R + 0.062B + 16
155 * Cr = - 0.399G + 0.439R - 0.040B + 128
156 */
157 {
158 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
159 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
160 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
161 },
162 /*
163 * RGB[0:255]2RGB[16:235]:
164 * R' = R x (235-16)/255 + 16;
165 * G' = G x (235-16)/255 + 16;
166 * B' = B x (235-16)/255 + 16;
167 */
168 {
169 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
170 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
171 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10
172 },
173 };
174
bridge_to_hdmi(struct drm_bridge * b)175 static inline struct rk628_hdmi *bridge_to_hdmi(struct drm_bridge *b)
176 {
177 return container_of(b, struct rk628_hdmi, bridge);
178 }
179
connector_to_hdmi(struct drm_connector * c)180 static inline struct rk628_hdmi *connector_to_hdmi(struct drm_connector *c)
181 {
182 return container_of(c, struct rk628_hdmi, connector);
183 }
184
hdmi_readb(struct rk628_hdmi * hdmi,u32 reg)185 static u32 hdmi_readb(struct rk628_hdmi *hdmi, u32 reg)
186 {
187 u32 val;
188
189 rk628_i2c_read(hdmi->rk628, reg, &val);
190
191 return val;
192 }
193
hdmi_writeb(struct rk628_hdmi * hdmi,u32 reg,u32 val)194 static void hdmi_writeb(struct rk628_hdmi *hdmi, u32 reg, u32 val)
195 {
196 rk628_i2c_write(hdmi->rk628, reg, val);
197 }
198
hdmi_modb(struct rk628_hdmi * hdmi,u32 offset,u32 msk,u32 val)199 static void hdmi_modb(struct rk628_hdmi *hdmi, u32 offset,
200 u32 msk, u32 val)
201 {
202 u8 temp = hdmi_readb(hdmi, offset) & ~msk;
203
204 temp |= val & msk;
205 hdmi_writeb(hdmi, offset, temp);
206 }
207
rk628_hdmi_i2c_init(struct rk628_hdmi * hdmi)208 static void rk628_hdmi_i2c_init(struct rk628_hdmi *hdmi)
209 {
210 int ddc_bus_freq;
211
212 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
213
214 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
215 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
216
217 /* Clear the EDID interrupt flag and mute the interrupt */
218 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
219 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, INT_EDID_READY);
220 }
221
rk628_hdmi_sys_power(struct rk628_hdmi * hdmi,bool enable)222 static void rk628_hdmi_sys_power(struct rk628_hdmi *hdmi, bool enable)
223 {
224 if (enable)
225 hdmi_modb(hdmi, HDMI_SYS_CTRL, POWER_MASK, PWR_OFF(0));
226 else
227 hdmi_modb(hdmi, HDMI_SYS_CTRL, POWER_MASK, PWR_OFF(1));
228 }
229
230 static struct rk628_hdmi_phy_config rk628_hdmi_phy_config[] = {
231 /* pixelclk pre-emp vlev */
232 { 74250000, 0x3f, 0x88 },
233 { 165000000, 0x3f, 0x88 },
234 { ~0UL, 0x00, 0x00 }
235 };
236
rk628_hdmi_set_pwr_mode(struct rk628_hdmi * hdmi,int mode)237 static void rk628_hdmi_set_pwr_mode(struct rk628_hdmi *hdmi, int mode)
238 {
239 const struct rk628_hdmi_phy_config *phy_config =
240 rk628_hdmi_phy_config;
241
242 switch (mode) {
243 case NORMAL:
244 rk628_hdmi_sys_power(hdmi, false);
245 for (; phy_config->mpixelclock != ~0UL; phy_config++)
246 if (hdmi->tmds_rate <= phy_config->mpixelclock)
247 break;
248 if (!phy_config->mpixelclock)
249 return;
250 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS,
251 phy_config->pre_emphasis);
252 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, phy_config->vlev_ctr);
253
254 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
255 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
256 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
257 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
258 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
259 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
260
261 rk628_hdmi_sys_power(hdmi, true);
262 break;
263
264 case LOWER_PWR:
265 rk628_hdmi_sys_power(hdmi, false);
266 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
267 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
268 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
269 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
270 break;
271
272 default:
273 dev_err(hdmi->dev, "Unknown power mode %d\n", mode);
274 }
275 }
276
rk628_hdmi_reset(struct rk628_hdmi * hdmi)277 static void rk628_hdmi_reset(struct rk628_hdmi *hdmi)
278 {
279 u32 val;
280 u32 msk;
281
282 hdmi_modb(hdmi, HDMI_SYS_CTRL, RST_DIGITAL_MASK, NOT_RST_DIGITAL(1));
283 usleep_range(100, 110);
284
285 hdmi_modb(hdmi, HDMI_SYS_CTRL, RST_ANALOG_MASK, NOT_RST_ANALOG(1));
286 usleep_range(100, 110);
287
288 msk = REG_CLK_INV_MASK | REG_CLK_SOURCE_MASK | POWER_MASK |
289 INT_POL_MASK;
290 val = REG_CLK_INV(1) | REG_CLK_SOURCE(1) | PWR_OFF(0) | INT_POL(1);
291 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
292
293 rk628_hdmi_set_pwr_mode(hdmi, NORMAL);
294 }
295
rk628_hdmi_upload_frame(struct rk628_hdmi * hdmi,int setup_rc,union hdmi_infoframe * frame,u32 frame_index,u32 mask,u32 disable,u32 enable)296 static int rk628_hdmi_upload_frame(struct rk628_hdmi *hdmi, int setup_rc,
297 union hdmi_infoframe *frame, u32 frame_index,
298 u32 mask, u32 disable, u32 enable)
299 {
300 if (mask)
301 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
302
303 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
304
305 if (setup_rc >= 0) {
306 u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
307 ssize_t rc, i;
308
309 rc = hdmi_infoframe_pack(frame, packed_frame,
310 sizeof(packed_frame));
311 if (rc < 0)
312 return rc;
313
314 for (i = 0; i < rc; i++)
315 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + (i * 4),
316 packed_frame[i]);
317
318 if (mask)
319 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
320 }
321
322 return setup_rc;
323 }
324
rk628_hdmi_config_video_vsi(struct rk628_hdmi * hdmi,struct drm_display_mode * mode)325 static int rk628_hdmi_config_video_vsi(struct rk628_hdmi *hdmi,
326 struct drm_display_mode *mode)
327 {
328 union hdmi_infoframe frame;
329 int rc;
330
331 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
332 &hdmi->connector,
333 mode);
334
335 return rk628_hdmi_upload_frame(hdmi, rc, &frame,
336 INFOFRAME_VSI, PACKET_VSI_EN_MASK,
337 PACKET_VSI_EN(0), PACKET_VSI_EN(1));
338 }
339
rk628_hdmi_config_video_avi(struct rk628_hdmi * hdmi,struct drm_display_mode * mode)340 static int rk628_hdmi_config_video_avi(struct rk628_hdmi *hdmi,
341 struct drm_display_mode *mode)
342 {
343 union hdmi_infoframe frame;
344 int rc;
345
346 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
347 &hdmi->connector, mode);
348
349 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
350 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
351 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
352 frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
353 else
354 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
355
356 if (frame.avi.colorspace != HDMI_COLORSPACE_RGB)
357 frame.avi.colorimetry = hdmi->hdmi_data.colorimetry;
358
359 frame.avi.scan_mode = HDMI_SCAN_MODE_NONE;
360
361 return rk628_hdmi_upload_frame(hdmi, rc, &frame,
362 INFOFRAME_AVI, 0, 0, 0);
363 }
364
rk628_hdmi_config_audio_aai(struct rk628_hdmi * hdmi,struct audio_info * audio)365 static int rk628_hdmi_config_audio_aai(struct rk628_hdmi *hdmi,
366 struct audio_info *audio)
367 {
368 struct hdmi_audio_infoframe *faudio;
369 union hdmi_infoframe frame;
370 int rc;
371
372 rc = hdmi_audio_infoframe_init(&frame.audio);
373 faudio = (struct hdmi_audio_infoframe *)&frame;
374
375 faudio->channels = audio->channels;
376
377 return rk628_hdmi_upload_frame(hdmi, rc, &frame,
378 INFOFRAME_AAI, 0, 0, 0);
379 }
380
rk628_hdmi_config_video_csc(struct rk628_hdmi * hdmi)381 static int rk628_hdmi_config_video_csc(struct rk628_hdmi *hdmi)
382 {
383 struct hdmi_data_info *data = &hdmi->hdmi_data;
384 int c0_c2_change = 0;
385 int csc_enable = 0;
386 int csc_mode = 0;
387 int auto_csc = 0;
388 int value;
389 int i;
390 int out_fmt;
391
392 /* Input video mode is SDR RGB24bit, data enable signal from external */
393 hdmi_writeb(hdmi, HDMI_VIDEO_CONTROL1, DE_SOURCE(1) |
394 VIDEO_INPUT_SDR_RGB444);
395
396 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
397 out_fmt = VIDEO_OUTPUT_YCBCR444;
398 else
399 out_fmt = VIDEO_OUTPUT_RRGB444;
400 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
401 value = VIDEO_INPUT_8BITS | out_fmt | VIDEO_INPUT_CSP(0);
402 hdmi_writeb(hdmi, HDMI_VIDEO_CONTROL2, value);
403
404 if (data->enc_in_format == data->enc_out_format) {
405 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
406 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
407 value = SOF_DISABLE(1) | COLOR_DEPTH_NOT_INDICATED(1);
408 hdmi_writeb(hdmi, HDMI_VIDEO_CONTROL3, value);
409
410 hdmi_modb(hdmi, HDMI_VIDEO_CONTROL,
411 VIDEO_AUTO_CSC_MASK | VIDEO_C0_C2_SWAP_MASK,
412 VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
413 VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
414 return 0;
415 }
416 }
417
418 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
419 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
420 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
421 csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
422 auto_csc = AUTO_CSC_DISABLE;
423 c0_c2_change = C0_C2_CHANGE_DISABLE;
424 csc_enable = CSC_ENABLE(1);
425 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
426 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
427 csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
428 auto_csc = AUTO_CSC_ENABLE;
429 c0_c2_change = C0_C2_CHANGE_DISABLE;
430 csc_enable = CSC_ENABLE(0);
431 }
432 } else {
433 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
434 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
435 csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
436 auto_csc = AUTO_CSC_DISABLE;
437 c0_c2_change = C0_C2_CHANGE_DISABLE;
438 csc_enable = CSC_ENABLE(1);
439 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
440 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
441 csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
442 auto_csc = AUTO_CSC_ENABLE;
443 c0_c2_change = C0_C2_CHANGE_DISABLE;
444 csc_enable = CSC_ENABLE(0);
445 }
446 }
447
448 for (i = 0; i < 24; i++)
449 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + (i * 4),
450 coeff_csc[csc_mode][i]);
451
452 value = SOF_DISABLE(1) | csc_enable | COLOR_DEPTH_NOT_INDICATED(1);
453 hdmi_writeb(hdmi, HDMI_VIDEO_CONTROL3, value);
454 hdmi_modb(hdmi, HDMI_VIDEO_CONTROL,
455 VIDEO_AUTO_CSC_MASK | VIDEO_C0_C2_SWAP_MASK,
456 VIDEO_AUTO_CSC(auto_csc) | VIDEO_C0_C2_SWAP(c0_c2_change));
457
458 return 0;
459 }
460
rk628_hdmi_config_video_timing(struct rk628_hdmi * hdmi,struct drm_display_mode * mode)461 static int rk628_hdmi_config_video_timing(struct rk628_hdmi *hdmi,
462 struct drm_display_mode *mode)
463 {
464 int value;
465
466 /* Set detail external video timing polarity and interlace mode */
467 value = EXTERANL_VIDEO(1);
468 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
469 HSYNC_POLARITY(1) : HSYNC_POLARITY(0);
470 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
471 VSYNC_POLARITY(1) : VSYNC_POLARITY(0);
472 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
473 INETLACE(1) : INETLACE(0);
474 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value);
475
476 /* Set detail external video timing */
477 value = mode->htotal;
478 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF);
479 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
480
481 value = mode->htotal - mode->hdisplay;
482 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
483 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
484
485 value = mode->htotal - mode->hsync_start;
486 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
487 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
488
489 value = mode->hsync_end - mode->hsync_start;
490 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF);
491 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
492
493 value = mode->vtotal;
494 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF);
495 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
496
497 value = mode->vtotal - mode->vdisplay;
498 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
499
500 value = mode->vtotal - mode->vsync_start;
501 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
502
503 value = mode->vsync_end - mode->vsync_start;
504 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF);
505
506 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e);
507 hdmi_writeb(hdmi, PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c);
508 hdmi_writeb(hdmi, PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01);
509
510 return 0;
511 }
512
rk628_hdmi_setup(struct rk628_hdmi * hdmi,struct drm_display_mode * mode)513 static int rk628_hdmi_setup(struct rk628_hdmi *hdmi,
514 struct drm_display_mode *mode)
515 {
516 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
517
518 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
519 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
520
521 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
522 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
523 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
524 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
525 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
526 else
527 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
528
529 /* Mute video and audio output */
530 hdmi_modb(hdmi, HDMI_AV_MUTE, AUDIO_MUTE_MASK | VIDEO_BLACK_MASK,
531 AUDIO_MUTE(1) | VIDEO_MUTE(1));
532
533 /* Set HDMI Mode */
534 hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
535 HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi));
536
537 rk628_hdmi_config_video_timing(hdmi, mode);
538
539 rk628_hdmi_config_video_csc(hdmi);
540
541 if (hdmi->hdmi_data.sink_is_hdmi) {
542 rk628_hdmi_config_video_avi(hdmi, mode);
543 rk628_hdmi_config_video_vsi(hdmi, mode);
544 }
545
546 /*
547 * When IP controller have configured to an accurate video
548 * timing, then the TMDS clock source would be switched to
549 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
550 * clock rate, and reconfigure the DDC clock.
551 */
552 hdmi->tmds_rate = mode->clock * 1000;
553 rk628_hdmi_i2c_init(hdmi);
554
555 /* Unmute video and audio output */
556 hdmi_modb(hdmi, HDMI_AV_MUTE, VIDEO_BLACK_MASK, VIDEO_MUTE(0));
557 if (hdmi->audio_enable)
558 hdmi_modb(hdmi, HDMI_AV_MUTE, AUDIO_MUTE_MASK, AUDIO_MUTE(0));
559
560 return 0;
561 }
562
563 static enum drm_connector_status
rk628_hdmi_connector_detect(struct drm_connector * connector,bool force)564 rk628_hdmi_connector_detect(struct drm_connector *connector, bool force)
565 {
566 struct rk628_hdmi *hdmi = connector_to_hdmi(connector);
567 int status;
568
569 status = hdmi_readb(hdmi, HDMI_STATUS) & HOTPLUG_STATUS;
570
571 if (status)
572 extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, true);
573 else
574 extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false);
575
576 return status ? connector_status_connected :
577 connector_status_disconnected;
578 }
579
rk628_hdmi_connector_get_modes(struct drm_connector * connector)580 static int rk628_hdmi_connector_get_modes(struct drm_connector *connector)
581 {
582 struct rk628_hdmi *hdmi = connector_to_hdmi(connector);
583 struct drm_display_info *info = &connector->display_info;
584 struct edid *edid = NULL;
585 int ret = 0;
586
587 if (!hdmi->ddc)
588 return 0;
589
590 if ((hdmi_readb(hdmi, HDMI_STATUS) & HOTPLUG_STATUS))
591 edid = drm_get_edid(connector, hdmi->ddc);
592
593 if (edid) {
594 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
595 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
596
597 drm_connector_update_edid_property(connector, edid);
598
599 ret = drm_add_edid_modes(connector, edid);
600 kfree(edid);
601 } else {
602 hdmi->hdmi_data.sink_is_hdmi = true;
603 hdmi->hdmi_data.sink_has_audio = true;
604
605 ret = rockchip_drm_add_modes_noedid(connector);
606
607 info->edid_hdmi_dc_modes = 0;
608 info->hdmi.y420_dc_modes = 0;
609 info->color_formats = 0;
610
611 dev_info(hdmi->dev, "failed to get edid\n");
612 }
613
614 return ret;
615 }
616
617 static enum drm_mode_status
rk628_hdmi_connector_mode_valid(struct drm_connector * connector,struct drm_display_mode * mode)618 rk628_hdmi_connector_mode_valid(struct drm_connector *connector,
619 struct drm_display_mode *mode)
620 {
621 if ((mode->hdisplay == 1920 && mode->vdisplay == 1080) ||
622 (mode->hdisplay == 1280 && mode->vdisplay == 720))
623 return MODE_OK;
624 else
625 return MODE_BAD;
626 }
627
628 static struct drm_encoder *
rk628_hdmi_connector_best_encoder(struct drm_connector * connector)629 rk628_hdmi_connector_best_encoder(struct drm_connector *connector)
630 {
631 struct rk628_hdmi *hdmi = connector_to_hdmi(connector);
632
633 return hdmi->bridge.encoder;
634 }
635
636 static int
rk628_hdmi_probe_single_connector_modes(struct drm_connector * connector,u32 maxX,u32 maxY)637 rk628_hdmi_probe_single_connector_modes(struct drm_connector *connector,
638 u32 maxX, u32 maxY)
639 {
640 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
641 }
642
643 static const struct drm_connector_funcs rk628_hdmi_connector_funcs = {
644 .fill_modes = rk628_hdmi_probe_single_connector_modes,
645 .detect = rk628_hdmi_connector_detect,
646 .destroy = drm_connector_cleanup,
647 .reset = drm_atomic_helper_connector_reset,
648 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
649 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
650 };
651
652 static const struct drm_connector_helper_funcs
653 rk628_hdmi_connector_helper_funcs = {
654 .get_modes = rk628_hdmi_connector_get_modes,
655 .mode_valid = rk628_hdmi_connector_mode_valid,
656 .best_encoder = rk628_hdmi_connector_best_encoder,
657 };
658
rk628_hdmi_bridge_mode_set(struct drm_bridge * bridge,const struct drm_display_mode * mode,const struct drm_display_mode * adj_mode)659 static void rk628_hdmi_bridge_mode_set(struct drm_bridge *bridge,
660 const struct drm_display_mode *mode,
661 const struct drm_display_mode *adj_mode)
662 {
663 struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
664 struct rk628 *rk628 = hdmi->rk628;
665 struct rk628_display_mode *src = rk628_display_get_src_mode(rk628);
666 struct rk628_display_mode *dst = rk628_display_get_dst_mode(rk628);
667
668 /* Store the display mode for plugin/DPMS poweron events */
669 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
670 dst->clock = mode->clock;
671 dst->hdisplay = mode->hdisplay;
672 dst->hsync_start = mode->hsync_start;
673 dst->hsync_end = mode->hsync_end;
674 dst->htotal = mode->htotal;
675 dst->vdisplay = mode->vdisplay;
676 dst->vsync_start = mode->vsync_start;
677 dst->vsync_end = mode->vsync_end;
678 dst->vtotal = mode->vtotal;
679 dst->flags = mode->flags;
680 rk628_mode_copy(src, dst);
681 }
682
683 static bool
rk628_hdmi_bridge_mode_fixup(struct drm_bridge * bridge,const struct drm_display_mode * mode,struct drm_display_mode * adj)684 rk628_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
685 const struct drm_display_mode *mode,
686 struct drm_display_mode *adj)
687 {
688 struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
689 struct rk628 *rk628 = hdmi->rk628;
690
691 if (rk628->sync_pol == MODE_FLAG_NSYNC) {
692 adj->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
693 adj->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
694 } else {
695 adj->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
696 adj->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
697 }
698
699 return true;
700 }
701
rk628_hdmi_bridge_enable(struct drm_bridge * bridge)702 static void rk628_hdmi_bridge_enable(struct drm_bridge *bridge)
703 {
704 struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
705
706 rk628_post_process_init(hdmi->rk628);
707 rk628_post_process_enable(hdmi->rk628);
708 rk628_hdmi_setup(hdmi, &hdmi->previous_mode);
709 rk628_hdmi_set_pwr_mode(hdmi, NORMAL);
710 }
711
rk628_hdmi_bridge_disable(struct drm_bridge * bridge)712 static void rk628_hdmi_bridge_disable(struct drm_bridge *bridge)
713 {
714 struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
715
716 rk628_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
717 }
718
rk628_hdmi_bridge_attach(struct drm_bridge * bridge,enum drm_bridge_attach_flags flags)719 static int rk628_hdmi_bridge_attach(struct drm_bridge *bridge,
720 enum drm_bridge_attach_flags flags)
721 {
722 struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
723 struct drm_connector *connector = &hdmi->connector;
724 struct drm_device *drm = bridge->dev;
725 int ret;
726
727 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
728 return 0;
729
730 connector->polled = DRM_CONNECTOR_POLL_HPD;
731
732 ret = drm_connector_init(drm, connector, &rk628_hdmi_connector_funcs,
733 DRM_MODE_CONNECTOR_HDMIA);
734 if (ret) {
735 dev_err(hdmi->dev, "Failed to initialize connector with drm\n");
736 return ret;
737 }
738
739 drm_connector_helper_add(connector,
740 &rk628_hdmi_connector_helper_funcs);
741 drm_connector_attach_encoder(connector, bridge->encoder);
742
743 hdmi->sub_dev.connector = &hdmi->connector;
744 hdmi->sub_dev.of_node = hdmi->dev->of_node;
745 rockchip_drm_register_sub_dev(&hdmi->sub_dev);
746
747 return 0;
748 }
749
rk628_hdmi_bridge_detach(struct drm_bridge * bridge)750 static void rk628_hdmi_bridge_detach(struct drm_bridge *bridge)
751 {
752 struct rk628_hdmi *hdmi = bridge_to_hdmi(bridge);
753
754 rockchip_drm_unregister_sub_dev(&hdmi->sub_dev);
755 }
756
757 static const struct drm_bridge_funcs rk628_hdmi_bridge_funcs = {
758 .attach = rk628_hdmi_bridge_attach,
759 .detach = rk628_hdmi_bridge_detach,
760 .mode_set = rk628_hdmi_bridge_mode_set,
761 .mode_fixup = rk628_hdmi_bridge_mode_fixup,
762 .enable = rk628_hdmi_bridge_enable,
763 .disable = rk628_hdmi_bridge_disable,
764 };
765
766 static int
rk628_hdmi_audio_config_set(struct rk628_hdmi * hdmi,struct audio_info * audio)767 rk628_hdmi_audio_config_set(struct rk628_hdmi *hdmi, struct audio_info *audio)
768 {
769 int rate, N, channel;
770
771 if (audio->channels < 3)
772 channel = I2S_CHANNEL_1_2;
773 else if (audio->channels < 5)
774 channel = I2S_CHANNEL_3_4;
775 else if (audio->channels < 7)
776 channel = I2S_CHANNEL_5_6;
777 else
778 channel = I2S_CHANNEL_7_8;
779
780 switch (audio->sample_rate) {
781 case 32000:
782 rate = AUDIO_32K;
783 N = N_32K;
784 break;
785 case 44100:
786 rate = AUDIO_441K;
787 N = N_441K;
788 break;
789 case 48000:
790 rate = AUDIO_48K;
791 N = N_48K;
792 break;
793 case 88200:
794 rate = AUDIO_882K;
795 N = N_882K;
796 break;
797 case 96000:
798 rate = AUDIO_96K;
799 N = N_96K;
800 break;
801 case 176400:
802 rate = AUDIO_1764K;
803 N = N_1764K;
804 break;
805 case 192000:
806 rate = AUDIO_192K;
807 N = N_192K;
808 break;
809 default:
810 dev_err(hdmi->dev, "[%s] not support such sample rate %d\n",
811 __func__, audio->sample_rate);
812 return -ENOENT;
813 }
814
815 /* set_audio source I2S */
816 hdmi_writeb(hdmi, HDMI_AUDIO_CTRL1, 0x01);
817 hdmi_writeb(hdmi, AUDIO_SAMPLE_RATE, rate);
818 hdmi_writeb(hdmi, AUDIO_I2S_MODE,
819 I2S_MODE(I2S_STANDARD) | I2S_CHANNEL(channel));
820
821 hdmi_writeb(hdmi, AUDIO_I2S_MAP, 0x00);
822 hdmi_writeb(hdmi, AUDIO_I2S_SWAPS_SPDIF, 0);
823
824 /* Set N value */
825 hdmi_writeb(hdmi, AUDIO_N_H, (N >> 16) & 0x0F);
826 hdmi_writeb(hdmi, AUDIO_N_M, (N >> 8) & 0xFF);
827 hdmi_writeb(hdmi, AUDIO_N_L, N & 0xFF);
828
829 /*Set hdmi nlpcm mode to support hdmi bitstream*/
830 hdmi_writeb(hdmi, HDMI_AUDIO_CHANNEL_STATUS, AUDIO_STATUS_NLPCM(0));
831
832 return rk628_hdmi_config_audio_aai(hdmi, audio);
833 }
834
rk628_hdmi_audio_hw_params(struct device * dev,void * d,struct hdmi_codec_daifmt * daifmt,struct hdmi_codec_params * params)835 static int rk628_hdmi_audio_hw_params(struct device *dev, void *d,
836 struct hdmi_codec_daifmt *daifmt,
837 struct hdmi_codec_params *params)
838 {
839 struct rk628_hdmi *hdmi = dev_get_drvdata(dev);
840 struct audio_info audio = {
841 .sample_width = params->sample_width,
842 .sample_rate = params->sample_rate,
843 .channels = params->channels,
844 };
845
846 if (!hdmi->hdmi_data.sink_has_audio) {
847 dev_err(hdmi->dev, "Sink do not support audio!\n");
848 return -ENODEV;
849 }
850
851 if (!hdmi->bridge.encoder->crtc)
852 return -ENODEV;
853
854 switch (daifmt->fmt) {
855 case HDMI_I2S:
856 break;
857 default:
858 dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt);
859 return -EINVAL;
860 }
861
862 return rk628_hdmi_audio_config_set(hdmi, &audio);
863 }
864
rk628_hdmi_audio_shutdown(struct device * dev,void * d)865 static void rk628_hdmi_audio_shutdown(struct device *dev, void *d)
866 {
867 /* do nothing */
868 }
869
rk628_hdmi_audio_mute(struct device * dev,void * d,bool mute,int direction)870 static int rk628_hdmi_audio_mute(struct device *dev, void *d, bool mute,
871 int direction)
872 {
873 struct rk628_hdmi *hdmi = dev_get_drvdata(dev);
874
875 if (!hdmi->hdmi_data.sink_has_audio) {
876 dev_err(hdmi->dev, "Sink do not support audio!\n");
877 return -ENODEV;
878 }
879
880 hdmi->audio_enable = !mute;
881
882 if (mute)
883 hdmi_modb(hdmi, HDMI_AV_MUTE, AUDIO_MUTE_MASK | AUDIO_PD_MASK,
884 AUDIO_MUTE(1) | AUDIO_PD(1));
885 else
886 hdmi_modb(hdmi, HDMI_AV_MUTE, AUDIO_MUTE_MASK | AUDIO_PD_MASK,
887 AUDIO_MUTE(0) | AUDIO_PD(0));
888
889 return 0;
890 }
891
rk628_hdmi_audio_get_eld(struct device * dev,void * d,u8 * buf,size_t len)892 static int rk628_hdmi_audio_get_eld(struct device *dev, void *d,
893 u8 *buf, size_t len)
894 {
895 struct rk628_hdmi *hdmi = dev_get_drvdata(dev);
896 struct drm_mode_config *config = &hdmi->bridge.dev->mode_config;
897 struct drm_connector *connector;
898 int ret = -ENODEV;
899
900 mutex_lock(&config->mutex);
901 list_for_each_entry(connector, &config->connector_list, head) {
902 if (hdmi->bridge.encoder == connector->encoder) {
903 memcpy(buf, connector->eld,
904 min(sizeof(connector->eld), len));
905 ret = 0;
906 }
907 }
908 mutex_unlock(&config->mutex);
909
910 return ret;
911 }
912
913 static const struct hdmi_codec_ops audio_codec_ops = {
914 .hw_params = rk628_hdmi_audio_hw_params,
915 .audio_shutdown = rk628_hdmi_audio_shutdown,
916 .mute_stream = rk628_hdmi_audio_mute,
917 .no_capture_mute = 1,
918 .get_eld = rk628_hdmi_audio_get_eld,
919 };
920
rk628_hdmi_audio_codec_init(struct rk628_hdmi * hdmi,struct device * dev)921 static int rk628_hdmi_audio_codec_init(struct rk628_hdmi *hdmi,
922 struct device *dev)
923 {
924 struct hdmi_codec_pdata codec_data = {
925 .i2s = 1,
926 .ops = &audio_codec_ops,
927 .max_i2s_channels = 8,
928 };
929
930 hdmi->audio_enable = false;
931 hdmi->audio_pdev = platform_device_register_data(dev,
932 HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE,
933 &codec_data, sizeof(codec_data));
934
935 return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
936 }
937
rk628_hdmi_irq(int irq,void * dev_id)938 static irqreturn_t rk628_hdmi_irq(int irq, void *dev_id)
939 {
940 struct rk628_hdmi *hdmi = dev_id;
941 u8 interrupt;
942
943 /* clear interrupts */
944 rk628_i2c_write(hdmi->rk628, GRF_INTR0_CLR_EN, 0x00040004);
945 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
946 if (!(interrupt & INT_HOTPLUG))
947 return IRQ_HANDLED;
948
949 hdmi_modb(hdmi, HDMI_STATUS, INT_HOTPLUG, INT_HOTPLUG);
950 if (hdmi->connector.dev)
951 drm_helper_hpd_irq_event(hdmi->connector.dev);
952
953 return IRQ_HANDLED;
954 }
955
rk628_hdmi_i2c_read(struct rk628_hdmi * hdmi,struct i2c_msg * msgs)956 static int rk628_hdmi_i2c_read(struct rk628_hdmi *hdmi, struct i2c_msg *msgs)
957 {
958 int length = msgs->len;
959 u8 *buf = msgs->buf;
960 int i;
961 u32 c;
962
963 for (i = 0; i < 5; i++) {
964 msleep(20);
965 c = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
966 if (c & INT_EDID_READY)
967 break;
968 }
969 if ((c & INT_EDID_READY) == 0)
970 return -EAGAIN;
971
972 while (length--)
973 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
974
975 return 0;
976 }
977
rk628_hdmi_i2c_write(struct rk628_hdmi * hdmi,struct i2c_msg * msgs)978 static int rk628_hdmi_i2c_write(struct rk628_hdmi *hdmi, struct i2c_msg *msgs)
979 {
980 /*
981 * The DDC module only support read EDID message, so
982 * we assume that each word write to this i2c adapter
983 * should be the offset of EDID word address.
984 */
985 if ((msgs->len != 1) ||
986 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
987 return -EINVAL;
988
989 if (msgs->addr == DDC_ADDR)
990 hdmi->i2c->ddc_addr = msgs->buf[0];
991 if (msgs->addr == DDC_SEGMENT_ADDR) {
992 hdmi->i2c->segment_addr = msgs->buf[0];
993 return 0;
994 }
995
996 /* Set edid fifo first addr */
997 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
998
999 /* Set edid word address 0x00/0x80 */
1000 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
1001
1002 /* Set edid segment pointer */
1003 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
1004
1005 return 0;
1006 }
1007
rk628_hdmi_i2c_xfer(struct i2c_adapter * adap,struct i2c_msg * msgs,int num)1008 static int rk628_hdmi_i2c_xfer(struct i2c_adapter *adap,
1009 struct i2c_msg *msgs, int num)
1010 {
1011 struct rk628_hdmi *hdmi = i2c_get_adapdata(adap);
1012 struct rk628_hdmi_i2c *i2c = hdmi->i2c;
1013 int i, ret = 0;
1014
1015 mutex_lock(&i2c->lock);
1016
1017 hdmi->i2c->ddc_addr = 0;
1018 hdmi->i2c->segment_addr = 0;
1019
1020 /* Clear the EDID interrupt flag and unmute the interrupt */
1021 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, INT_EDID_READY);
1022 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, INT_EDID_READY_MASK);
1023
1024 for (i = 0; i < num; i++) {
1025 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n",
1026 i + 1, num, msgs[i].len, msgs[i].flags);
1027
1028 if (msgs[i].flags & I2C_M_RD)
1029 ret = rk628_hdmi_i2c_read(hdmi, &msgs[i]);
1030 else
1031 ret = rk628_hdmi_i2c_write(hdmi, &msgs[i]);
1032
1033 if (ret < 0)
1034 break;
1035 }
1036
1037 if (!ret)
1038 ret = num;
1039
1040 /* Mute HDMI EDID interrupt */
1041 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
1042 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, INT_EDID_READY);
1043
1044 mutex_unlock(&i2c->lock);
1045
1046 return ret;
1047 }
1048
rk628_hdmi_i2c_func(struct i2c_adapter * adapter)1049 static u32 rk628_hdmi_i2c_func(struct i2c_adapter *adapter)
1050 {
1051 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1052 }
1053
1054 static const struct i2c_algorithm rk628_hdmi_algorithm = {
1055 .master_xfer = rk628_hdmi_i2c_xfer,
1056 .functionality = rk628_hdmi_i2c_func,
1057 };
1058
rk628_hdmi_i2c_adapter(struct rk628_hdmi * hdmi)1059 static struct i2c_adapter *rk628_hdmi_i2c_adapter(struct rk628_hdmi *hdmi)
1060 {
1061 struct i2c_adapter *adap;
1062 struct rk628_hdmi_i2c *i2c;
1063 int ret;
1064
1065 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
1066 if (!i2c)
1067 return ERR_PTR(-ENOMEM);
1068
1069 mutex_init(&i2c->lock);
1070
1071 adap = &i2c->adap;
1072 adap->class = I2C_CLASS_DDC;
1073 adap->owner = THIS_MODULE;
1074 adap->dev.parent = hdmi->dev;
1075 adap->dev.of_node = hdmi->dev->of_node;
1076 adap->algo = &rk628_hdmi_algorithm;
1077 strscpy(adap->name, "RK628 HDMI", sizeof(adap->name));
1078 i2c_set_adapdata(adap, hdmi);
1079
1080 ret = i2c_add_adapter(adap);
1081 if (ret) {
1082 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
1083 devm_kfree(hdmi->dev, i2c);
1084 return ERR_PTR(ret);
1085 }
1086
1087 hdmi->i2c = i2c;
1088
1089 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
1090
1091 return adap;
1092 }
1093
rk628_hdmitx_enable(struct rk628 * rk628)1094 int rk628_hdmitx_enable(struct rk628 *rk628)
1095 {
1096 struct device *dev = rk628->dev;
1097 struct rk628_hdmi *hdmi;
1098 int irq;
1099 int ret;
1100
1101 if (!of_device_is_available(dev->of_node))
1102 return -ENODEV;
1103
1104 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1105 if (!hdmi)
1106 return -ENOMEM;
1107
1108
1109 hdmi->dev = dev;
1110 hdmi->rk628 = rk628;
1111
1112 irq = rk628->client->irq;
1113 if (irq < 0)
1114 return irq;
1115 dev_set_drvdata(dev, hdmi);
1116
1117 /* selete int io function */
1118 rk628_i2c_write(rk628, GRF_GPIO0AB_SEL_CON, 0x70007000);
1119 rk628_i2c_write(rk628, GRF_GPIO0AB_SEL_CON, 0x055c055c);
1120
1121 /* hdmitx vclk pllref select Pin_vclk */
1122 rk628_i2c_update_bits(rk628, GRF_POST_PROC_CON,
1123 SW_HDMITX_VCLK_PLLREF_SEL_MASK,
1124 SW_HDMITX_VCLK_PLLREF_SEL(1));
1125 /* set output mode to HDMI */
1126 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_OUTPUT_MODE_MASK,
1127 SW_OUTPUT_MODE(OUTPUT_MODE_HDMI));
1128
1129 rk628_hdmi_reset(hdmi);
1130
1131 hdmi->ddc = rk628_hdmi_i2c_adapter(hdmi);
1132 if (IS_ERR(hdmi->ddc)) {
1133 ret = PTR_ERR(hdmi->ddc);
1134 hdmi->ddc = NULL;
1135 goto fail;
1136 }
1137
1138 /*
1139 * When IP controller haven't configured to an accurate video
1140 * timing, then the TMDS clock source would be switched to
1141 * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
1142 * and reconfigure the DDC clock.
1143 */
1144 hdmi->tmds_rate = 24000 * 1000;
1145
1146 /* hdmitx int en */
1147 rk628_i2c_write(rk628, GRF_INTR0_EN, 0x00040004);
1148 rk628_hdmi_i2c_init(hdmi);
1149
1150 rk628_hdmi_audio_codec_init(hdmi, dev);
1151
1152 ret = devm_request_threaded_irq(dev, irq, NULL,
1153 rk628_hdmi_irq,
1154 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
1155 dev_name(dev), hdmi);
1156 if (ret) {
1157 dev_err(dev, "failed to request hdmi irq: %d\n", ret);
1158 goto fail;
1159 }
1160
1161 /* Unmute hotplug interrupt */
1162 hdmi_modb(hdmi, HDMI_STATUS, MASK_INT_HOTPLUG_MASK,
1163 MASK_INT_HOTPLUG(1));
1164 hdmi->bridge.funcs = &rk628_hdmi_bridge_funcs;
1165 hdmi->bridge.of_node = dev->of_node;
1166
1167 drm_bridge_add(&hdmi->bridge);
1168
1169 hdmi->extcon = devm_extcon_dev_allocate(hdmi->dev, rk628_hdmi_cable);
1170 if (IS_ERR(hdmi->extcon)) {
1171 dev_err(hdmi->dev, "allocate extcon failed\n");
1172 ret = PTR_ERR(hdmi->extcon);
1173 goto fail;
1174 }
1175
1176 ret = devm_extcon_dev_register(hdmi->dev, hdmi->extcon);
1177 if (ret) {
1178 dev_err(dev, "failed to register extcon: %d\n", ret);
1179 goto fail;
1180 }
1181
1182 ret = extcon_set_property_capability(hdmi->extcon, EXTCON_DISP_HDMI,
1183 EXTCON_PROP_DISP_HPD);
1184 if (ret) {
1185 dev_err(dev, "failed to set USB property capability: %d\n",
1186 ret);
1187 goto fail;
1188 }
1189
1190 return 0;
1191
1192 fail:
1193 return ret;
1194 }
1195
1196 MODULE_AUTHOR("Chen Shunqing <csq@rock-chips.com>");
1197 MODULE_DESCRIPTION("Rockchip RK628 HDMI driver");
1198 MODULE_LICENSE("GPL");
1199