1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
10 #include <linux/delay.h>
11 #include <linux/err.h>
12 #include <linux/hdmi.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/platform_device.h>
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_edid.h>
21 #include <drm/drm_of.h>
22 #include <drm/drm_probe_helper.h>
23 #include <drm/drm_simple_kms_helper.h>
25 #include "rockchip_drm_drv.h"
26 #include "rockchip_drm_vop.h"
28 #include "inno_hdmi.h"
30 struct hdmi_data_info {
33 unsigned int enc_in_format;
34 unsigned int enc_out_format;
35 unsigned int colorimetry;
38 struct inno_hdmi_i2c {
39 struct i2c_adapter adap;
45 struct completion cmp;
50 struct drm_device *drm_dev;
56 struct drm_connector connector;
57 struct rockchip_encoder encoder;
59 struct inno_hdmi_i2c *i2c;
60 struct i2c_adapter *ddc;
62 unsigned int tmds_rate;
64 struct hdmi_data_info hdmi_data;
65 struct drm_display_mode previous_mode;
68 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
70 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
72 return container_of(rkencoder, struct inno_hdmi, encoder);
75 static struct inno_hdmi *connector_to_inno_hdmi(struct drm_connector *connector)
77 return container_of(connector, struct inno_hdmi, connector);
81 CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
82 CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
83 CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
84 CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
85 CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
86 CSC_RGB_0_255_TO_RGB_16_235_8BIT,
89 static const char coeff_csc[][24] = {
91 * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
92 * R = 1.164*Y + 1.596*V - 204
93 * G = 1.164*Y - 0.391*U - 0.813*V + 154
94 * B = 1.164*Y + 2.018*U - 258
97 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
98 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
99 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
102 * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
103 * R = Y + 1.402*V - 248
104 * G = Y - 0.344*U - 0.714*V + 135
105 * B = Y + 1.772*U - 227
108 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
109 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
110 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
113 * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
114 * R = 1.164*Y + 1.793*V - 248
115 * G = 1.164*Y - 0.213*U - 0.534*V + 77
116 * B = 1.164*Y + 2.115*U - 289
119 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
120 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
121 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
125 * RGB2YUV:601 SD mode:
126 * Cb = -0.291G - 0.148R + 0.439B + 128
127 * Y = 0.504G + 0.257R + 0.098B + 16
128 * Cr = -0.368G + 0.439R - 0.071B + 128
131 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
132 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
133 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
136 * RGB2YUV:709 HD mode:
137 * Cb = - 0.338G - 0.101R + 0.439B + 128
138 * Y = 0.614G + 0.183R + 0.062B + 16
139 * Cr = - 0.399G + 0.439R - 0.040B + 128
142 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
143 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
144 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
147 * RGB[0:255]2RGB[16:235]:
148 * R' = R x (235-16)/255 + 16;
149 * G' = G x (235-16)/255 + 16;
150 * B' = B x (235-16)/255 + 16;
153 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
154 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
155 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10
159 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
161 return readl_relaxed(hdmi->regs + (offset) * 0x04);
164 static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val)
166 writel_relaxed(val, hdmi->regs + (offset) * 0x04);
169 static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset,
172 u8 temp = hdmi_readb(hdmi, offset) & ~msk;
175 hdmi_writeb(hdmi, offset, temp);
178 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
182 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
184 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
185 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
187 /* Clear the EDID interrupt flag and mute the interrupt */
188 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
189 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
192 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
195 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON);
197 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
200 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
204 inno_hdmi_sys_power(hdmi, false);
206 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
207 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
209 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
210 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
211 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
212 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
213 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
214 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
216 inno_hdmi_sys_power(hdmi, true);
220 inno_hdmi_sys_power(hdmi, false);
221 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
222 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
223 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
224 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
229 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
233 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
238 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
241 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
244 msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
245 val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
246 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
248 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
251 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
252 union hdmi_infoframe *frame, u32 frame_index,
253 u32 mask, u32 disable, u32 enable)
256 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
258 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
261 u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
264 rc = hdmi_infoframe_pack(frame, packed_frame,
265 sizeof(packed_frame));
269 for (i = 0; i < rc; i++)
270 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
274 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
280 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
281 struct drm_display_mode *mode)
283 union hdmi_infoframe frame;
286 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
290 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI,
291 m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
294 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
295 struct drm_display_mode *mode)
297 union hdmi_infoframe frame;
300 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
304 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
305 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
306 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
307 frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
309 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
311 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
314 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
316 struct hdmi_data_info *data = &hdmi->hdmi_data;
317 int c0_c2_change = 0;
324 /* Input video mode is SDR RGB24bit, data enable signal from external */
325 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL |
326 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444));
328 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
329 value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) |
330 v_VIDEO_OUTPUT_COLOR(0) |
331 v_VIDEO_INPUT_CSP(0);
332 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
334 if (data->enc_in_format == data->enc_out_format) {
335 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
336 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
337 value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
338 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
340 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
341 m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
342 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
343 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
348 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
349 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
350 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
351 csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
352 auto_csc = AUTO_CSC_DISABLE;
353 c0_c2_change = C0_C2_CHANGE_DISABLE;
354 csc_enable = v_CSC_ENABLE;
355 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
356 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
357 csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
358 auto_csc = AUTO_CSC_ENABLE;
359 c0_c2_change = C0_C2_CHANGE_DISABLE;
360 csc_enable = v_CSC_DISABLE;
363 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
364 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
365 csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
366 auto_csc = AUTO_CSC_DISABLE;
367 c0_c2_change = C0_C2_CHANGE_DISABLE;
368 csc_enable = v_CSC_ENABLE;
369 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
370 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
371 csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
372 auto_csc = AUTO_CSC_ENABLE;
373 c0_c2_change = C0_C2_CHANGE_DISABLE;
374 csc_enable = v_CSC_DISABLE;
378 for (i = 0; i < 24; i++)
379 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i,
380 coeff_csc[csc_mode][i]);
382 value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
383 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
384 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC |
385 m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) |
386 v_VIDEO_C0_C2_SWAP(c0_c2_change));
391 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
392 struct drm_display_mode *mode)
396 /* Set detail external video timing polarity and interlace mode */
397 value = v_EXTERANL_VIDEO(1);
398 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
399 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
400 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
401 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
402 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
403 v_INETLACE(1) : v_INETLACE(0);
404 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value);
406 /* Set detail external video timing */
407 value = mode->htotal;
408 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF);
409 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
411 value = mode->htotal - mode->hdisplay;
412 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
413 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
415 value = mode->hsync_start - mode->hdisplay;
416 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
417 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
419 value = mode->hsync_end - mode->hsync_start;
420 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF);
421 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
423 value = mode->vtotal;
424 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF);
425 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
427 value = mode->vtotal - mode->vdisplay;
428 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
430 value = mode->vsync_start - mode->vdisplay;
431 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
433 value = mode->vsync_end - mode->vsync_start;
434 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF);
436 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e);
437 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c);
438 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01);
443 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
444 struct drm_display_mode *mode)
446 struct drm_display_info *display = &hdmi->connector.display_info;
448 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
450 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
451 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
453 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
454 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
455 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
456 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
457 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
459 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
461 /* Mute video and audio output */
462 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
463 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
466 hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
467 v_HDMI_DVI(display->is_hdmi));
469 inno_hdmi_config_video_timing(hdmi, mode);
471 inno_hdmi_config_video_csc(hdmi);
473 if (display->is_hdmi) {
474 inno_hdmi_config_video_avi(hdmi, mode);
475 inno_hdmi_config_video_vsi(hdmi, mode);
479 * When IP controller have configured to an accurate video
480 * timing, then the TMDS clock source would be switched to
481 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
482 * clock rate, and reconfigure the DDC clock.
484 hdmi->tmds_rate = mode->clock * 1000;
485 inno_hdmi_i2c_init(hdmi);
487 /* Unmute video and audio output */
488 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
489 v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
494 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
495 struct drm_display_mode *mode,
496 struct drm_display_mode *adj_mode)
498 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
500 inno_hdmi_setup(hdmi, adj_mode);
502 /* Store the display mode for plugin/DPMS poweron events */
503 drm_mode_copy(&hdmi->previous_mode, adj_mode);
506 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
508 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
510 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
513 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
515 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
517 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
520 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
521 const struct drm_display_mode *mode,
522 struct drm_display_mode *adj_mode)
528 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
529 struct drm_crtc_state *crtc_state,
530 struct drm_connector_state *conn_state)
532 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
534 s->output_mode = ROCKCHIP_OUT_MODE_P888;
535 s->output_type = DRM_MODE_CONNECTOR_HDMIA;
540 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
541 .enable = inno_hdmi_encoder_enable,
542 .disable = inno_hdmi_encoder_disable,
543 .mode_fixup = inno_hdmi_encoder_mode_fixup,
544 .mode_set = inno_hdmi_encoder_mode_set,
545 .atomic_check = inno_hdmi_encoder_atomic_check,
548 static enum drm_connector_status
549 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
551 struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
553 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
554 connector_status_connected : connector_status_disconnected;
557 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
559 struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
566 edid = drm_get_edid(connector, hdmi->ddc);
568 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
569 drm_connector_update_edid_property(connector, edid);
570 ret = drm_add_edid_modes(connector, edid);
577 static enum drm_mode_status
578 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
579 struct drm_display_mode *mode)
585 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
586 uint32_t maxX, uint32_t maxY)
588 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
591 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
593 drm_connector_unregister(connector);
594 drm_connector_cleanup(connector);
597 static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
598 .fill_modes = inno_hdmi_probe_single_connector_modes,
599 .detect = inno_hdmi_connector_detect,
600 .destroy = inno_hdmi_connector_destroy,
601 .reset = drm_atomic_helper_connector_reset,
602 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
603 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
606 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
607 .get_modes = inno_hdmi_connector_get_modes,
608 .mode_valid = inno_hdmi_connector_mode_valid,
611 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
613 struct drm_encoder *encoder = &hdmi->encoder.encoder;
614 struct device *dev = hdmi->dev;
616 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
619 * If we failed to find the CRTC(s) which this encoder is
620 * supposed to be connected to, it's because the CRTC has
621 * not been registered yet. Defer probing, and hope that
622 * the required CRTC is added later.
624 if (encoder->possible_crtcs == 0)
625 return -EPROBE_DEFER;
627 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
628 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
630 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
632 drm_connector_helper_add(&hdmi->connector,
633 &inno_hdmi_connector_helper_funcs);
634 drm_connector_init_with_ddc(drm, &hdmi->connector,
635 &inno_hdmi_connector_funcs,
636 DRM_MODE_CONNECTOR_HDMIA,
639 drm_connector_attach_encoder(&hdmi->connector, encoder);
644 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
646 struct inno_hdmi_i2c *i2c = hdmi->i2c;
649 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
650 if (!(stat & m_INT_EDID_READY))
653 /* Clear HDMI EDID interrupt flag */
654 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
661 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
663 struct inno_hdmi *hdmi = dev_id;
664 irqreturn_t ret = IRQ_NONE;
668 ret = inno_hdmi_i2c_irq(hdmi);
670 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
671 if (interrupt & m_INT_HOTPLUG) {
672 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
673 ret = IRQ_WAKE_THREAD;
679 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
681 struct inno_hdmi *hdmi = dev_id;
683 drm_helper_hpd_irq_event(hdmi->connector.dev);
688 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
690 int length = msgs->len;
694 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
699 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
704 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
707 * The DDC module only support read EDID message, so
708 * we assume that each word write to this i2c adapter
709 * should be the offset of EDID word address.
711 if ((msgs->len != 1) ||
712 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
715 reinit_completion(&hdmi->i2c->cmp);
717 if (msgs->addr == DDC_SEGMENT_ADDR)
718 hdmi->i2c->segment_addr = msgs->buf[0];
719 if (msgs->addr == DDC_ADDR)
720 hdmi->i2c->ddc_addr = msgs->buf[0];
722 /* Set edid fifo first addr */
723 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
725 /* Set edid word address 0x00/0x80 */
726 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
728 /* Set edid segment pointer */
729 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
734 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
735 struct i2c_msg *msgs, int num)
737 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
738 struct inno_hdmi_i2c *i2c = hdmi->i2c;
741 mutex_lock(&i2c->lock);
743 /* Clear the EDID interrupt flag and unmute the interrupt */
744 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
745 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
747 for (i = 0; i < num; i++) {
748 DRM_DEV_DEBUG(hdmi->dev,
749 "xfer: num: %d/%d, len: %d, flags: %#x\n",
750 i + 1, num, msgs[i].len, msgs[i].flags);
752 if (msgs[i].flags & I2C_M_RD)
753 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
755 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
764 /* Mute HDMI EDID interrupt */
765 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
767 mutex_unlock(&i2c->lock);
772 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
774 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
777 static const struct i2c_algorithm inno_hdmi_algorithm = {
778 .master_xfer = inno_hdmi_i2c_xfer,
779 .functionality = inno_hdmi_i2c_func,
782 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
784 struct i2c_adapter *adap;
785 struct inno_hdmi_i2c *i2c;
788 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
790 return ERR_PTR(-ENOMEM);
792 mutex_init(&i2c->lock);
793 init_completion(&i2c->cmp);
796 adap->class = I2C_CLASS_DDC;
797 adap->owner = THIS_MODULE;
798 adap->dev.parent = hdmi->dev;
799 adap->dev.of_node = hdmi->dev->of_node;
800 adap->algo = &inno_hdmi_algorithm;
801 strscpy(adap->name, "Inno HDMI", sizeof(adap->name));
802 i2c_set_adapdata(adap, hdmi);
804 ret = i2c_add_adapter(adap);
806 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
807 devm_kfree(hdmi->dev, i2c);
813 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
818 static int inno_hdmi_bind(struct device *dev, struct device *master,
821 struct platform_device *pdev = to_platform_device(dev);
822 struct drm_device *drm = data;
823 struct inno_hdmi *hdmi;
827 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
834 hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
835 if (IS_ERR(hdmi->regs))
836 return PTR_ERR(hdmi->regs);
838 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk");
839 if (IS_ERR(hdmi->pclk)) {
840 DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n");
841 return PTR_ERR(hdmi->pclk);
844 ret = clk_prepare_enable(hdmi->pclk);
846 DRM_DEV_ERROR(hdmi->dev,
847 "Cannot enable HDMI pclk clock: %d\n", ret);
851 irq = platform_get_irq(pdev, 0);
854 goto err_disable_clk;
857 inno_hdmi_reset(hdmi);
859 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
860 if (IS_ERR(hdmi->ddc)) {
861 ret = PTR_ERR(hdmi->ddc);
863 goto err_disable_clk;
867 * When IP controller haven't configured to an accurate video
868 * timing, then the TMDS clock source would be switched to
869 * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
870 * and reconfigure the DDC clock.
872 hdmi->tmds_rate = clk_get_rate(hdmi->pclk);
873 inno_hdmi_i2c_init(hdmi);
875 ret = inno_hdmi_register(drm, hdmi);
877 goto err_put_adapter;
879 dev_set_drvdata(dev, hdmi);
881 /* Unmute hotplug interrupt */
882 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
884 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
885 inno_hdmi_irq, IRQF_SHARED,
886 dev_name(dev), hdmi);
888 goto err_cleanup_hdmi;
892 hdmi->connector.funcs->destroy(&hdmi->connector);
893 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
895 i2c_put_adapter(hdmi->ddc);
897 clk_disable_unprepare(hdmi->pclk);
901 static void inno_hdmi_unbind(struct device *dev, struct device *master,
904 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
906 hdmi->connector.funcs->destroy(&hdmi->connector);
907 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
909 i2c_put_adapter(hdmi->ddc);
910 clk_disable_unprepare(hdmi->pclk);
913 static const struct component_ops inno_hdmi_ops = {
914 .bind = inno_hdmi_bind,
915 .unbind = inno_hdmi_unbind,
918 static int inno_hdmi_probe(struct platform_device *pdev)
920 return component_add(&pdev->dev, &inno_hdmi_ops);
923 static void inno_hdmi_remove(struct platform_device *pdev)
925 component_del(&pdev->dev, &inno_hdmi_ops);
928 static const struct of_device_id inno_hdmi_dt_ids[] = {
929 { .compatible = "rockchip,rk3036-inno-hdmi",
933 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
935 struct platform_driver inno_hdmi_driver = {
936 .probe = inno_hdmi_probe,
937 .remove_new = inno_hdmi_remove,
939 .name = "innohdmi-rockchip",
940 .of_match_table = inno_hdmi_dt_ids,