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>
25 #include <soc/starfive/jh7110_pmic.h>//20220520 pmic support
30 #include "inno_hdmi.h"
32 #include "fmux_macro.h"
33 #include "sys_iomux_cfg_macro.h"
35 #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x)
37 struct hdmi_data_info {
41 unsigned int enc_in_format;
42 unsigned int enc_out_format;
43 unsigned int colorimetry;
46 struct inno_hdmi_i2c {
47 struct i2c_adapter adap;
53 struct completion cmp;
58 struct drm_device *drm_dev;
65 struct reset_control *tx_rst;
68 struct drm_connector connector;
69 struct drm_encoder encoder;
71 struct inno_hdmi_i2c *i2c;
72 struct i2c_adapter *ddc;
74 unsigned int tmds_rate;
76 struct hdmi_data_info hdmi_data;
77 struct drm_display_mode previous_mode;
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 void inno_hdmi_srcdata_fmt_config(int panel_sel, int dpi_dp_sel, int dpi_dp_depth)
180 SET_U2_DISPLAY_PANEL_MUX_PANEL_SEL(panel_sel);
181 SET_U0_HDMI_DATA_MAPPING_DPI_DP_SEL(dpi_dp_sel);
182 SET_U0_HDMI_DATA_MAPPING_DPI_BIT_DEPTH(dpi_dp_depth);
185 static void inno_hdmi_power_up(struct inno_hdmi *hdmi)
189 val = readl_relaxed(hdmi->regs + (0x1b0) * 0x04);
191 writel_relaxed(val, hdmi->regs + (0x1b0) * 0x04);
192 writel_relaxed(0xf, hdmi->regs + (0x1cc) * 0x04);
195 val = readl_relaxed(hdmi->regs + (0x1a0) * 0x04);
197 writel_relaxed(val, hdmi->regs + (0x1a0) * 0x04);
199 val = readl_relaxed(hdmi->regs + (0x1aa) * 0x04);
201 writel_relaxed(val, hdmi->regs + (0x1aa) * 0x04);
203 /*wait for pre-PLL and post-PLL lock*/
204 //while(!(hdmi_read(word_align(0x1a9)) & 0x1));
205 //while(!(hdmi_read(word_align(0x1af)) & 0x1));
206 while (!(readl_relaxed(hdmi->regs + (0x1a9) * 0x04) & 0x1))
208 while (!(readl_relaxed(hdmi->regs + (0x1af) * 0x04) & 0x1))
212 writel_relaxed(0x7, hdmi->regs + (0x1b4) * 0x04);
213 /*turn on serializer*/
214 writel_relaxed(0x70, hdmi->regs + (0x1be) * 0x04);
217 static void inno_hdmi_tx_phy_power_down(struct inno_hdmi *hdmi)
219 //hdmi_write(0x63, word_align(0x00));
220 writel_relaxed(0x63, hdmi->regs + (0x00) * 0x04);
223 typedef struct register_value {
229 static void inno_hdmi_config_640x480p60(struct inno_hdmi *hdmi)
231 const reg_value_t cfg_pll_data[] = {
232 /* config pll: 640x480p, 60hz*/
252 for (i = 0; i < sizeof(cfg_pll_data) / sizeof(reg_value_t); i++) {
253 //hdmi_write(cfg_pll_data[i].value, word_align(cfg_pll_data[i].reg));
254 writel_relaxed(cfg_pll_data[i].value, hdmi->regs + (cfg_pll_data[i].reg) * 0x04);
260 static void inno_hdmi_config_1920x1080p60(struct inno_hdmi *hdmi)
263 const reg_value_t cfg_pll_data[] = {
264 /* config pll: 1080p, 60hz*/
281 for (i = 0; i < sizeof(cfg_pll_data) / sizeof(reg_value_t); i++)
282 writel_relaxed(cfg_pll_data[i].value, hdmi->regs + (cfg_pll_data[i].reg) * 0x04);
287 static void inno_hdmi_tx_ctrl(struct inno_hdmi *hdmi)
289 writel_relaxed(0x06, hdmi->regs + (0x9f) * 0x04);
290 writel_relaxed(0x82, hdmi->regs + (0xa0) * 0x04);
291 writel_relaxed(0xd, hdmi->regs + (0xa2) * 0x04);
292 writel_relaxed(0x0, hdmi->regs + (0xa3) * 0x04);
293 writel_relaxed(0x0, hdmi->regs + (0xa4) * 0x04);
294 writel_relaxed(0x8, hdmi->regs + (0xa5) * 0x04);
295 writel_relaxed(0x70, hdmi->regs + (0xa6) * 0x04);
296 writel_relaxed(0x10, hdmi->regs + (0xa7) * 0x04);
297 writel_relaxed(0x10, hdmi->regs + (0xc9) * 0x04);
300 static void inno_hdmi_tx_phy_param_config(struct inno_hdmi *hdmi)
304 //vic = VIC_640x480p60;
305 //inno_hdmi_config_640x480p60(hdmi);
308 inno_hdmi_config_1920x1080p60(hdmi);
310 inno_hdmi_tx_ctrl(hdmi);
315 static void inno_hdmi_tx_phy_power_on(struct inno_hdmi *hdmi)
317 const reg_value_t pwon_data[] = {
319 //{0xce, 0x00},//data sync
323 for (i = 0; i < sizeof(pwon_data)/sizeof(reg_value_t); i++) {
324 //hdmi_write(pwon_data[i].value, word_align(pwon_data[i].reg));
325 writel_relaxed(pwon_data[i].value, hdmi->regs + (pwon_data[i].reg) * 0x04);
330 void inno_hdmi_tmds_driver_on(struct inno_hdmi *hdmi)
332 writel_relaxed(0x8f, hdmi->regs + (0x1b2) * 0x04);
333 printk("HDMI tmds encode driver on\r\n");
337 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
341 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
343 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
344 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
346 /* Clear the EDID interrupt flag and mute the interrupt */
347 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
348 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
351 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
354 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON);
356 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
359 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
363 inno_hdmi_sys_power(hdmi, true);
367 inno_hdmi_sys_power(hdmi, false);
371 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
375 static void inno_hdmi_init(struct inno_hdmi *hdmi)
377 writel_relaxed(0x3, hdmi->regs + (0x100) * 0x04);
378 writel_relaxed(0xc, hdmi->regs + (0x8) * 0x04);
380 inno_hdmi_power_up(hdmi);
381 inno_hdmi_tx_phy_power_down(hdmi);
382 inno_hdmi_tx_phy_param_config(hdmi);
383 //inno_hdmi_wait_pll_clk_locked();
385 inno_hdmi_tx_phy_power_on(hdmi);
386 inno_hdmi_tmds_driver_on(hdmi);
388 writel_relaxed(0x0, hdmi->regs + (0xce) * 0x04);
389 writel_relaxed(0x1, hdmi->regs + (0xce) * 0x04);
393 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
398 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
401 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
404 msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
405 val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
406 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
408 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
411 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
412 union hdmi_infoframe *frame, u32 frame_index,
413 u32 mask, u32 disable, u32 enable)
417 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
419 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
422 u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
425 rc = hdmi_infoframe_pack(frame, packed_frame,
426 sizeof(packed_frame));
430 for (i = 0; i < rc; i++)
431 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
435 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
441 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
442 struct drm_display_mode *mode)
444 union hdmi_infoframe frame;
447 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
451 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI,
452 m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
455 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
456 struct drm_display_mode *mode)
458 union hdmi_infoframe frame;
461 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
465 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
466 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
467 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
468 frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
470 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
472 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
475 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
477 struct hdmi_data_info *data = &hdmi->hdmi_data;
478 int c0_c2_change = 0;
485 /* Input video mode is SDR RGB24bit, data enable signal from external */
486 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL |
487 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444));
489 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
490 value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) |
491 v_VIDEO_OUTPUT_COLOR(0) |
492 v_VIDEO_INPUT_CSP(0);
493 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
495 if (data->enc_in_format == data->enc_out_format) {
496 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
497 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
498 value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
499 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
501 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
502 m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
503 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
504 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
509 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
510 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
511 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
512 csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
513 auto_csc = AUTO_CSC_DISABLE;
514 c0_c2_change = C0_C2_CHANGE_DISABLE;
515 csc_enable = v_CSC_ENABLE;
516 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
517 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
518 csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
519 auto_csc = AUTO_CSC_ENABLE;
520 c0_c2_change = C0_C2_CHANGE_DISABLE;
521 csc_enable = v_CSC_DISABLE;
524 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
525 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
526 csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
527 auto_csc = AUTO_CSC_DISABLE;
528 c0_c2_change = C0_C2_CHANGE_DISABLE;
529 csc_enable = v_CSC_ENABLE;
530 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
531 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
532 csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
533 auto_csc = AUTO_CSC_ENABLE;
534 c0_c2_change = C0_C2_CHANGE_DISABLE;
535 csc_enable = v_CSC_DISABLE;
539 for (i = 0; i < 24; i++)
540 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i,
541 coeff_csc[csc_mode][i]);
543 value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
544 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
545 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC |
546 m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) |
547 v_VIDEO_C0_C2_SWAP(c0_c2_change));
552 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
553 struct drm_display_mode *mode)
557 /* Set detail external video timing polarity and interlace mode */
558 value = v_EXTERANL_VIDEO(1);
559 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
560 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
561 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
562 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
563 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
564 v_INETLACE(1) : v_INETLACE(0);
565 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value);
567 /* Set detail external video timing */
568 value = mode->htotal;
569 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF);
570 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
572 value = mode->htotal - mode->hdisplay;
573 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
574 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
576 value = mode->hsync_start - mode->hdisplay;
577 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
578 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
580 value = mode->hsync_end - mode->hsync_start;
581 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF);
582 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
584 value = mode->vtotal;
585 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF);
586 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
588 value = mode->vtotal - mode->vdisplay;
589 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
591 value = mode->vsync_start - mode->vdisplay;
592 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
594 value = mode->vsync_end - mode->vsync_start;
595 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF);
600 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
601 struct drm_display_mode *mode)
603 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
605 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
606 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
608 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
609 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
610 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
611 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
612 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
614 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
616 /* Mute video and audio output */
617 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
618 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
621 hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
622 v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi));
624 inno_hdmi_config_video_timing(hdmi, mode);
626 inno_hdmi_config_video_csc(hdmi);
628 if (hdmi->hdmi_data.sink_is_hdmi) {
629 inno_hdmi_config_video_avi(hdmi, mode);
630 inno_hdmi_config_video_vsi(hdmi, mode);
634 * When IP controller have configured to an accurate video
635 * timing, then the TMDS clock source would be switched to
636 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
637 * clock rate, and reconfigure the DDC clock.
639 hdmi->tmds_rate = mode->clock * 1000;
640 inno_hdmi_i2c_init(hdmi);
642 /* Unmute video and audio output */
643 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
644 v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
649 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
650 struct drm_display_mode *mode,
651 struct drm_display_mode *adj_mode)
653 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
655 inno_hdmi_setup(hdmi, adj_mode);
657 /* Store the display mode for plugin/DPMS poweron events */
658 memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
661 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
663 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
664 inno_hdmi_init(hdmi);
666 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
669 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
671 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
673 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
676 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
677 const struct drm_display_mode *mode,
678 struct drm_display_mode *adj_mode)
684 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
685 struct drm_crtc_state *crtc_state,
686 struct drm_connector_state *conn_state)
688 //struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
690 //s->output_mode = ROCKCHIP_OUT_MODE_P888;
691 //s->output_type = DRM_MODE_CONNECTOR_HDMIA;
696 static const struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
697 .enable = inno_hdmi_encoder_enable,
698 .disable = inno_hdmi_encoder_disable,
699 .mode_fixup = inno_hdmi_encoder_mode_fixup,
700 .mode_set = inno_hdmi_encoder_mode_set,
701 .atomic_check = inno_hdmi_encoder_atomic_check,
704 static enum drm_connector_status
705 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
707 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
709 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
710 connector_status_connected : connector_status_disconnected;
713 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
715 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
722 edid = drm_get_edid(connector, hdmi->ddc);
724 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
725 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
726 drm_connector_update_edid_property(connector, edid);
727 ret = drm_add_edid_modes(connector, edid);
734 static enum drm_mode_status
735 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
736 struct drm_display_mode *mode)
742 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
743 uint32_t maxX, uint32_t maxY)
745 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
748 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
750 drm_connector_unregister(connector);
751 drm_connector_cleanup(connector);
754 static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
755 .fill_modes = inno_hdmi_probe_single_connector_modes,
756 .detect = inno_hdmi_connector_detect,
757 .destroy = inno_hdmi_connector_destroy,
758 .reset = drm_atomic_helper_connector_reset,
759 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
760 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
763 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
764 .get_modes = inno_hdmi_connector_get_modes,
765 .mode_valid = inno_hdmi_connector_mode_valid,
768 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
770 struct drm_encoder *encoder = &hdmi->encoder;
771 struct device *dev = hdmi->dev;
773 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
776 * If we failed to find the CRTC(s) which this encoder is
777 * supposed to be connected to, it's because the CRTC has
778 * not been registered yet. Defer probing, and hope that
779 * the required CRTC is added later.
781 if (encoder->possible_crtcs == 0)
782 return -EPROBE_DEFER;
784 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
785 drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
787 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
789 drm_connector_helper_add(&hdmi->connector,
790 &inno_hdmi_connector_helper_funcs);
791 drm_connector_init_with_ddc(drm, &hdmi->connector,
792 &inno_hdmi_connector_funcs,
793 DRM_MODE_CONNECTOR_HDMIA,
796 drm_connector_attach_encoder(&hdmi->connector, encoder);
801 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
803 struct inno_hdmi_i2c *i2c = hdmi->i2c;
806 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
807 if (!(stat & m_INT_EDID_READY))
810 /* Clear HDMI EDID interrupt flag */
811 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
818 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
820 struct inno_hdmi *hdmi = dev_id;
821 irqreturn_t ret = IRQ_NONE;
825 ret = inno_hdmi_i2c_irq(hdmi);
827 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
828 if (interrupt & m_INT_HOTPLUG) {
829 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
830 ret = IRQ_WAKE_THREAD;
836 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
838 struct inno_hdmi *hdmi = dev_id;
840 drm_helper_hpd_irq_event(hdmi->connector.dev);
845 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
847 int length = msgs->len;
851 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
856 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
861 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
864 * The DDC module only support read EDID message, so
865 * we assume that each word write to this i2c adapter
866 * should be the offset of EDID word address.
868 if ((msgs->len != 1) ||
869 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
872 reinit_completion(&hdmi->i2c->cmp);
874 if (msgs->addr == DDC_SEGMENT_ADDR)
875 hdmi->i2c->segment_addr = msgs->buf[0];
876 if (msgs->addr == DDC_ADDR)
877 hdmi->i2c->ddc_addr = msgs->buf[0];
879 /* Set edid fifo first addr */
880 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
882 /* Set edid word address 0x00/0x80 */
883 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
885 /* Set edid segment pointer */
886 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
891 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
892 struct i2c_msg *msgs, int num)
894 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
895 struct inno_hdmi_i2c *i2c = hdmi->i2c;
898 mutex_lock(&i2c->lock);
900 /* Clear the EDID interrupt flag and unmute the interrupt */
901 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
902 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
904 for (i = 0; i < num; i++) {
905 DRM_DEV_DEBUG(hdmi->dev,
906 "xfer: num: %d/%d, len: %d, flags: %#x\n",
907 i + 1, num, msgs[i].len, msgs[i].flags);
909 if (msgs[i].flags & I2C_M_RD)
910 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
912 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
921 /* Mute HDMI EDID interrupt */
922 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
924 mutex_unlock(&i2c->lock);
929 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
931 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
934 static const struct i2c_algorithm inno_hdmi_algorithm = {
935 .master_xfer = inno_hdmi_i2c_xfer,
936 .functionality = inno_hdmi_i2c_func,
939 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
941 struct i2c_adapter *adap;
942 struct inno_hdmi_i2c *i2c;
945 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
947 return ERR_PTR(-ENOMEM);
949 mutex_init(&i2c->lock);
950 init_completion(&i2c->cmp);
953 adap->class = I2C_CLASS_DDC;
954 adap->owner = THIS_MODULE;
955 adap->dev.parent = hdmi->dev;
956 adap->dev.of_node = hdmi->dev->of_node;
957 adap->algo = &inno_hdmi_algorithm;
958 strlcpy(adap->name, "Inno HDMI", sizeof(adap->name));
959 i2c_set_adapdata(adap, hdmi);
961 ret = i2c_add_adapter(adap);
963 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
964 devm_kfree(hdmi->dev, i2c);
970 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
979 static void inno_hdmi_get_edid(struct inno_hdmi *hdmi, unsigned int tmds_clk, unsigned char *data)
981 unsigned int i, ddc_div_msb, ddc_div_lsb;
982 unsigned int ddc_scl = 100000; //scl:100k
984 //hdmi_write(0xff, 0x0c2);
985 //hdmi_write(0xff, 0x0c4);
987 ddc_div_lsb = (tmds_clk/(4*ddc_scl))>>2;
988 ddc_div_msb = (tmds_clk/(4*ddc_scl)) & 0x00ff;
989 hdmi_writeb(hdmi, 0x04b,ddc_div_lsb);
990 hdmi_writeb(hdmi, 0x04c,ddc_div_msb);
991 /*enable EDID ready interrupt*/
992 hdmi_writeb(hdmi,0x0c0,0x04 );
994 /*read e-edid segment 0x00 256 bytes steps*/
995 /*set EDID FIFO initial address*/
996 hdmi_writeb(hdmi,0x04f, 0x00);
997 /*set EDID first word address, read first 128 byte*/
998 hdmi_writeb(hdmi,0x04e, 0x00);
999 /*set EDID segment 0x00 address*/
1000 hdmi_writeb(hdmi, 0x04d,0x00);
1002 while(!(hdmi_readb(hdmi,0x0c1) & 0x4));
1003 hdmi_writeb(hdmi,0x0c1, 0x04); // clear ready interrupt: write 1 to bit2
1005 /*read first 128 bytes*/
1006 for(i = 0; i < 128; i++)
1008 data[i] = hdmi_readb(hdmi,0x050);
1011 /*set EDID FIFO initial address again*/
1012 hdmi_writeb(hdmi,0x04f, 0x00);
1013 /*set EDID first word address, read last 128 byte*/
1014 hdmi_writeb(hdmi,0x04e, 0x80);
1015 /*set EDID segment 0x00 address*/
1016 hdmi_writeb(hdmi,0x04d, 0x00);
1018 while(!(hdmi_readb(hdmi,0x0c1) & 0x4));
1019 hdmi_writeb(hdmi,0x0c1, 0x04); // clear ready interrupt: write 1 to bit2
1021 /*read last 128 bytes*/
1022 for(i = 128; i < 256; i++)
1024 data[i] = hdmi_readb(hdmi,0x050);
1030 static int inno_hdmi_get_clk_rst(struct device *dev, struct inno_hdmi *hdmi)
1033 hdmi->sys_clk = devm_clk_get(dev, "sysclk");
1034 if (IS_ERR(hdmi->sys_clk)) {
1035 DRM_DEV_ERROR(dev, "Unable to get HDMI sysclk clk\n");
1036 return PTR_ERR(hdmi->sys_clk);
1038 hdmi->mclk = devm_clk_get(dev, "mclk");
1039 if (IS_ERR(hdmi->mclk)) {
1040 DRM_DEV_ERROR(dev, "Unable to get HDMI mclk clk\n");
1041 return PTR_ERR(hdmi->mclk);
1043 hdmi->bclk = devm_clk_get(dev, "bclk");
1044 if (IS_ERR(hdmi->bclk)) {
1045 DRM_DEV_ERROR(dev, "Unable to get HDMI bclk clk\n");
1046 return PTR_ERR(hdmi->bclk);
1048 hdmi->tx_rst = reset_control_get_exclusive(dev, "hdmi_tx");
1049 if (IS_ERR(hdmi->tx_rst)) {
1050 DRM_DEV_ERROR(dev, "Unable to get HDMI tx rst\n");
1051 return PTR_ERR(hdmi->tx_rst);
1056 static int inno_hdmi_en_clk_deas_rst(struct device *dev, struct inno_hdmi *hdmi)
1060 ret = clk_prepare_enable(hdmi->sys_clk);
1063 "Cannot enable HDMI sys clock: %d\n", ret);
1066 ret = clk_prepare_enable(hdmi->mclk);
1069 "Cannot enable HDMI mclk clock: %d\n", ret);
1072 ret = clk_prepare_enable(hdmi->bclk);
1075 "Cannot enable HDMI bclk clock: %d\n", ret);
1079 ret = reset_control_deassert(hdmi->tx_rst);
1081 dev_err(dev, "failed to deassert tx_rst\n");
1088 static int inno_hdmi_bind(struct device *dev, struct device *master,
1091 struct platform_device *pdev = to_platform_device(dev);
1092 struct drm_device *drm = data;
1093 struct inno_hdmi *hdmi;
1094 struct resource *iores;
1098 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1103 hdmi->drm_dev = drm;
1105 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1106 hdmi->regs = devm_ioremap_resource(dev, iores);
1107 if (IS_ERR(hdmi->regs))
1108 return PTR_ERR(hdmi->regs);
1111 pmic_set_domain(POWER_SW_0_REG, POWER_SW_0_VDD18_HDMI, 1);
1113 pmic_set_domain(POWER_SW_0_REG, POWER_SW_0_VDD09_HDMI, 1);
1116 //20220531 clk rst interface support
1118 ret = inno_hdmi_get_clk_rst(dev, hdmi);
1120 // dev_err(dev, "failed to get clock or reset\n");
1123 ret = inno_hdmi_en_clk_deas_rst(dev, hdmi);
1125 // dev_err(dev, "failed to enable clock or deassert reset\n");
1129 //20220531 clk rst interface support
1132 irq = platform_get_irq(pdev, 0);
1135 goto err_disable_clk;
1137 //inno_hdmi_set_pinmux();//20220601 disable for testing dts pinctrl setting
1138 //inno_hdmi_init(hdmi);
1139 //inno_hdmi_get_edid(hdmi,51200000, data);//20220525
1140 inno_hdmi_reset(hdmi);
1142 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
1143 if (IS_ERR(hdmi->ddc)) {
1144 ret = PTR_ERR(hdmi->ddc);
1146 goto err_disable_clk;
1149 hdmi->tmds_rate = 51200000;
1151 inno_hdmi_i2c_init(hdmi);
1153 ret = inno_hdmi_register(drm, hdmi);
1155 goto err_put_adapter;
1157 dev_set_drvdata(dev, hdmi);
1159 /* Unmute hotplug interrupt */
1160 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
1162 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
1163 inno_hdmi_irq, IRQF_SHARED,
1164 dev_name(dev), hdmi);
1166 goto err_cleanup_hdmi;
1170 hdmi->connector.funcs->destroy(&hdmi->connector);
1171 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1173 i2c_put_adapter(hdmi->ddc);
1175 //clk_disable_unprepare(hdmi->pclk);
1179 static void inno_hdmi_unbind(struct device *dev, struct device *master,
1182 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
1185 hdmi->connector.funcs->destroy(&hdmi->connector);
1186 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1188 i2c_put_adapter(hdmi->ddc);
1190 ret = reset_control_assert(hdmi->tx_rst);
1192 dev_err(dev, "failed to assert tx_rst\n");
1194 clk_disable_unprepare(hdmi->sys_clk);
1195 clk_disable_unprepare(hdmi->mclk);
1196 clk_disable_unprepare(hdmi->bclk);
1200 pmic_set_domain(POWER_SW_0_REG, POWER_SW_0_VDD18_HDMI, 0);
1202 pmic_set_domain(POWER_SW_0_REG, POWER_SW_0_VDD09_HDMI, 0);
1206 // clk_disable_unprepare(hdmi->pclk);
1209 static const struct component_ops inno_hdmi_ops = {
1210 .bind = inno_hdmi_bind,
1211 .unbind = inno_hdmi_unbind,
1214 static int inno_hdmi_probe(struct platform_device *pdev)
1216 return component_add(&pdev->dev, &inno_hdmi_ops);
1219 static int inno_hdmi_remove(struct platform_device *pdev)
1221 component_del(&pdev->dev, &inno_hdmi_ops);
1226 static const struct of_device_id inno_hdmi_dt_ids[] = {
1227 { .compatible = "rockchip,rk3036-inno-hdmi",
1231 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
1233 struct platform_driver inno_hdmi_driver = {
1234 .probe = inno_hdmi_probe,
1235 .remove = inno_hdmi_remove,
1237 .name = "innohdmi-rockchip",
1238 .of_match_table = inno_hdmi_dt_ids,