xref: /OK3568_Linux_fs/kernel/drivers/misc/rk628/rk628_hdmitx.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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