2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Zheng Yang <zhengyang@rock-chips.com>
4 * Yakir Yang <ykk@rock-chips.com>
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/irq.h>
17 #include <linux/clk.h>
18 #include <linux/delay.h>
19 #include <linux/err.h>
20 #include <linux/hdmi.h>
21 #include <linux/mfd/syscon.h>
22 #include <linux/module.h>
23 #include <linux/mutex.h>
24 #include <linux/of_device.h>
26 #include <drm/drm_of.h>
28 #include <drm/drm_atomic_helper.h>
29 #include <drm/drm_crtc_helper.h>
30 #include <drm/drm_edid.h>
32 #include <sound/hdmi-codec.h>
34 #include "rockchip_drm_drv.h"
35 #include "rockchip_drm_vop.h"
37 #include "inno_hdmi.h"
39 #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x)
47 struct hdmi_data_info {
51 unsigned int enc_in_format;
52 unsigned int enc_out_format;
53 unsigned int colorimetry;
56 struct inno_hdmi_i2c {
57 struct i2c_adapter adap;
63 struct completion cmp;
68 struct drm_device *drm_dev;
74 struct drm_connector connector;
75 struct drm_encoder encoder;
77 struct inno_hdmi_i2c *i2c;
78 struct i2c_adapter *ddc;
80 unsigned int tmds_rate;
82 struct platform_device *audio_pdev;
85 struct hdmi_data_info hdmi_data;
86 struct drm_display_mode previous_mode;
90 CSC_ITU601_16_235_TO_RGB_0_255_8BIT,
91 CSC_ITU601_0_255_TO_RGB_0_255_8BIT,
92 CSC_ITU709_16_235_TO_RGB_0_255_8BIT,
93 CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
94 CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
95 CSC_RGB_0_255_TO_RGB_16_235_8BIT,
98 static const char coeff_csc[][24] = {
100 * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
101 * R = 1.164*Y + 1.596*V - 204
102 * G = 1.164*Y - 0.391*U - 0.813*V + 154
103 * B = 1.164*Y + 2.018*U - 258
106 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
107 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
108 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
111 * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
112 * R = Y + 1.402*V - 248
113 * G = Y - 0.344*U - 0.714*V + 135
114 * B = Y + 1.772*U - 227
117 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
118 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
119 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
122 * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
123 * R = 1.164*Y + 1.793*V - 248
124 * G = 1.164*Y - 0.213*U - 0.534*V + 77
125 * B = 1.164*Y + 2.115*U - 289
128 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
129 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
130 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
134 * RGB2YUV:601 SD mode:
135 * Cb = -0.291G - 0.148R + 0.439B + 128
136 * Y = 0.504G + 0.257R + 0.098B + 16
137 * Cr = -0.368G + 0.439R - 0.071B + 128
140 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
141 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
142 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
145 * RGB2YUV:709 HD mode:
146 * Cb = - 0.338G - 0.101R + 0.439B + 128
147 * Y = 0.614G + 0.183R + 0.062B + 16
148 * Cr = - 0.399G + 0.439R - 0.040B + 128
151 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
152 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
153 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
156 * RGB[0:255]2RGB[16:235]:
157 * R' = R x (235-16)/255 + 16;
158 * G' = G x (235-16)/255 + 16;
159 * B' = B x (235-16)/255 + 16;
162 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
163 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
164 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10
168 static inline u8 hdmi_readb(struct inno_hdmi *hdmi, u16 offset)
170 return readl_relaxed(hdmi->regs + (offset) * 0x04);
173 static inline void hdmi_writeb(struct inno_hdmi *hdmi, u16 offset, u32 val)
175 writel_relaxed(val, hdmi->regs + (offset) * 0x04);
178 static inline void hdmi_modb(struct inno_hdmi *hdmi, u16 offset,
181 u8 temp = hdmi_readb(hdmi, offset) & ~msk;
184 hdmi_writeb(hdmi, offset, temp);
187 static void inno_hdmi_i2c_init(struct inno_hdmi *hdmi)
191 ddc_bus_freq = (hdmi->tmds_rate >> 2) / HDMI_SCL_RATE;
193 hdmi_writeb(hdmi, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
194 hdmi_writeb(hdmi, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
196 /* Clear the EDID interrupt flag and mute the interrupt */
197 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
198 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
201 static void inno_hdmi_sys_power(struct inno_hdmi *hdmi, bool enable)
204 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_ON);
206 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_POWER, v_PWR_OFF);
209 static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
213 inno_hdmi_sys_power(hdmi, false);
215 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x6f);
216 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0xbb);
218 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
219 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14);
220 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10);
221 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f);
222 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00);
223 hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01);
225 inno_hdmi_sys_power(hdmi, true);
229 inno_hdmi_sys_power(hdmi, false);
230 hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00);
231 hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00);
232 hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00);
233 hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15);
238 dev_err(hdmi->dev, "Unknown power mode %d\n", mode);
242 static void inno_hdmi_reset(struct inno_hdmi *hdmi)
247 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
250 hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
253 msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
254 val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
255 hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
257 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
260 static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, int setup_rc,
261 union hdmi_infoframe *frame, u32 frame_index,
262 u32 mask, u32 disable, u32 enable)
265 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
267 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, frame_index);
270 u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
273 rc = hdmi_infoframe_pack(frame, packed_frame,
274 sizeof(packed_frame));
278 for (i = 0; i < rc; i++)
279 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
283 hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, enable);
289 static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
290 struct drm_display_mode *mode)
292 union hdmi_infoframe frame;
295 rc = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
298 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_VSI,
299 m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
302 static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
303 struct drm_display_mode *mode)
305 union hdmi_infoframe frame;
308 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
310 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
311 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
312 else if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV422)
313 frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
315 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
317 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0);
320 static int inno_hdmi_config_audio_aai(struct inno_hdmi *hdmi,
321 struct audio_info *audio)
323 struct hdmi_audio_infoframe *faudio;
324 union hdmi_infoframe frame;
327 rc = hdmi_audio_infoframe_init(&frame.audio);
328 faudio = (struct hdmi_audio_infoframe *)&frame;
330 faudio->channels = audio->channels;
332 switch (audio->sample_width) {
334 faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_16;
337 faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_20;
340 faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
344 switch (audio->sample_rate) {
346 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_32000;
349 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_44100;
352 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
355 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_88200;
358 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_96000;
361 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_176400;
364 faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_192000;
368 return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AAI, 0, 0, 0);
371 static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
373 struct hdmi_data_info *data = &hdmi->hdmi_data;
374 int c0_c2_change = 0;
381 /* Input video mode is SDR RGB24bit, data enable signal from external */
382 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL |
383 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444));
385 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
386 value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) |
387 v_VIDEO_OUTPUT_COLOR(0) |
388 v_VIDEO_INPUT_CSP(0);
389 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
391 if (data->enc_in_format == data->enc_out_format) {
392 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) ||
393 (data->enc_in_format >= HDMI_COLORSPACE_YUV444)) {
394 value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
395 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
397 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
398 m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
399 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
400 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
405 if (data->colorimetry == HDMI_COLORIMETRY_ITU_601) {
406 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
407 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
408 csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
409 auto_csc = AUTO_CSC_DISABLE;
410 c0_c2_change = C0_C2_CHANGE_DISABLE;
411 csc_enable = v_CSC_ENABLE;
412 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
413 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
414 csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
415 auto_csc = AUTO_CSC_ENABLE;
416 c0_c2_change = C0_C2_CHANGE_DISABLE;
417 csc_enable = v_CSC_DISABLE;
420 if ((data->enc_in_format == HDMI_COLORSPACE_RGB) &&
421 (data->enc_out_format == HDMI_COLORSPACE_YUV444)) {
422 csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
423 auto_csc = AUTO_CSC_DISABLE;
424 c0_c2_change = C0_C2_CHANGE_DISABLE;
425 csc_enable = v_CSC_ENABLE;
426 } else if ((data->enc_in_format == HDMI_COLORSPACE_YUV444) &&
427 (data->enc_out_format == HDMI_COLORSPACE_RGB)) {
428 csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
429 auto_csc = AUTO_CSC_ENABLE;
430 c0_c2_change = C0_C2_CHANGE_DISABLE;
431 csc_enable = v_CSC_DISABLE;
435 for (i = 0; i < 24; i++)
436 hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i,
437 coeff_csc[csc_mode][i]);
439 value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
440 hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
441 hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC |
442 m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) |
443 v_VIDEO_C0_C2_SWAP(c0_c2_change));
448 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
449 struct drm_display_mode *mode)
453 /* Set detail external video timing polarity and interlace mode */
454 value = v_EXTERANL_VIDEO(1);
455 value |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
456 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
457 value |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
458 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
459 value |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
460 v_INETLACE(1) : v_INETLACE(0);
461 hdmi_writeb(hdmi, HDMI_VIDEO_TIMING_CTL, value);
463 /* Set detail external video timing */
464 value = mode->htotal;
465 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_L, value & 0xFF);
466 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
468 value = mode->htotal - mode->hdisplay;
469 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
470 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
472 value = mode->hsync_start - mode->hdisplay;
473 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
474 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
476 value = mode->hsync_end - mode->hsync_start;
477 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_L, value & 0xFF);
478 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
480 value = mode->vtotal;
481 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_L, value & 0xFF);
482 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
484 value = mode->vtotal - mode->vdisplay;
485 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
487 value = mode->vsync_start - mode->vdisplay;
488 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
490 value = mode->vsync_end - mode->vsync_start;
491 hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDURATION, value & 0xFF);
493 hdmi_writeb(hdmi, HDMI_PHY_PRE_DIV_RATIO, 0x1e);
494 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c);
495 hdmi_writeb(hdmi, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01);
500 static int inno_hdmi_setup(struct inno_hdmi *hdmi,
501 struct drm_display_mode *mode)
503 hdmi->hdmi_data.vic = drm_match_cea_mode(mode);
505 hdmi->hdmi_data.enc_in_format = HDMI_COLORSPACE_RGB;
506 hdmi->hdmi_data.enc_out_format = HDMI_COLORSPACE_RGB;
508 if ((hdmi->hdmi_data.vic == 6) || (hdmi->hdmi_data.vic == 7) ||
509 (hdmi->hdmi_data.vic == 21) || (hdmi->hdmi_data.vic == 22) ||
510 (hdmi->hdmi_data.vic == 2) || (hdmi->hdmi_data.vic == 3) ||
511 (hdmi->hdmi_data.vic == 17) || (hdmi->hdmi_data.vic == 18))
512 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
514 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
516 /* Mute video and audio output */
517 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
518 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
521 hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
522 v_HDMI_DVI(hdmi->hdmi_data.sink_is_hdmi));
524 inno_hdmi_config_video_timing(hdmi, mode);
526 inno_hdmi_config_video_csc(hdmi);
528 if (hdmi->hdmi_data.sink_is_hdmi) {
529 inno_hdmi_config_video_avi(hdmi, mode);
530 inno_hdmi_config_video_vsi(hdmi, mode);
534 * When IP controller have configured to an accurate video
535 * timing, then the TMDS clock source would be switched to
536 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
537 * clock rate, and reconfigure the DDC clock.
539 hdmi->tmds_rate = mode->clock * 1000;
540 inno_hdmi_i2c_init(hdmi);
542 /* Unmute video and audio output */
543 hdmi_modb(hdmi, HDMI_AV_MUTE, m_VIDEO_BLACK, v_VIDEO_MUTE(0));
544 if (hdmi->audio_enable)
545 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE, v_AUDIO_MUTE(0));
550 static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
551 struct drm_display_mode *mode,
552 struct drm_display_mode *adj_mode)
554 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
556 inno_hdmi_setup(hdmi, adj_mode);
558 /* Store the display mode for plugin/DPMS poweron events */
559 memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
562 static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
564 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
566 inno_hdmi_set_pwr_mode(hdmi, NORMAL);
569 static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
571 struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
573 inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
576 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
577 const struct drm_display_mode *mode,
578 struct drm_display_mode *adj_mode)
584 inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
585 struct drm_crtc_state *crtc_state,
586 struct drm_connector_state *conn_state)
588 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
590 s->output_mode = ROCKCHIP_OUT_MODE_P888;
591 s->output_type = DRM_MODE_CONNECTOR_HDMIA;
596 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
597 .enable = inno_hdmi_encoder_enable,
598 .disable = inno_hdmi_encoder_disable,
599 .mode_fixup = inno_hdmi_encoder_mode_fixup,
600 .mode_set = inno_hdmi_encoder_mode_set,
601 .atomic_check = inno_hdmi_encoder_atomic_check,
604 static struct drm_encoder_funcs inno_hdmi_encoder_funcs = {
605 .destroy = drm_encoder_cleanup,
608 static enum drm_connector_status
609 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
611 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
613 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
614 connector_status_connected : connector_status_disconnected;
617 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
619 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
626 edid = drm_get_edid(connector, hdmi->ddc);
628 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
629 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
630 drm_mode_connector_update_edid_property(connector, edid);
631 ret = drm_add_edid_modes(connector, edid);
638 static enum drm_mode_status
639 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
640 struct drm_display_mode *mode)
645 static struct drm_encoder *
646 inno_hdmi_connector_best_encoder(struct drm_connector *connector)
648 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
650 return &hdmi->encoder;
654 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
655 uint32_t maxX, uint32_t maxY)
657 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
660 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
662 drm_connector_unregister(connector);
663 drm_connector_cleanup(connector);
666 static struct drm_connector_funcs inno_hdmi_connector_funcs = {
667 .dpms = drm_atomic_helper_connector_dpms,
668 .fill_modes = inno_hdmi_probe_single_connector_modes,
669 .detect = inno_hdmi_connector_detect,
670 .destroy = inno_hdmi_connector_destroy,
671 .reset = drm_atomic_helper_connector_reset,
672 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
673 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
676 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
677 .get_modes = inno_hdmi_connector_get_modes,
678 .mode_valid = inno_hdmi_connector_mode_valid,
679 .best_encoder = inno_hdmi_connector_best_encoder,
682 int inno_hdmi_audio_config_set(struct inno_hdmi *hdmi, struct audio_info *audio)
684 int rate, N, channel;
686 if (audio->channels < 3)
687 channel = I2S_CHANNEL_1_2;
688 else if (audio->channels < 5)
689 channel = I2S_CHANNEL_3_4;
690 else if (audio->channels < 7)
691 channel = I2S_CHANNEL_5_6;
693 channel = I2S_CHANNEL_7_8;
695 switch (audio->sample_rate) {
725 dev_err(hdmi->dev, "[%s] not support such sample rate %d\n",
726 __func__, audio->sample_rate);
730 /* set_audio source I2S */
731 hdmi_writeb(hdmi, HDMI_AUDIO_CTRL1, 0x01);
732 hdmi_writeb(hdmi, AUDIO_SAMPLE_RATE, rate);
733 hdmi_writeb(hdmi, AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) |
734 v_I2S_CHANNEL(channel));
736 hdmi_writeb(hdmi, AUDIO_I2S_MAP, 0x00);
737 hdmi_writeb(hdmi, AUDIO_I2S_SWAPS_SPDIF, 0);
740 hdmi_writeb(hdmi, AUDIO_N_H, (N >> 16) & 0x0F);
741 hdmi_writeb(hdmi, AUDIO_N_M, (N >> 8) & 0xFF);
742 hdmi_writeb(hdmi, AUDIO_N_L, N & 0xFF);
744 /*Set hdmi nlpcm mode to support hdmi bitstream*/
745 hdmi_writeb(hdmi, HDMI_AUDIO_CHANNEL_STATUS, v_AUDIO_STATUS_NLPCM(0));
747 return inno_hdmi_config_audio_aai(hdmi, audio);
750 static int inno_hdmi_audio_hw_params(struct device *dev, void *d,
751 struct hdmi_codec_daifmt *daifmt,
752 struct hdmi_codec_params *params)
754 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
755 struct audio_info audio = {
756 .sample_width = params->sample_width,
757 .sample_rate = params->sample_rate,
758 .channels = params->channels,
761 if (!hdmi->hdmi_data.sink_has_audio) {
762 dev_err(hdmi->dev, "Sink do not support audio!\n");
766 if (!hdmi->encoder.crtc)
769 switch (daifmt->fmt) {
773 dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt);
777 return inno_hdmi_audio_config_set(hdmi, &audio);
780 static void inno_hdmi_audio_shutdown(struct device *dev, void *d)
785 static int inno_hdmi_audio_digital_mute(struct device *dev, void *d, bool mute)
787 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
789 if (!hdmi->hdmi_data.sink_has_audio) {
790 dev_err(hdmi->dev, "Sink do not support audio!\n");
794 hdmi->audio_enable = !mute;
797 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD,
798 v_AUDIO_MUTE(1) | v_AUDIO_PD(1));
800 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD,
801 v_AUDIO_MUTE(0) | v_AUDIO_PD(0));
806 static int inno_hdmi_audio_get_eld(struct device *dev, void *d,
807 uint8_t *buf, size_t len)
809 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
810 struct drm_mode_config *config = &hdmi->encoder.dev->mode_config;
811 struct drm_connector *connector;
814 mutex_lock(&config->mutex);
815 list_for_each_entry(connector, &config->connector_list, head) {
816 if (&hdmi->encoder == connector->encoder) {
817 memcpy(buf, connector->eld,
818 min(sizeof(connector->eld), len));
822 mutex_unlock(&config->mutex);
827 static const struct hdmi_codec_ops audio_codec_ops = {
828 .hw_params = inno_hdmi_audio_hw_params,
829 .audio_shutdown = inno_hdmi_audio_shutdown,
830 .digital_mute = inno_hdmi_audio_digital_mute,
831 .get_eld = inno_hdmi_audio_get_eld,
834 static int inno_hdmi_audio_codec_init(struct inno_hdmi *hdmi,
837 struct hdmi_codec_pdata codec_data = {
839 .ops = &audio_codec_ops,
840 .max_i2s_channels = 8,
843 hdmi->audio_enable = false;
844 hdmi->audio_pdev = platform_device_register_data(
845 dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE,
846 &codec_data, sizeof(codec_data));
848 return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
851 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
853 struct drm_encoder *encoder = &hdmi->encoder;
854 struct device *dev = hdmi->dev;
856 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
859 * If we failed to find the CRTC(s) which this encoder is
860 * supposed to be connected to, it's because the CRTC has
861 * not been registered yet. Defer probing, and hope that
862 * the required CRTC is added later.
864 if (encoder->possible_crtcs == 0)
865 return -EPROBE_DEFER;
867 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
868 drm_encoder_init(drm, encoder, &inno_hdmi_encoder_funcs,
869 DRM_MODE_ENCODER_TMDS, NULL);
871 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
872 hdmi->connector.port = dev->of_node;
874 drm_connector_helper_add(&hdmi->connector,
875 &inno_hdmi_connector_helper_funcs);
876 drm_connector_init(drm, &hdmi->connector, &inno_hdmi_connector_funcs,
877 DRM_MODE_CONNECTOR_HDMIA);
879 drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
881 inno_hdmi_audio_codec_init(hdmi, dev);
886 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
888 struct inno_hdmi_i2c *i2c = hdmi->i2c;
891 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
892 if (!(stat & m_INT_EDID_READY))
895 /* Clear HDMI EDID interrupt flag */
896 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
903 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
905 struct inno_hdmi *hdmi = dev_id;
906 irqreturn_t ret = IRQ_NONE;
910 ret = inno_hdmi_i2c_irq(hdmi);
912 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
913 if (interrupt & m_INT_HOTPLUG) {
914 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
915 ret = IRQ_WAKE_THREAD;
921 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
923 struct inno_hdmi *hdmi = dev_id;
925 drm_helper_hpd_irq_event(hdmi->connector.dev);
930 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
932 int length = msgs->len;
936 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
941 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
946 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
949 * The DDC module only support read EDID message, so
950 * we assume that each word write to this i2c adapter
951 * should be the offset of EDID word address.
953 if ((msgs->len != 1) ||
954 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
957 reinit_completion(&hdmi->i2c->cmp);
959 if (msgs->addr == DDC_SEGMENT_ADDR)
960 hdmi->i2c->segment_addr = msgs->buf[0];
961 if (msgs->addr == DDC_ADDR)
962 hdmi->i2c->ddc_addr = msgs->buf[0];
964 /* Set edid fifo first addr */
965 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
967 /* Set edid word address 0x00/0x80 */
968 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
970 /* Set edid segment pointer */
971 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
976 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
977 struct i2c_msg *msgs, int num)
979 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
980 struct inno_hdmi_i2c *i2c = hdmi->i2c;
983 mutex_lock(&i2c->lock);
985 /* Clear the EDID interrupt flag and unmute the interrupt */
986 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
987 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
989 for (i = 0; i < num; i++) {
990 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n",
991 i + 1, num, msgs[i].len, msgs[i].flags);
993 if (msgs[i].flags & I2C_M_RD)
994 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
996 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
1005 /* Mute HDMI EDID interrupt */
1006 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
1008 mutex_unlock(&i2c->lock);
1013 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
1015 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1018 static const struct i2c_algorithm inno_hdmi_algorithm = {
1019 .master_xfer = inno_hdmi_i2c_xfer,
1020 .functionality = inno_hdmi_i2c_func,
1023 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
1025 struct i2c_adapter *adap;
1026 struct inno_hdmi_i2c *i2c;
1029 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
1031 return ERR_PTR(-ENOMEM);
1033 mutex_init(&i2c->lock);
1034 init_completion(&i2c->cmp);
1037 adap->class = I2C_CLASS_DDC;
1038 adap->owner = THIS_MODULE;
1039 adap->dev.parent = hdmi->dev;
1040 adap->dev.of_node = hdmi->dev->of_node;
1041 adap->algo = &inno_hdmi_algorithm;
1042 strlcpy(adap->name, "Inno HDMI", sizeof(adap->name));
1043 i2c_set_adapdata(adap, hdmi);
1045 ret = i2c_add_adapter(adap);
1047 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
1048 devm_kfree(hdmi->dev, i2c);
1049 return ERR_PTR(ret);
1054 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
1059 static int inno_hdmi_bind(struct device *dev, struct device *master,
1062 struct platform_device *pdev = to_platform_device(dev);
1063 struct drm_device *drm = data;
1064 struct inno_hdmi *hdmi;
1065 struct resource *iores;
1069 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1074 hdmi->drm_dev = drm;
1076 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1080 hdmi->regs = devm_ioremap_resource(dev, iores);
1081 if (IS_ERR(hdmi->regs))
1082 return PTR_ERR(hdmi->regs);
1084 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk");
1085 if (IS_ERR(hdmi->pclk)) {
1086 dev_err(hdmi->dev, "Unable to get HDMI pclk clk\n");
1087 return PTR_ERR(hdmi->pclk);
1090 ret = clk_prepare_enable(hdmi->pclk);
1092 dev_err(hdmi->dev, "Cannot enable HDMI pclk clock: %d\n", ret);
1096 irq = platform_get_irq(pdev, 0);
1100 inno_hdmi_reset(hdmi);
1102 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
1103 if (IS_ERR(hdmi->ddc)) {
1104 ret = PTR_ERR(hdmi->ddc);
1110 * When IP controller haven't configured to an accurate video
1111 * timing, then the TMDS clock source would be switched to
1112 * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
1113 * and reconfigure the DDC clock.
1115 hdmi->tmds_rate = clk_get_rate(hdmi->pclk);
1116 inno_hdmi_i2c_init(hdmi);
1118 ret = inno_hdmi_register(drm, hdmi);
1122 dev_set_drvdata(dev, hdmi);
1124 /* Unmute hotplug interrupt */
1125 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
1127 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
1128 inno_hdmi_irq, IRQF_SHARED,
1129 dev_name(dev), hdmi);
1134 static void inno_hdmi_unbind(struct device *dev, struct device *master,
1137 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
1139 hdmi->connector.funcs->destroy(&hdmi->connector);
1140 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1142 clk_disable_unprepare(hdmi->pclk);
1143 i2c_put_adapter(hdmi->ddc);
1146 static const struct component_ops inno_hdmi_ops = {
1147 .bind = inno_hdmi_bind,
1148 .unbind = inno_hdmi_unbind,
1151 static int inno_hdmi_probe(struct platform_device *pdev)
1153 return component_add(&pdev->dev, &inno_hdmi_ops);
1156 static int inno_hdmi_remove(struct platform_device *pdev)
1158 component_del(&pdev->dev, &inno_hdmi_ops);
1163 static const struct of_device_id inno_hdmi_dt_ids[] = {
1164 { .compatible = "rockchip,rk3036-inno-hdmi",
1168 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
1170 static struct platform_driver inno_hdmi_driver = {
1171 .probe = inno_hdmi_probe,
1172 .remove = inno_hdmi_remove,
1174 .name = "innohdmi-rockchip",
1175 .of_match_table = inno_hdmi_dt_ids,
1179 module_platform_driver(inno_hdmi_driver);
1181 MODULE_AUTHOR("Zheng Yang <zhengyang@rock-chips.com>");
1182 MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
1183 MODULE_DESCRIPTION("Rockchip Specific INNO-HDMI Driver");
1184 MODULE_LICENSE("GPL v2");
1185 MODULE_ALIAS("platform:innohdmi-rockchip");