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>
17 #include <linux/component.h>
18 #include<linux/reset.h>
20 #include <drm/drm_atomic_helper.h>
21 #include <drm/drm_edid.h>
22 #include <drm/drm_of.h>
23 #include <drm/drm_probe_helper.h>
24 #include <drm/drm_simple_kms_helper.h>
29 #include "inno_hdmi.h"
31 #include "fmux_macro.h"
32 #include "sys_iomux_cfg_macro.h"
34 #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x)
36 struct hdmi_data_info {
40 unsigned int enc_in_format;
41 unsigned int enc_out_format;
42 unsigned int colorimetry;
45 struct inno_hdmi_i2c {
46 struct i2c_adapter adap;
52 struct completion cmp;
57 struct drm_device *drm_dev;
64 struct reset_control *tx_rst;
67 struct drm_connector connector;
68 struct drm_encoder encoder;
70 struct inno_hdmi_i2c *i2c;
71 struct i2c_adapter *ddc;
73 unsigned int tmds_rate;
75 struct hdmi_data_info hdmi_data;
76 struct drm_display_mode previous_mode;
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 void inno_hdmi_srcdata_fmt_config(int panel_sel, int dpi_dp_sel, int dpi_dp_depth)
179 SET_U2_DISPLAY_PANEL_MUX_PANEL_SEL(panel_sel);
180 SET_U0_HDMI_DATA_MAPPING_DPI_DP_SEL(dpi_dp_sel);
181 SET_U0_HDMI_DATA_MAPPING_DPI_BIT_DEPTH(dpi_dp_depth);
184 static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
188 val = readl_relaxed(hdmi->regs + (0x1b0) * 0x04);
190 writel_relaxed(val, hdmi->regs + (0x1b0) * 0x04);
191 writel_relaxed(0xf, hdmi->regs + (0x1cc) * 0x04);
194 val = readl_relaxed(hdmi->regs + (0x1a0) * 0x04);
196 writel_relaxed(val, hdmi->regs + (0x1a0) * 0x04);
198 val = readl_relaxed(hdmi->regs + (0x1aa) * 0x04);
200 writel_relaxed(val, hdmi->regs + (0x1aa) * 0x04);
202 /*wait for pre-PLL and post-PLL lock*/
203 //while(!(hdmi_read(word_align(0x1a9)) & 0x1));
204 //while(!(hdmi_read(word_align(0x1af)) & 0x1));
205 while (!(readl_relaxed(hdmi->regs + (0x1a9) * 0x04) & 0x1))
207 while (!(readl_relaxed(hdmi->regs + (0x1af) * 0x04) & 0x1))
211 writel_relaxed(0x7, hdmi->regs + (0x1b4) * 0x04);
212 /*turn on serializer*/
213 writel_relaxed(0x70, hdmi->regs + (0x1be) * 0x04);
216 static void inno_hdmi_tx_phy_power_down(struct inno_hdmi *hdmi)
218 //hdmi_write(0x63, word_align(0x00));
219 writel_relaxed(0x63, hdmi->regs + (0x00) * 0x04);
222 typedef struct register_value {
228 static void inno_hdmi_config_640x480p60(struct inno_hdmi *hdmi)
230 const reg_value_t cfg_pll_data[] = {
231 /* config pll: 640x480p, 60hz*/
251 for (i = 0; i < sizeof(cfg_pll_data) / sizeof(reg_value_t); i++) {
252 //hdmi_write(cfg_pll_data[i].value, word_align(cfg_pll_data[i].reg));
253 writel_relaxed(cfg_pll_data[i].value, hdmi->regs + (cfg_pll_data[i].reg) * 0x04);
259 static void inno_hdmi_config_1920x1080p60(struct inno_hdmi *hdmi)
262 const reg_value_t cfg_pll_data[] = {
263 /* config pll: 1080p, 60hz*/
280 for (i = 0; i < sizeof(cfg_pll_data) / sizeof(reg_value_t); i++)
281 writel_relaxed(cfg_pll_data[i].value, hdmi->regs + (cfg_pll_data[i].reg) * 0x04);
286 static void inno_hdmi_tx_ctrl(struct inno_hdmi *hdmi)
288 writel_relaxed(0x06, hdmi->regs + (0x9f) * 0x04);
289 writel_relaxed(0x82, hdmi->regs + (0xa0) * 0x04);
290 writel_relaxed(0xd, hdmi->regs + (0xa2) * 0x04);
291 writel_relaxed(0x0, hdmi->regs + (0xa3) * 0x04);
292 writel_relaxed(0x0, hdmi->regs + (0xa4) * 0x04);
293 writel_relaxed(0x8, hdmi->regs + (0xa5) * 0x04);
294 writel_relaxed(0x70, hdmi->regs + (0xa6) * 0x04);
295 writel_relaxed(0x10, hdmi->regs + (0xa7) * 0x04);
296 writel_relaxed(0x10, hdmi->regs + (0xc9) * 0x04);
299 static void inno_hdmi_tx_phy_param_config(struct inno_hdmi *hdmi)
303 //vic = VIC_640x480p60;
304 //inno_hdmi_config_640x480p60(hdmi);
307 inno_hdmi_config_1920x1080p60(hdmi);
309 inno_hdmi_tx_ctrl(hdmi);
314 static void inno_hdmi_tx_phy_power_on(struct inno_hdmi *hdmi)
316 const reg_value_t pwon_data[] = {
318 //{0xce, 0x00},//data sync
322 for (i = 0; i < sizeof(pwon_data)/sizeof(reg_value_t); i++) {
323 //hdmi_write(pwon_data[i].value, word_align(pwon_data[i].reg));
324 writel_relaxed(pwon_data[i].value, hdmi->regs + (pwon_data[i].reg) * 0x04);
329 void inno_hdmi_tmds_driver_on(struct inno_hdmi *hdmi)
331 writel_relaxed(0x8f, hdmi->regs + (0x1b2) * 0x04);
332 printk("HDMI tmds encode driver on\r\n");
336 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
340 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
342 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
343 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
345 /* Clear the EDID interrupt flag and mute the interrupt */
346 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
347 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
350 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
353 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON);
355 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
358 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
362 inno_hdmi_sys_power(hdmi, true);
366 inno_hdmi_sys_power(hdmi, false);
370 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
374 static void inno_hdmi_init(struct inno_hdmi *hdmi)
376 writel_relaxed(0x3, hdmi->regs + (0x100) * 0x04);
377 writel_relaxed(0xc, hdmi->regs + (0x8) * 0x04);
379 inno_hdmi_power_up(hdmi);
380 inno_hdmi_tx_phy_power_down(hdmi);
381 inno_hdmi_tx_phy_param_config(hdmi);
382 //inno_hdmi_wait_pll_clk_locked();
384 inno_hdmi_tx_phy_power_on(hdmi);
385 inno_hdmi_tmds_driver_on(hdmi);
387 writel_relaxed(0x0, hdmi->regs + (0xce) * 0x04);
388 writel_relaxed(0x1, hdmi->regs + (0xce) * 0x04);
392 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
397 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
400 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
403 msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
404 val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
405 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
407 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
410 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
411 union hdmi_infoframe *frame, u32 frame_index,
412 u32 mask, u32 disable, u32 enable)
416 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
418 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
421 u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
424 rc = hdmi_infoframe_pack(frame, packed_frame,
425 sizeof(packed_frame));
429 for (i = 0; i < rc; i++)
430 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
434 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
440 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
441 struct drm_display_mode *mode)
443 union hdmi_infoframe frame;
446 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
450 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI,
451 m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
454 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
455 struct drm_display_mode *mode)
457 union hdmi_infoframe frame;
460 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
464 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
465 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
466 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
467 frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
469 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
471 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
474 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
476 struct hdmi_data_info *data = &hdmi->hdmi_data;
477 int c0_c2_change = 0;
484 /* Input video mode is SDR RGB24bit, data enable signal from external */
485 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL |
486 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444));
488 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
489 value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) |
490 v_VIDEO_OUTPUT_COLOR(0) |
491 v_VIDEO_INPUT_CSP(0);
492 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
494 if (data->enc_in_format == data->enc_out_format) {
495 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
496 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
497 value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
498 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
500 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
501 m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
502 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
503 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
508 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
509 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
510 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
511 csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
512 auto_csc = AUTO_CSC_DISABLE;
513 c0_c2_change = C0_C2_CHANGE_DISABLE;
514 csc_enable = v_CSC_ENABLE;
515 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
516 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
517 csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
518 auto_csc = AUTO_CSC_ENABLE;
519 c0_c2_change = C0_C2_CHANGE_DISABLE;
520 csc_enable = v_CSC_DISABLE;
523 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
524 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
525 csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
526 auto_csc = AUTO_CSC_DISABLE;
527 c0_c2_change = C0_C2_CHANGE_DISABLE;
528 csc_enable = v_CSC_ENABLE;
529 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
530 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
531 csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
532 auto_csc = AUTO_CSC_ENABLE;
533 c0_c2_change = C0_C2_CHANGE_DISABLE;
534 csc_enable = v_CSC_DISABLE;
538 for (i = 0; i < 24; i++)
539 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i,
540 coeff_csc[csc_mode][i]);
542 value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
543 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
544 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC |
545 m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) |
546 v_VIDEO_C0_C2_SWAP(c0_c2_change));
551 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
552 struct drm_display_mode *mode)
556 /* Set detail external video timing polarity and interlace mode */
557 value = v_EXTERANL_VIDEO(1);
558 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
559 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
560 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
561 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
562 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
563 v_INETLACE(1) : v_INETLACE(0);
564 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value);
566 /* Set detail external video timing */
567 value = mode->htotal;
568 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF);
569 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
571 value = mode->htotal - mode->hdisplay;
572 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
573 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
575 value = mode->hsync_start - mode->hdisplay;
576 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
577 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
579 value = mode->hsync_end - mode->hsync_start;
580 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF);
581 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
583 value = mode->vtotal;
584 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF);
585 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
587 value = mode->vtotal - mode->vdisplay;
588 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
590 value = mode->vsync_start - mode->vdisplay;
591 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
593 value = mode->vsync_end - mode->vsync_start;
594 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF);
599 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
600 struct drm_display_mode *mode)
602 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
604 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
605 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
607 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
608 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
609 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
610 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
611 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
613 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
615 /* Mute video and audio output */
616 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
617 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
620 hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
621 v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi));
623 inno_hdmi_config_video_timing(hdmi, mode);
625 inno_hdmi_config_video_csc(hdmi);
627 if (hdmi->hdmi_data.sink_is_hdmi) {
628 inno_hdmi_config_video_avi(hdmi, mode);
629 inno_hdmi_config_video_vsi(hdmi, mode);
633 * When IP controller have configured to an accurate video
634 * timing, then the TMDS clock source would be switched to
635 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
636 * clock rate, and reconfigure the DDC clock.
638 hdmi->tmds_rate = mode->clock * 1000;
639 inno_hdmi_i2c_init(hdmi);
641 /* Unmute video and audio output */
642 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
643 v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
648 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
649 struct drm_display_mode *mode,
650 struct drm_display_mode *adj_mode)
652 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
654 inno_hdmi_setup(hdmi, adj_mode);
656 /* Store the display mode for plugin/DPMS poweron events */
657 memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
660 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
662 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
663 inno_hdmi_init(hdmi);
665 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
668 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
670 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
672 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
675 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
676 const struct drm_display_mode *mode,
677 struct drm_display_mode *adj_mode)
683 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
684 struct drm_crtc_state *crtc_state,
685 struct drm_connector_state *conn_state)
687 //struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
689 //s->output_mode = ROCKCHIP_OUT_MODE_P888;
690 //s->output_type = DRM_MODE_CONNECTOR_HDMIA;
695 static const struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
696 .enable = inno_hdmi_encoder_enable,
697 .disable = inno_hdmi_encoder_disable,
698 .mode_fixup = inno_hdmi_encoder_mode_fixup,
699 .mode_set = inno_hdmi_encoder_mode_set,
700 .atomic_check = inno_hdmi_encoder_atomic_check,
703 static enum drm_connector_status
704 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
706 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
708 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
709 connector_status_connected : connector_status_disconnected;
712 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
714 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
721 edid = drm_get_edid(connector, hdmi->ddc);
723 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
724 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
725 drm_connector_update_edid_property(connector, edid);
726 ret = drm_add_edid_modes(connector, edid);
733 static enum drm_mode_status
734 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
735 struct drm_display_mode *mode)
741 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
742 uint32_t maxX, uint32_t maxY)
744 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
747 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
749 drm_connector_unregister(connector);
750 drm_connector_cleanup(connector);
753 static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
754 .fill_modes = inno_hdmi_probe_single_connector_modes,
755 .detect = inno_hdmi_connector_detect,
756 .destroy = inno_hdmi_connector_destroy,
757 .reset = drm_atomic_helper_connector_reset,
758 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
759 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
762 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
763 .get_modes = inno_hdmi_connector_get_modes,
764 .mode_valid = inno_hdmi_connector_mode_valid,
767 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
769 struct drm_encoder *encoder = &hdmi->encoder;
770 struct device *dev = hdmi->dev;
772 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
775 * If we failed to find the CRTC(s) which this encoder is
776 * supposed to be connected to, it's because the CRTC has
777 * not been registered yet. Defer probing, and hope that
778 * the required CRTC is added later.
780 if (encoder->possible_crtcs == 0)
781 return -EPROBE_DEFER;
783 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
784 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
786 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
788 drm_connector_helper_add(&hdmi->connector,
789 &inno_hdmi_connector_helper_funcs);
790 drm_connector_init_with_ddc(drm, &hdmi->connector,
791 &inno_hdmi_connector_funcs,
792 DRM_MODE_CONNECTOR_HDMIA,
795 drm_connector_attach_encoder(&hdmi->connector, encoder);
800 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
802 struct inno_hdmi_i2c *i2c = hdmi->i2c;
805 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
806 if (!(stat & m_INT_EDID_READY))
809 /* Clear HDMI EDID interrupt flag */
810 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
817 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
819 struct inno_hdmi *hdmi = dev_id;
820 irqreturn_t ret = IRQ_NONE;
824 ret = inno_hdmi_i2c_irq(hdmi);
826 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
827 if (interrupt & m_INT_HOTPLUG) {
828 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
829 ret = IRQ_WAKE_THREAD;
835 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
837 struct inno_hdmi *hdmi = dev_id;
839 drm_helper_hpd_irq_event(hdmi->connector.dev);
844 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
846 int length = msgs->len;
850 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
855 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
860 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
863 * The DDC module only support read EDID message, so
864 * we assume that each word write to this i2c adapter
865 * should be the offset of EDID word address.
867 if ((msgs->len != 1) ||
868 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
871 reinit_completion(&hdmi->i2c->cmp);
873 if (msgs->addr == DDC_SEGMENT_ADDR)
874 hdmi->i2c->segment_addr = msgs->buf[0];
875 if (msgs->addr == DDC_ADDR)
876 hdmi->i2c->ddc_addr = msgs->buf[0];
878 /* Set edid fifo first addr */
879 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
881 /* Set edid word address 0x00/0x80 */
882 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
884 /* Set edid segment pointer */
885 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
890 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
891 struct i2c_msg *msgs, int num)
893 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
894 struct inno_hdmi_i2c *i2c = hdmi->i2c;
897 mutex_lock(&i2c->lock);
899 /* Clear the EDID interrupt flag and unmute the interrupt */
900 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
901 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
903 for (i = 0; i < num; i++) {
904 DRM_DEV_DEBUG(hdmi->dev,
905 "xfer: num: %d/%d, len: %d, flags: %#x\n",
906 i + 1, num, msgs[i].len, msgs[i].flags);
908 if (msgs[i].flags & I2C_M_RD)
909 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
911 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
920 /* Mute HDMI EDID interrupt */
921 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
923 mutex_unlock(&i2c->lock);
928 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
930 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
933 static const struct i2c_algorithm inno_hdmi_algorithm = {
934 .master_xfer = inno_hdmi_i2c_xfer,
935 .functionality = inno_hdmi_i2c_func,
938 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
940 struct i2c_adapter *adap;
941 struct inno_hdmi_i2c *i2c;
944 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
946 return ERR_PTR(-ENOMEM);
948 mutex_init(&i2c->lock);
949 init_completion(&i2c->cmp);
952 adap->class = I2C_CLASS_DDC;
953 adap->owner = THIS_MODULE;
954 adap->dev.parent = hdmi->dev;
955 adap->dev.of_node = hdmi->dev->of_node;
956 adap->algo = &inno_hdmi_algorithm;
957 strlcpy(adap->name, "Inno HDMI", sizeof(adap->name));
958 i2c_set_adapdata(adap, hdmi);
960 ret = i2c_add_adapter(adap);
962 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
963 devm_kfree(hdmi->dev, i2c);
969 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
978 static void inno_hdmi_get_edid(struct inno_hdmi *hdmi, unsigned int tmds_clk, unsigned char *data)
980 unsigned int i, ddc_div_msb, ddc_div_lsb;
981 unsigned int ddc_scl = 100000; //scl:100k
983 //hdmi_write(0xff, 0x0c2);
984 //hdmi_write(0xff, 0x0c4);
986 ddc_div_lsb = (tmds_clk/(4*ddc_scl))>>2;
987 ddc_div_msb = (tmds_clk/(4*ddc_scl)) & 0x00ff;
988 hdmi_writeb(hdmi, 0x04b,ddc_div_lsb);
989 hdmi_writeb(hdmi, 0x04c,ddc_div_msb);
990 /*enable EDID ready interrupt*/
991 hdmi_writeb(hdmi,0x0c0,0x04 );
993 /*read e-edid segment 0x00 256 bytes steps*/
994 /*set EDID FIFO initial address*/
995 hdmi_writeb(hdmi,0x04f, 0x00);
996 /*set EDID first word address, read first 128 byte*/
997 hdmi_writeb(hdmi,0x04e, 0x00);
998 /*set EDID segment 0x00 address*/
999 hdmi_writeb(hdmi, 0x04d,0x00);
1001 while(!(hdmi_readb(hdmi,0x0c1) & 0x4));
1002 hdmi_writeb(hdmi,0x0c1, 0x04); // clear ready interrupt: write 1 to bit2
1004 /*read first 128 bytes*/
1005 for(i = 0; i < 128; i++)
1007 data[i] = hdmi_readb(hdmi,0x050);
1010 /*set EDID FIFO initial address again*/
1011 hdmi_writeb(hdmi,0x04f, 0x00);
1012 /*set EDID first word address, read last 128 byte*/
1013 hdmi_writeb(hdmi,0x04e, 0x80);
1014 /*set EDID segment 0x00 address*/
1015 hdmi_writeb(hdmi,0x04d, 0x00);
1017 while(!(hdmi_readb(hdmi,0x0c1) & 0x4));
1018 hdmi_writeb(hdmi,0x0c1, 0x04); // clear ready interrupt: write 1 to bit2
1020 /*read last 128 bytes*/
1021 for(i = 128; i < 256; i++)
1023 data[i] = hdmi_readb(hdmi,0x050);
1029 static int inno_hdmi_get_clk_rst(struct device *dev, struct inno_hdmi *hdmi)
1032 hdmi->sys_clk = devm_clk_get(dev, "sysclk");
1033 if (IS_ERR(hdmi->sys_clk)) {
1034 DRM_DEV_ERROR(dev, "Unable to get HDMI sysclk clk\n");
1035 return PTR_ERR(hdmi->sys_clk);
1037 hdmi->mclk = devm_clk_get(dev, "mclk");
1038 if (IS_ERR(hdmi->mclk)) {
1039 DRM_DEV_ERROR(dev, "Unable to get HDMI mclk clk\n");
1040 return PTR_ERR(hdmi->mclk);
1042 hdmi->bclk = devm_clk_get(dev, "bclk");
1043 if (IS_ERR(hdmi->bclk)) {
1044 DRM_DEV_ERROR(dev, "Unable to get HDMI bclk clk\n");
1045 return PTR_ERR(hdmi->bclk);
1047 hdmi->tx_rst = reset_control_get_exclusive(dev, "hdmi_tx");
1048 if (IS_ERR(hdmi->tx_rst)) {
1049 DRM_DEV_ERROR(dev, "Unable to get HDMI tx rst\n");
1050 return PTR_ERR(hdmi->tx_rst);
1055 static int inno_hdmi_en_clk_deas_rst(struct device *dev, struct inno_hdmi *hdmi)
1059 ret = clk_prepare_enable(hdmi->sys_clk);
1062 "Cannot enable HDMI sys clock: %d\n", ret);
1065 ret = clk_prepare_enable(hdmi->mclk);
1068 "Cannot enable HDMI mclk clock: %d\n", ret);
1071 ret = clk_prepare_enable(hdmi->bclk);
1074 "Cannot enable HDMI bclk clock: %d\n", ret);
1078 ret = reset_control_deassert(hdmi->tx_rst);
1080 dev_err(dev, "failed to deassert tx_rst\n");
1087 static int inno_hdmi_bind(struct device *dev, struct device *master,
1090 struct platform_device *pdev = to_platform_device(dev);
1091 struct drm_device *drm = data;
1092 struct inno_hdmi *hdmi;
1093 struct resource *iores;
1097 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1102 hdmi->drm_dev = drm;
1104 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1105 hdmi->regs = devm_ioremap_resource(dev, iores);
1106 if (IS_ERR(hdmi->regs))
1107 return PTR_ERR(hdmi->regs);
1113 //20220531 clk rst interface support
1115 ret = inno_hdmi_get_clk_rst(dev, hdmi);
1117 // dev_err(dev, "failed to get clock or reset\n");
1120 ret = inno_hdmi_en_clk_deas_rst(dev, hdmi);
1122 // dev_err(dev, "failed to enable clock or deassert reset\n");
1126 //20220531 clk rst interface support
1129 irq = platform_get_irq(pdev, 0);
1132 goto err_disable_clk;
1134 //inno_hdmi_set_pinmux();//20220601 disable for testing dts pinctrl setting
1135 //inno_hdmi_init(hdmi);
1136 //inno_hdmi_get_edid(hdmi,51200000, data);//20220525
1137 inno_hdmi_reset(hdmi);
1139 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
1140 if (IS_ERR(hdmi->ddc)) {
1141 ret = PTR_ERR(hdmi->ddc);
1143 goto err_disable_clk;
1146 hdmi->tmds_rate = 51200000;
1148 inno_hdmi_i2c_init(hdmi);
1150 ret = inno_hdmi_register(drm, hdmi);
1152 goto err_put_adapter;
1154 dev_set_drvdata(dev, hdmi);
1156 /* Unmute hotplug interrupt */
1157 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
1159 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
1160 inno_hdmi_irq, IRQF_SHARED,
1161 dev_name(dev), hdmi);
1163 goto err_cleanup_hdmi;
1167 hdmi->connector.funcs->destroy(&hdmi->connector);
1168 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1170 i2c_put_adapter(hdmi->ddc);
1172 //clk_disable_unprepare(hdmi->pclk);
1176 static void inno_hdmi_unbind(struct device *dev, struct device *master,
1179 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
1182 hdmi->connector.funcs->destroy(&hdmi->connector);
1183 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1185 i2c_put_adapter(hdmi->ddc);
1187 ret = reset_control_assert(hdmi->tx_rst);
1189 dev_err(dev, "failed to assert tx_rst\n");
1191 clk_disable_unprepare(hdmi->sys_clk);
1192 clk_disable_unprepare(hdmi->mclk);
1193 clk_disable_unprepare(hdmi->bclk);
1201 // clk_disable_unprepare(hdmi->pclk);
1204 static const struct component_ops inno_hdmi_ops = {
1205 .bind = inno_hdmi_bind,
1206 .unbind = inno_hdmi_unbind,
1209 static int inno_hdmi_probe(struct platform_device *pdev)
1211 return component_add(&pdev->dev, &inno_hdmi_ops);
1214 static int inno_hdmi_remove(struct platform_device *pdev)
1216 component_del(&pdev->dev, &inno_hdmi_ops);
1221 static const struct of_device_id inno_hdmi_dt_ids[] = {
1222 { .compatible = "rockchip,rk3036-inno-hdmi",
1226 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
1228 struct platform_driver inno_hdmi_driver = {
1229 .probe = inno_hdmi_probe,
1230 .remove = inno_hdmi_remove,
1232 .name = "innohdmi-rockchip",
1233 .of_match_table = inno_hdmi_dt_ids,