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, false);
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;
592 s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
597 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
598 .enable = inno_hdmi_encoder_enable,
599 .disable = inno_hdmi_encoder_disable,
600 .mode_fixup = inno_hdmi_encoder_mode_fixup,
601 .mode_set = inno_hdmi_encoder_mode_set,
602 .atomic_check = inno_hdmi_encoder_atomic_check,
605 static struct drm_encoder_funcs inno_hdmi_encoder_funcs = {
606 .destroy = drm_encoder_cleanup,
609 static enum drm_connector_status
610 inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
612 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
614 return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
615 connector_status_connected : connector_status_disconnected;
618 static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
620 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
627 edid = drm_get_edid(connector, hdmi->ddc);
629 hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid);
630 hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid);
631 drm_mode_connector_update_edid_property(connector, edid);
632 ret = drm_add_edid_modes(connector, edid);
639 static enum drm_mode_status
640 inno_hdmi_connector_mode_valid(struct drm_connector *connector,
641 struct drm_display_mode *mode)
646 static struct drm_encoder *
647 inno_hdmi_connector_best_encoder(struct drm_connector *connector)
649 struct inno_hdmi *hdmi = to_inno_hdmi(connector);
651 return &hdmi->encoder;
655 inno_hdmi_probe_single_connector_modes(struct drm_connector *connector,
656 uint32_t maxX, uint32_t maxY)
658 return drm_helper_probe_single_connector_modes(connector, 1920, 1080);
661 static void inno_hdmi_connector_destroy(struct drm_connector *connector)
663 drm_connector_unregister(connector);
664 drm_connector_cleanup(connector);
667 static struct drm_connector_funcs inno_hdmi_connector_funcs = {
668 .dpms = drm_atomic_helper_connector_dpms,
669 .fill_modes = inno_hdmi_probe_single_connector_modes,
670 .detect = inno_hdmi_connector_detect,
671 .destroy = inno_hdmi_connector_destroy,
672 .reset = drm_atomic_helper_connector_reset,
673 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
674 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
677 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
678 .get_modes = inno_hdmi_connector_get_modes,
679 .mode_valid = inno_hdmi_connector_mode_valid,
680 .best_encoder = inno_hdmi_connector_best_encoder,
683 int inno_hdmi_audio_config_set(struct inno_hdmi *hdmi, struct audio_info *audio)
685 int rate, N, channel;
687 if (audio->channels < 3)
688 channel = I2S_CHANNEL_1_2;
689 else if (audio->channels < 5)
690 channel = I2S_CHANNEL_3_4;
691 else if (audio->channels < 7)
692 channel = I2S_CHANNEL_5_6;
694 channel = I2S_CHANNEL_7_8;
696 switch (audio->sample_rate) {
726 dev_err(hdmi->dev, "[%s] not support such sample rate %d\n",
727 __func__, audio->sample_rate);
731 /* set_audio source I2S */
732 hdmi_writeb(hdmi, HDMI_AUDIO_CTRL1, 0x01);
733 hdmi_writeb(hdmi, AUDIO_SAMPLE_RATE, rate);
734 hdmi_writeb(hdmi, AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) |
735 v_I2S_CHANNEL(channel));
737 hdmi_writeb(hdmi, AUDIO_I2S_MAP, 0x00);
738 hdmi_writeb(hdmi, AUDIO_I2S_SWAPS_SPDIF, 0);
741 hdmi_writeb(hdmi, AUDIO_N_H, (N >> 16) & 0x0F);
742 hdmi_writeb(hdmi, AUDIO_N_M, (N >> 8) & 0xFF);
743 hdmi_writeb(hdmi, AUDIO_N_L, N & 0xFF);
745 /*Set hdmi nlpcm mode to support hdmi bitstream*/
746 hdmi_writeb(hdmi, HDMI_AUDIO_CHANNEL_STATUS, v_AUDIO_STATUS_NLPCM(0));
748 return inno_hdmi_config_audio_aai(hdmi, audio);
751 static int inno_hdmi_audio_hw_params(struct device *dev, void *d,
752 struct hdmi_codec_daifmt *daifmt,
753 struct hdmi_codec_params *params)
755 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
756 struct audio_info audio = {
757 .sample_width = params->sample_width,
758 .sample_rate = params->sample_rate,
759 .channels = params->channels,
762 if (!hdmi->hdmi_data.sink_has_audio) {
763 dev_err(hdmi->dev, "Sink do not support audio!\n");
767 if (!hdmi->encoder.crtc)
770 switch (daifmt->fmt) {
774 dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt);
778 return inno_hdmi_audio_config_set(hdmi, &audio);
781 static void inno_hdmi_audio_shutdown(struct device *dev, void *d)
786 static int inno_hdmi_audio_digital_mute(struct device *dev, void *d, bool mute)
788 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
790 if (!hdmi->hdmi_data.sink_has_audio) {
791 dev_err(hdmi->dev, "Sink do not support audio!\n");
795 hdmi->audio_enable = !mute;
798 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD,
799 v_AUDIO_MUTE(1) | v_AUDIO_PD(1));
801 hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD,
802 v_AUDIO_MUTE(0) | v_AUDIO_PD(0));
807 static int inno_hdmi_audio_get_eld(struct device *dev, void *d,
808 uint8_t *buf, size_t len)
810 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
811 struct drm_mode_config *config = &hdmi->encoder.dev->mode_config;
812 struct drm_connector *connector;
815 mutex_lock(&config->mutex);
816 list_for_each_entry(connector, &config->connector_list, head) {
817 if (&hdmi->encoder == connector->encoder) {
818 memcpy(buf, connector->eld,
819 min(sizeof(connector->eld), len));
823 mutex_unlock(&config->mutex);
828 static const struct hdmi_codec_ops audio_codec_ops = {
829 .hw_params = inno_hdmi_audio_hw_params,
830 .audio_shutdown = inno_hdmi_audio_shutdown,
831 .digital_mute = inno_hdmi_audio_digital_mute,
832 .get_eld = inno_hdmi_audio_get_eld,
835 static int inno_hdmi_audio_codec_init(struct inno_hdmi *hdmi,
838 struct hdmi_codec_pdata codec_data = {
840 .ops = &audio_codec_ops,
841 .max_i2s_channels = 8,
844 hdmi->audio_enable = false;
845 hdmi->audio_pdev = platform_device_register_data(
846 dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE,
847 &codec_data, sizeof(codec_data));
849 return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
852 static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
854 struct drm_encoder *encoder = &hdmi->encoder;
855 struct device *dev = hdmi->dev;
857 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
860 * If we failed to find the CRTC(s) which this encoder is
861 * supposed to be connected to, it's because the CRTC has
862 * not been registered yet. Defer probing, and hope that
863 * the required CRTC is added later.
865 if (encoder->possible_crtcs == 0)
866 return -EPROBE_DEFER;
868 drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
869 drm_encoder_init(drm, encoder, &inno_hdmi_encoder_funcs,
870 DRM_MODE_ENCODER_TMDS, NULL);
872 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
873 hdmi->connector.port = dev->of_node;
875 drm_connector_helper_add(&hdmi->connector,
876 &inno_hdmi_connector_helper_funcs);
877 drm_connector_init(drm, &hdmi->connector, &inno_hdmi_connector_funcs,
878 DRM_MODE_CONNECTOR_HDMIA);
880 drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
882 inno_hdmi_audio_codec_init(hdmi, dev);
887 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
889 struct inno_hdmi_i2c *i2c = hdmi->i2c;
892 stat = hdmi_readb(hdmi, HDMI_INTERRUPT_STATUS1);
893 if (!(stat & m_INT_EDID_READY))
896 /* Clear HDMI EDID interrupt flag */
897 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
904 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
906 struct inno_hdmi *hdmi = dev_id;
907 irqreturn_t ret = IRQ_NONE;
911 ret = inno_hdmi_i2c_irq(hdmi);
913 interrupt = hdmi_readb(hdmi, HDMI_STATUS);
914 if (interrupt & m_INT_HOTPLUG) {
915 hdmi_modb(hdmi, HDMI_STATUS, m_INT_HOTPLUG, m_INT_HOTPLUG);
916 ret = IRQ_WAKE_THREAD;
922 static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
924 struct inno_hdmi *hdmi = dev_id;
926 drm_helper_hpd_irq_event(hdmi->connector.dev);
931 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
933 int length = msgs->len;
937 ret = wait_for_completion_timeout(&hdmi->i2c->cmp, HZ / 10);
942 *buf++ = hdmi_readb(hdmi, HDMI_EDID_FIFO_ADDR);
947 static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
950 * The DDC module only support read EDID message, so
951 * we assume that each word write to this i2c adapter
952 * should be the offset of EDID word address.
954 if ((msgs->len != 1) ||
955 ((msgs->addr != DDC_ADDR) && (msgs->addr != DDC_SEGMENT_ADDR)))
958 reinit_completion(&hdmi->i2c->cmp);
960 if (msgs->addr == DDC_SEGMENT_ADDR)
961 hdmi->i2c->segment_addr = msgs->buf[0];
962 if (msgs->addr == DDC_ADDR)
963 hdmi->i2c->ddc_addr = msgs->buf[0];
965 /* Set edid fifo first addr */
966 hdmi_writeb(hdmi, HDMI_EDID_FIFO_OFFSET, 0x00);
968 /* Set edid word address 0x00/0x80 */
969 hdmi_writeb(hdmi, HDMI_EDID_WORD_ADDR, hdmi->i2c->ddc_addr);
971 /* Set edid segment pointer */
972 hdmi_writeb(hdmi, HDMI_EDID_SEGMENT_POINTER, hdmi->i2c->segment_addr);
977 static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
978 struct i2c_msg *msgs, int num)
980 struct inno_hdmi *hdmi = i2c_get_adapdata(adap);
981 struct inno_hdmi_i2c *i2c = hdmi->i2c;
984 mutex_lock(&i2c->lock);
986 /* Clear the EDID interrupt flag and unmute the interrupt */
987 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, m_INT_EDID_READY);
988 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
990 for (i = 0; i < num; i++) {
991 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n",
992 i + 1, num, msgs[i].len, msgs[i].flags);
994 if (msgs[i].flags & I2C_M_RD)
995 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
997 ret = inno_hdmi_i2c_write(hdmi, &msgs[i]);
1006 /* Mute HDMI EDID interrupt */
1007 hdmi_writeb(hdmi, HDMI_INTERRUPT_MASK1, 0);
1009 mutex_unlock(&i2c->lock);
1014 static u32 inno_hdmi_i2c_func(struct i2c_adapter *adapter)
1016 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1019 static const struct i2c_algorithm inno_hdmi_algorithm = {
1020 .master_xfer = inno_hdmi_i2c_xfer,
1021 .functionality = inno_hdmi_i2c_func,
1024 static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
1026 struct i2c_adapter *adap;
1027 struct inno_hdmi_i2c *i2c;
1030 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
1032 return ERR_PTR(-ENOMEM);
1034 mutex_init(&i2c->lock);
1035 init_completion(&i2c->cmp);
1038 adap->class = I2C_CLASS_DDC;
1039 adap->owner = THIS_MODULE;
1040 adap->dev.parent = hdmi->dev;
1041 adap->dev.of_node = hdmi->dev->of_node;
1042 adap->algo = &inno_hdmi_algorithm;
1043 strlcpy(adap->name, "Inno HDMI", sizeof(adap->name));
1044 i2c_set_adapdata(adap, hdmi);
1046 ret = i2c_add_adapter(adap);
1048 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
1049 devm_kfree(hdmi->dev, i2c);
1050 return ERR_PTR(ret);
1055 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
1060 static int inno_hdmi_bind(struct device *dev, struct device *master,
1063 struct platform_device *pdev = to_platform_device(dev);
1064 struct drm_device *drm = data;
1065 struct inno_hdmi *hdmi;
1066 struct resource *iores;
1070 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
1075 hdmi->drm_dev = drm;
1077 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1081 hdmi->regs = devm_ioremap_resource(dev, iores);
1082 if (IS_ERR(hdmi->regs))
1083 return PTR_ERR(hdmi->regs);
1085 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk");
1086 if (IS_ERR(hdmi->pclk)) {
1087 dev_err(hdmi->dev, "Unable to get HDMI pclk clk\n");
1088 return PTR_ERR(hdmi->pclk);
1091 ret = clk_prepare_enable(hdmi->pclk);
1093 dev_err(hdmi->dev, "Cannot enable HDMI pclk clock: %d\n", ret);
1097 irq = platform_get_irq(pdev, 0);
1101 inno_hdmi_reset(hdmi);
1103 hdmi->ddc = inno_hdmi_i2c_adapter(hdmi);
1104 if (IS_ERR(hdmi->ddc)) {
1105 ret = PTR_ERR(hdmi->ddc);
1111 * When IP controller haven't configured to an accurate video
1112 * timing, then the TMDS clock source would be switched to
1113 * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
1114 * and reconfigure the DDC clock.
1116 hdmi->tmds_rate = clk_get_rate(hdmi->pclk);
1117 inno_hdmi_i2c_init(hdmi);
1119 ret = inno_hdmi_register(drm, hdmi);
1123 dev_set_drvdata(dev, hdmi);
1125 /* Unmute hotplug interrupt */
1126 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
1128 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
1129 inno_hdmi_irq, IRQF_SHARED,
1130 dev_name(dev), hdmi);
1135 static void inno_hdmi_unbind(struct device *dev, struct device *master,
1138 struct inno_hdmi *hdmi = dev_get_drvdata(dev);
1140 hdmi->connector.funcs->destroy(&hdmi->connector);
1141 hdmi->encoder.funcs->destroy(&hdmi->encoder);
1143 clk_disable_unprepare(hdmi->pclk);
1144 i2c_put_adapter(hdmi->ddc);
1147 static const struct component_ops inno_hdmi_ops = {
1148 .bind = inno_hdmi_bind,
1149 .unbind = inno_hdmi_unbind,
1152 static int inno_hdmi_probe(struct platform_device *pdev)
1154 return component_add(&pdev->dev, &inno_hdmi_ops);
1157 static int inno_hdmi_remove(struct platform_device *pdev)
1159 component_del(&pdev->dev, &inno_hdmi_ops);
1164 static const struct of_device_id inno_hdmi_dt_ids[] = {
1165 { .compatible = "rockchip,rk3036-inno-hdmi",
1169 MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
1171 static struct platform_driver inno_hdmi_driver = {
1172 .probe = inno_hdmi_probe,
1173 .remove = inno_hdmi_remove,
1175 .name = "innohdmi-rockchip",
1176 .of_match_table = inno_hdmi_dt_ids,
1180 module_platform_driver(inno_hdmi_driver);
1182 MODULE_AUTHOR("Zheng Yang <zhengyang@rock-chips.com>");
1183 MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
1184 MODULE_DESCRIPTION("Rockchip Specific INNO-HDMI Driver");
1185 MODULE_LICENSE("GPL v2");
1186 MODULE_ALIAS("platform:innohdmi-rockchip");