1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Zheng Yang <zhengyang@rock-chips.com>
5 * Yakir Yang <ykk@rock-chips.com>
10 #include <linux/delay.h>
11 #include <linux/err.h>
12 #include <linux/hdmi.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/of_device.h>
18 #include <drm/drm_atomic_helper.h>
19 #include <drm/drm_edid.h>
20 #include <drm/drm_of.h>
21 #include <drm/drm_probe_helper.h>
22 #include <drm/drm_simple_kms_helper.h>
24 #include "rockchip_drm_drv.h"
25 #include "rockchip_drm_vop.h"
27 #include "inno_hdmi.h"
29 struct hdmi_data_info {
32 unsigned int enc_in_format;
33 unsigned int enc_out_format;
34 unsigned int colorimetry;
37 struct inno_hdmi_i2c {
38 struct i2c_adapter adap;
44 struct completion cmp;
49 struct drm_device *drm_dev;
55 struct drm_connector connector;
56 struct rockchip_encoder encoder;
58 struct inno_hdmi_i2c *i2c;
59 struct i2c_adapter *ddc;
61 unsigned int tmds_rate;
63 struct hdmi_data_info hdmi_data;
64 struct drm_display_mode previous_mode;
67 static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
69 struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
71 return container_of(rkencoder, struct inno_hdmi, encoder);
74 static struct inno_hdmi *connector_to_inno_hdmi(struct drm_connector *connector)
76 return container_of(connector, struct inno_hdmi, connector);
80 CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
81 CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
82 CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
83 CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
84 CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
85 CSC_RGB_0_255_TO_RGB_16_235_8BIT,
88 static const char coeff_csc[][24] = {
90 * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
91 * R = 1.164*Y + 1.596*V - 204
92 * G = 1.164*Y - 0.391*U - 0.813*V + 154
93 * B = 1.164*Y + 2.018*U - 258
96 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
97 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
98 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
101 * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
102 * R = Y + 1.402*V - 248
103 * G = Y - 0.344*U - 0.714*V + 135
104 * B = Y + 1.772*U - 227
107 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
108 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
109 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
112 * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
113 * R = 1.164*Y + 1.793*V - 248
114 * G = 1.164*Y - 0.213*U - 0.534*V + 77
115 * B = 1.164*Y + 2.115*U - 289
118 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
119 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
120 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
124 * RGB2YUV:601 SD mode:
125 * Cb = -0.291G - 0.148R + 0.439B + 128
126 * Y = 0.504G + 0.257R + 0.098B + 16
127 * Cr = -0.368G + 0.439R - 0.071B + 128
130 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
131 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
132 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
135 * RGB2YUV:709 HD mode:
136 * Cb = - 0.338G - 0.101R + 0.439B + 128
137 * Y = 0.614G + 0.183R + 0.062B + 16
138 * Cr = - 0.399G + 0.439R - 0.040B + 128
141 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
142 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
143 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
146 * RGB[0:255]2RGB[16:235]:
147 * R' = R x (235-16)/255 + 16;
148 * G' = G x (235-16)/255 + 16;
149 * B' = B x (235-16)/255 + 16;
152 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
153 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
154 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10
158 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
160 return readl_relaxed(hdmi->regs + (offset) * 0x04);
163 static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val)
165 writel_relaxed(val, hdmi->regs + (offset) * 0x04);
168 static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset,
171 u8 temp = hdmi_readb(hdmi, offset) & ~msk;
174 hdmi_writeb(hdmi, offset, temp);
177 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
181 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
183 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
184 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
186 /* Clear the EDID interrupt flag and mute the interrupt */
187 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
188 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
191 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
194 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON);
196 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
199 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
203 inno_hdmi_sys_power(hdmi, false);
205 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
206 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
208 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
209 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
210 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
211 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
212 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
213 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
215 inno_hdmi_sys_power(hdmi, true);
219 inno_hdmi_sys_power(hdmi, false);
220 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
221 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
222 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
223 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
228 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
232 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
237 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
240 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
243 msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
244 val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
245 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
247 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
250 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
251 union hdmi_infoframe *frame, u32 frame_index,
252 u32 mask, u32 disable, u32 enable)
255 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
257 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
260 u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
263 rc = hdmi_infoframe_pack(frame, packed_frame,
264 sizeof(packed_frame));
268 for (i = 0; i < rc; i++)
269 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
273 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
279 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
280 struct drm_display_mode *mode)
282 union hdmi_infoframe frame;
285 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
289 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI,
290 m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
293 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
294 struct drm_display_mode *mode)
296 union hdmi_infoframe frame;
299 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
303 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
304 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
305 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
306 frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
308 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
310 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
313 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
315 struct hdmi_data_info *data = &hdmi->hdmi_data;
316 int c0_c2_change = 0;
323 /* Input video mode is SDR RGB24bit, data enable signal from external */
324 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL |
325 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444));
327 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
328 value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) |
329 v_VIDEO_OUTPUT_COLOR(0) |
330 v_VIDEO_INPUT_CSP(0);
331 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
333 if (data->enc_in_format == data->enc_out_format) {
334 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
335 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
336 value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
337 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
339 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
340 m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
341 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
342 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
347 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
348 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
349 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
350 csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
351 auto_csc = AUTO_CSC_DISABLE;
352 c0_c2_change = C0_C2_CHANGE_DISABLE;
353 csc_enable = v_CSC_ENABLE;
354 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
355 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
356 csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
357 auto_csc = AUTO_CSC_ENABLE;
358 c0_c2_change = C0_C2_CHANGE_DISABLE;
359 csc_enable = v_CSC_DISABLE;
362 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
363 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
364 csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
365 auto_csc = AUTO_CSC_DISABLE;
366 c0_c2_change = C0_C2_CHANGE_DISABLE;
367 csc_enable = v_CSC_ENABLE;
368 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
369 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
370 csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
371 auto_csc = AUTO_CSC_ENABLE;
372 c0_c2_change = C0_C2_CHANGE_DISABLE;
373 csc_enable = v_CSC_DISABLE;
377 for (i = 0; i < 24; i++)
378 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i,
379 coeff_csc[csc_mode][i]);
381 value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
382 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
383 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC |
384 m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) |
385 v_VIDEO_C0_C2_SWAP(c0_c2_change));
390 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
391 struct drm_display_mode *mode)
395 /* Set detail external video timing polarity and interlace mode */
396 value = v_EXTERANL_VIDEO(1);
397 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
398 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
399 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
400 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
401 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
402 v_INETLACE(1) : v_INETLACE(0);
403 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value);
405 /* Set detail external video timing */
406 value = mode->htotal;
407 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF);
408 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
410 value = mode->htotal - mode->hdisplay;
411 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
412 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
414 value = mode->hsync_start - mode->hdisplay;
415 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
416 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
418 value = mode->hsync_end - mode->hsync_start;
419 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF);
420 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
422 value = mode->vtotal;
423 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF);
424 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
426 value = mode->vtotal - mode->vdisplay;
427 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
429 value = mode->vsync_start - mode->vdisplay;
430 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
432 value = mode->vsync_end - mode->vsync_start;
433 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF);
435 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e);
436 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c);
437 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01);
442 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
443 struct drm_display_mode *mode)
445 struct drm_display_info *display = &hdmi->connector.display_info;
447 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
449 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
450 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
452 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
453 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
454 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
455 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
456 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
458 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
460 /* Mute video and audio output */
461 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
462 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
465 hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
466 v_HDMI_DVI(display->is_hdmi));
468 inno_hdmi_config_video_timing(hdmi, mode);
470 inno_hdmi_config_video_csc(hdmi);
472 if (display->is_hdmi) {
473 inno_hdmi_config_video_avi(hdmi, mode);
474 inno_hdmi_config_video_vsi(hdmi, mode);
478 * When IP controller have configured to an accurate video
479 * timing, then the TMDS clock source would be switched to
480 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
481 * clock rate, and reconfigure the DDC clock.
483 hdmi->tmds_rate = mode->clock * 1000;
484 inno_hdmi_i2c_init(hdmi);
486 /* Unmute video and audio output */
487 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
488 v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
493 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
494 struct drm_display_mode *mode,
495 struct drm_display_mode *adj_mode)
497 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
499 inno_hdmi_setup(hdmi, adj_mode);
501 /* Store the display mode for plugin/DPMS poweron events */
502 drm_mode_copy(&hdmi->previous_mode, adj_mode);
505 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
507 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
509 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
512 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
514 struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
516 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
519 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
520 const struct drm_display_mode *mode,
521 struct drm_display_mode *adj_mode)
527 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
528 struct drm_crtc_state *crtc_state,
529 struct drm_connector_state *conn_state)
531 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
533 s->output_mode = ROCKCHIP_OUT_MODE_P888;
534 s->output_type = DRM_MODE_CONNECTOR_HDMIA;
539 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
540 .enable = inno_hdmi_encoder_enable,
541 .disable = inno_hdmi_encoder_disable,
542 .mode_fixup = inno_hdmi_encoder_mode_fixup,
543 .mode_set = inno_hdmi_encoder_mode_set,
544 .atomic_check = inno_hdmi_encoder_atomic_check,
547 static enum drm_connector_status
548 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
550 struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
552 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
553 connector_status_connected : connector_status_disconnected;
556 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
558 struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
565 edid = drm_get_edid(connector, hdmi->ddc);
567 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
568 drm_connector_update_edid_property(connector, edid);
569 ret = drm_add_edid_modes(connector, edid);
576 static enum drm_mode_status
577 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
578 struct drm_display_mode *mode)
584 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
585 uint32_t maxX, uint32_t maxY)
587 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
590 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
592 drm_connector_unregister(connector);
593 drm_connector_cleanup(connector);
596 static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
597 .fill_modes = inno_hdmi_probe_single_connector_modes,
598 .detect = inno_hdmi_connector_detect,
599 .destroy = inno_hdmi_connector_destroy,
600 .reset = drm_atomic_helper_connector_reset,
601 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
602 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
605 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
606 .get_modes = inno_hdmi_connector_get_modes,
607 .mode_valid = inno_hdmi_connector_mode_valid,
610 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
612 struct drm_encoder *encoder = &hdmi->encoder.encoder;
613 struct device *dev = hdmi->dev;
615 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
618 * If we failed to find the CRTC(s) which this encoder is
619 * supposed to be connected to, it's because the CRTC has
620 * not been registered yet. Defer probing, and hope that
621 * the required CRTC is added later.
623 if (encoder->possible_crtcs == 0)
624 return -EPROBE_DEFER;
626 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
627 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
629 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
631 drm_connector_helper_add(&hdmi->connector,
632 &inno_hdmi_connector_helper_funcs);
633 drm_connector_init_with_ddc(drm, &hdmi->connector,
634 &inno_hdmi_connector_funcs,
635 DRM_MODE_CONNECTOR_HDMIA,
638 drm_connector_attach_encoder(&hdmi->connector, encoder);
643 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
645 struct inno_hdmi_i2c *i2c = hdmi->i2c;
648 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
649 if (!(stat & m_INT_EDID_READY))
652 /* Clear HDMI EDID interrupt flag */
653 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
660 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
662 struct inno_hdmi *hdmi = dev_id;
663 irqreturn_t ret = IRQ_NONE;
667 ret = inno_hdmi_i2c_irq(hdmi);
669 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
670 if (interrupt & m_INT_HOTPLUG) {
671 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
672 ret = IRQ_WAKE_THREAD;
678 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
680 struct inno_hdmi *hdmi = dev_id;
682 drm_helper_hpd_irq_event(hdmi->connector.dev);
687 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
689 int length = msgs->len;
693 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
698 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
703 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
706 * The DDC module only support read EDID message, so
707 * we assume that each word write to this i2c adapter
708 * should be the offset of EDID word address.
710 if ((msgs->len != 1) ||
711 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
714 reinit_completion(&hdmi->i2c->cmp);
716 if (msgs->addr == DDC_SEGMENT_ADDR)
717 hdmi->i2c->segment_addr = msgs->buf[0];
718 if (msgs->addr == DDC_ADDR)
719 hdmi->i2c->ddc_addr = msgs->buf[0];
721 /* Set edid fifo first addr */
722 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
724 /* Set edid word address 0x00/0x80 */
725 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
727 /* Set edid segment pointer */
728 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
733 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
734 struct i2c_msg *msgs, int num)
736 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
737 struct inno_hdmi_i2c *i2c = hdmi->i2c;
740 mutex_lock(&i2c->lock);
742 /* Clear the EDID interrupt flag and unmute the interrupt */
743 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
744 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
746 for (i = 0; i < num; i++) {
747 DRM_DEV_DEBUG(hdmi->dev,
748 "xfer: num: %d/%d, len: %d, flags: %#x\n",
749 i + 1, num, msgs[i].len, msgs[i].flags);
751 if (msgs[i].flags & I2C_M_RD)
752 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
754 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
763 /* Mute HDMI EDID interrupt */
764 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
766 mutex_unlock(&i2c->lock);
771 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
773 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
776 static const struct i2c_algorithm inno_hdmi_algorithm = {
777 .master_xfer = inno_hdmi_i2c_xfer,
778 .functionality = inno_hdmi_i2c_func,
781 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
783 struct i2c_adapter *adap;
784 struct inno_hdmi_i2c *i2c;
787 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
789 return ERR_PTR(-ENOMEM);
791 mutex_init(&i2c->lock);
792 init_completion(&i2c->cmp);
795 adap->class = I2C_CLASS_DDC;
796 adap->owner = THIS_MODULE;
797 adap->dev.parent = hdmi->dev;
798 adap->dev.of_node = hdmi->dev->of_node;
799 adap->algo = &inno_hdmi_algorithm;
800 strscpy(adap->name, "Inno HDMI", sizeof(adap->name));
801 i2c_set_adapdata(adap, hdmi);
803 ret = i2c_add_adapter(adap);
805 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
806 devm_kfree(hdmi->dev, i2c);
812 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
817 static int inno_hdmi_bind(struct device *dev, struct device *master,
820 struct platform_device *pdev = to_platform_device(dev);
821 struct drm_device *drm = data;
822 struct inno_hdmi *hdmi;
826 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
833 hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
834 if (IS_ERR(hdmi->regs))
835 return PTR_ERR(hdmi->regs);
837 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk");
838 if (IS_ERR(hdmi->pclk)) {
839 DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n");
840 return PTR_ERR(hdmi->pclk);
843 ret = clk_prepare_enable(hdmi->pclk);
845 DRM_DEV_ERROR(hdmi->dev,
846 "Cannot enable HDMI pclk clock: %d\n", ret);
850 irq = platform_get_irq(pdev, 0);
853 goto err_disable_clk;
856 inno_hdmi_reset(hdmi);
858 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
859 if (IS_ERR(hdmi->ddc)) {
860 ret = PTR_ERR(hdmi->ddc);
862 goto err_disable_clk;
866 * When IP controller haven't configured to an accurate video
867 * timing, then the TMDS clock source would be switched to
868 * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
869 * and reconfigure the DDC clock.
871 hdmi->tmds_rate = clk_get_rate(hdmi->pclk);
872 inno_hdmi_i2c_init(hdmi);
874 ret = inno_hdmi_register(drm, hdmi);
876 goto err_put_adapter;
878 dev_set_drvdata(dev, hdmi);
880 /* Unmute hotplug interrupt */
881 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
883 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
884 inno_hdmi_irq, IRQF_SHARED,
885 dev_name(dev), hdmi);
887 goto err_cleanup_hdmi;
891 hdmi->connector.funcs->destroy(&hdmi->connector);
892 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
894 i2c_put_adapter(hdmi->ddc);
896 clk_disable_unprepare(hdmi->pclk);
900 static void inno_hdmi_unbind(struct device *dev, struct device *master,
903 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
905 hdmi->connector.funcs->destroy(&hdmi->connector);
906 hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
908 i2c_put_adapter(hdmi->ddc);
909 clk_disable_unprepare(hdmi->pclk);
912 static const struct component_ops inno_hdmi_ops = {
913 .bind = inno_hdmi_bind,
914 .unbind = inno_hdmi_unbind,
917 static int inno_hdmi_probe(struct platform_device *pdev)
919 return component_add(&pdev->dev, &inno_hdmi_ops);
922 static int inno_hdmi_remove(struct platform_device *pdev)
924 component_del(&pdev->dev, &inno_hdmi_ops);
929 static const struct of_device_id inno_hdmi_dt_ids[] = {
930 { .compatible = "rockchip,rk3036-inno-hdmi",
934 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
936 struct platform_driver inno_hdmi_driver = {
937 .probe = inno_hdmi_probe,
938 .remove = inno_hdmi_remove,
940 .name = "innohdmi-rockchip",
941 .of_match_table = inno_hdmi_dt_ids,