1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Zheng Yang <zhengyang@rock-chips.com>
5 * Yakir Yang <ykk@rock-chips.com>
10 #include <linux/delay.h>
11 #include <linux/err.h>
12 #include <linux/hdmi.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/of_device.h>
18 #include <drm/drm_atomic_helper.h>
19 #include <drm/drm_edid.h>
20 #include <drm/drm_of.h>
21 #include <drm/drm_probe_helper.h>
23 #include "rockchip_drm_drv.h"
24 #include "rockchip_drm_vop.h"
26 #include "inno_hdmi.h"
28 #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x)
30 struct hdmi_data_info
{
34 unsigned int enc_in_format
;
35 unsigned int enc_out_format
;
36 unsigned int colorimetry
;
39 struct inno_hdmi_i2c
{
40 struct i2c_adapter adap
;
46 struct completion cmp
;
51 struct drm_device
*drm_dev
;
57 struct drm_connector connector
;
58 struct drm_encoder encoder
;
60 struct inno_hdmi_i2c
*i2c
;
61 struct i2c_adapter
*ddc
;
63 unsigned int tmds_rate
;
65 struct hdmi_data_info hdmi_data
;
66 struct drm_display_mode previous_mode
;
70 CSC_ITU601_16_235_TO_RGB_0_255_8BIT
,
71 CSC_ITU601_0_255_TO_RGB_0_255_8BIT
,
72 CSC_ITU709_16_235_TO_RGB_0_255_8BIT
,
73 CSC_RGB_0_255_TO_ITU601_16_235_8BIT
,
74 CSC_RGB_0_255_TO_ITU709_16_235_8BIT
,
75 CSC_RGB_0_255_TO_RGB_16_235_8BIT
,
78 static const char coeff_csc
[][24] = {
80 * YUV2RGB:601 SD mode(Y[16:235], UV[16:240], RGB[0:255]):
81 * R = 1.164*Y + 1.596*V - 204
82 * G = 1.164*Y - 0.391*U - 0.813*V + 154
83 * B = 1.164*Y + 2.018*U - 258
86 0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
87 0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
88 0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02
91 * YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
92 * R = Y + 1.402*V - 248
93 * G = Y - 0.344*U - 0.714*V + 135
94 * B = Y + 1.772*U - 227
97 0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
98 0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
99 0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3
102 * YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
103 * R = 1.164*Y + 1.793*V - 248
104 * G = 1.164*Y - 0.213*U - 0.534*V + 77
105 * B = 1.164*Y + 2.115*U - 289
108 0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
109 0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
110 0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21
114 * RGB2YUV:601 SD mode:
115 * Cb = -0.291G - 0.148R + 0.439B + 128
116 * Y = 0.504G + 0.257R + 0.098B + 16
117 * Cr = -0.368G + 0.439R - 0.071B + 128
120 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
121 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
122 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
125 * RGB2YUV:709 HD mode:
126 * Cb = - 0.338G - 0.101R + 0.439B + 128
127 * Y = 0.614G + 0.183R + 0.062B + 16
128 * Cr = - 0.399G + 0.439R - 0.040B + 128
131 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
132 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
133 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
136 * RGB[0:255]2RGB[16:235]:
137 * R' = R x (235-16)/255 + 16;
138 * G' = G x (235-16)/255 + 16;
139 * B' = B x (235-16)/255 + 16;
142 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
143 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
144 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10
148 static inline u8
hdmi_readb(struct inno_hdmi
*hdmi
, u16 offset
)
150 return readl_relaxed(hdmi
->regs
+ (offset
) * 0x04);
153 static inline void hdmi_writeb(struct inno_hdmi
*hdmi
, u16 offset
, u32 val
)
155 writel_relaxed(val
, hdmi
->regs
+ (offset
) * 0x04);
158 static inline void hdmi_modb(struct inno_hdmi
*hdmi
, u16 offset
,
161 u8 temp
= hdmi_readb(hdmi
, offset
) & ~msk
;
164 hdmi_writeb(hdmi
, offset
, temp
);
167 static void inno_hdmi_i2c_init(struct inno_hdmi
*hdmi
)
171 ddc_bus_freq
= (hdmi
->tmds_rate
>> 2) / HDMI_SCL_RATE
;
173 hdmi_writeb(hdmi
, DDC_BUS_FREQ_L
, ddc_bus_freq
& 0xFF);
174 hdmi_writeb(hdmi
, DDC_BUS_FREQ_H
, (ddc_bus_freq
>> 8) & 0xFF);
176 /* Clear the EDID interrupt flag and mute the interrupt */
177 hdmi_writeb(hdmi
, HDMI_INTERRUPT_MASK1
, 0);
178 hdmi_writeb(hdmi
, HDMI_INTERRUPT_STATUS1
, m_INT_EDID_READY
);
181 static void inno_hdmi_sys_power(struct inno_hdmi
*hdmi
, bool enable
)
184 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, m_POWER
, v_PWR_ON
);
186 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, m_POWER
, v_PWR_OFF
);
189 static void inno_hdmi_set_pwr_mode(struct inno_hdmi
*hdmi
, int mode
)
193 inno_hdmi_sys_power(hdmi
, false);
195 hdmi_writeb(hdmi
, HDMI_PHY_PRE_EMPHASIS
, 0x6f);
196 hdmi_writeb(hdmi
, HDMI_PHY_DRIVER
, 0xbb);
198 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x15);
199 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x14);
200 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x10);
201 hdmi_writeb(hdmi
, HDMI_PHY_CHG_PWR
, 0x0f);
202 hdmi_writeb(hdmi
, HDMI_PHY_SYNC
, 0x00);
203 hdmi_writeb(hdmi
, HDMI_PHY_SYNC
, 0x01);
205 inno_hdmi_sys_power(hdmi
, true);
209 inno_hdmi_sys_power(hdmi
, false);
210 hdmi_writeb(hdmi
, HDMI_PHY_DRIVER
, 0x00);
211 hdmi_writeb(hdmi
, HDMI_PHY_PRE_EMPHASIS
, 0x00);
212 hdmi_writeb(hdmi
, HDMI_PHY_CHG_PWR
, 0x00);
213 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x15);
218 DRM_DEV_ERROR(hdmi
->dev
, "Unknown power mode %d\n", mode
);
222 static void inno_hdmi_reset(struct inno_hdmi
*hdmi
)
227 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, m_RST_DIGITAL
, v_NOT_RST_DIGITAL
);
230 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, m_RST_ANALOG
, v_NOT_RST_ANALOG
);
233 msk
= m_REG_CLK_INV
| m_REG_CLK_SOURCE
| m_POWER
| m_INT_POL
;
234 val
= v_REG_CLK_INV
| v_REG_CLK_SOURCE_SYS
| v_PWR_ON
| v_INT_POL_HIGH
;
235 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, msk
, val
);
237 inno_hdmi_set_pwr_mode(hdmi
, NORMAL
);
240 static int inno_hdmi_upload_frame(struct inno_hdmi
*hdmi
, int setup_rc
,
241 union hdmi_infoframe
*frame
, u32 frame_index
,
242 u32 mask
, u32 disable
, u32 enable
)
245 hdmi_modb(hdmi
, HDMI_PACKET_SEND_AUTO
, mask
, disable
);
247 hdmi_writeb(hdmi
, HDMI_CONTROL_PACKET_BUF_INDEX
, frame_index
);
250 u8 packed_frame
[HDMI_MAXIMUM_INFO_FRAME_SIZE
];
253 rc
= hdmi_infoframe_pack(frame
, packed_frame
,
254 sizeof(packed_frame
));
258 for (i
= 0; i
< rc
; i
++)
259 hdmi_writeb(hdmi
, HDMI_CONTROL_PACKET_ADDR
+ i
,
263 hdmi_modb(hdmi
, HDMI_PACKET_SEND_AUTO
, mask
, enable
);
269 static int inno_hdmi_config_video_vsi(struct inno_hdmi
*hdmi
,
270 struct drm_display_mode
*mode
)
272 union hdmi_infoframe frame
;
275 rc
= drm_hdmi_vendor_infoframe_from_display_mode(&frame
.vendor
.hdmi
,
279 return inno_hdmi_upload_frame(hdmi
, rc
, &frame
, INFOFRAME_VSI
,
280 m_PACKET_VSI_EN
, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
283 static int inno_hdmi_config_video_avi(struct inno_hdmi
*hdmi
,
284 struct drm_display_mode
*mode
)
286 union hdmi_infoframe frame
;
289 rc
= drm_hdmi_avi_infoframe_from_display_mode(&frame
.avi
,
293 if (hdmi
->hdmi_data
.enc_out_format
== HDMI_COLORSPACE_YUV444
)
294 frame
.avi
.colorspace
= HDMI_COLORSPACE_YUV444
;
295 else if (hdmi
->hdmi_data
.enc_out_format
== HDMI_COLORSPACE_YUV422
)
296 frame
.avi
.colorspace
= HDMI_COLORSPACE_YUV422
;
298 frame
.avi
.colorspace
= HDMI_COLORSPACE_RGB
;
300 return inno_hdmi_upload_frame(hdmi
, rc
, &frame
, INFOFRAME_AVI
, 0, 0, 0);
303 static int inno_hdmi_config_video_csc(struct inno_hdmi
*hdmi
)
305 struct hdmi_data_info
*data
= &hdmi
->hdmi_data
;
306 int c0_c2_change
= 0;
313 /* Input video mode is SDR RGB24bit, data enable signal from external */
314 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL1
, v_DE_EXTERNAL
|
315 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444
));
317 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
318 value
= v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS
) |
319 v_VIDEO_OUTPUT_COLOR(0) |
320 v_VIDEO_INPUT_CSP(0);
321 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL2
, value
);
323 if (data
->enc_in_format
== data
->enc_out_format
) {
324 if ((data
->enc_in_format
== HDMI_COLORSPACE_RGB
) ||
325 (data
->enc_in_format
>= HDMI_COLORSPACE_YUV444
)) {
326 value
= v_SOF_DISABLE
| v_COLOR_DEPTH_NOT_INDICATED(1);
327 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL3
, value
);
329 hdmi_modb(hdmi
, HDMI_VIDEO_CONTRL
,
330 m_VIDEO_AUTO_CSC
| m_VIDEO_C0_C2_SWAP
,
331 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE
) |
332 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE
));
337 if (data
->colorimetry
== HDMI_COLORIMETRY_ITU_601
) {
338 if ((data
->enc_in_format
== HDMI_COLORSPACE_RGB
) &&
339 (data
->enc_out_format
== HDMI_COLORSPACE_YUV444
)) {
340 csc_mode
= CSC_RGB_0_255_TO_ITU601_16_235_8BIT
;
341 auto_csc
= AUTO_CSC_DISABLE
;
342 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
343 csc_enable
= v_CSC_ENABLE
;
344 } else if ((data
->enc_in_format
== HDMI_COLORSPACE_YUV444
) &&
345 (data
->enc_out_format
== HDMI_COLORSPACE_RGB
)) {
346 csc_mode
= CSC_ITU601_16_235_TO_RGB_0_255_8BIT
;
347 auto_csc
= AUTO_CSC_ENABLE
;
348 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
349 csc_enable
= v_CSC_DISABLE
;
352 if ((data
->enc_in_format
== HDMI_COLORSPACE_RGB
) &&
353 (data
->enc_out_format
== HDMI_COLORSPACE_YUV444
)) {
354 csc_mode
= CSC_RGB_0_255_TO_ITU709_16_235_8BIT
;
355 auto_csc
= AUTO_CSC_DISABLE
;
356 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
357 csc_enable
= v_CSC_ENABLE
;
358 } else if ((data
->enc_in_format
== HDMI_COLORSPACE_YUV444
) &&
359 (data
->enc_out_format
== HDMI_COLORSPACE_RGB
)) {
360 csc_mode
= CSC_ITU709_16_235_TO_RGB_0_255_8BIT
;
361 auto_csc
= AUTO_CSC_ENABLE
;
362 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
363 csc_enable
= v_CSC_DISABLE
;
367 for (i
= 0; i
< 24; i
++)
368 hdmi_writeb(hdmi
, HDMI_VIDEO_CSC_COEF
+ i
,
369 coeff_csc
[csc_mode
][i
]);
371 value
= v_SOF_DISABLE
| csc_enable
| v_COLOR_DEPTH_NOT_INDICATED(1);
372 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL3
, value
);
373 hdmi_modb(hdmi
, HDMI_VIDEO_CONTRL
, m_VIDEO_AUTO_CSC
|
374 m_VIDEO_C0_C2_SWAP
, v_VIDEO_AUTO_CSC(auto_csc
) |
375 v_VIDEO_C0_C2_SWAP(c0_c2_change
));
380 static int inno_hdmi_config_video_timing(struct inno_hdmi
*hdmi
,
381 struct drm_display_mode
*mode
)
385 /* Set detail external video timing polarity and interlace mode */
386 value
= v_EXTERANL_VIDEO(1);
387 value
|= mode
->flags
& DRM_MODE_FLAG_PHSYNC
?
388 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
389 value
|= mode
->flags
& DRM_MODE_FLAG_PVSYNC
?
390 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
391 value
|= mode
->flags
& DRM_MODE_FLAG_INTERLACE
?
392 v_INETLACE(1) : v_INETLACE(0);
393 hdmi_writeb(hdmi
, HDMI_VIDEO_TIMING_CTL
, value
);
395 /* Set detail external video timing */
396 value
= mode
->htotal
;
397 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HTOTAL_L
, value
& 0xFF);
398 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HTOTAL_H
, (value
>> 8) & 0xFF);
400 value
= mode
->htotal
- mode
->hdisplay
;
401 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HBLANK_L
, value
& 0xFF);
402 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HBLANK_H
, (value
>> 8) & 0xFF);
404 value
= mode
->hsync_start
- mode
->hdisplay
;
405 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDELAY_L
, value
& 0xFF);
406 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDELAY_H
, (value
>> 8) & 0xFF);
408 value
= mode
->hsync_end
- mode
->hsync_start
;
409 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDURATION_L
, value
& 0xFF);
410 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDURATION_H
, (value
>> 8) & 0xFF);
412 value
= mode
->vtotal
;
413 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VTOTAL_L
, value
& 0xFF);
414 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VTOTAL_H
, (value
>> 8) & 0xFF);
416 value
= mode
->vtotal
- mode
->vdisplay
;
417 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VBLANK
, value
& 0xFF);
419 value
= mode
->vsync_start
- mode
->vdisplay
;
420 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VDELAY
, value
& 0xFF);
422 value
= mode
->vsync_end
- mode
->vsync_start
;
423 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VDURATION
, value
& 0xFF);
425 hdmi_writeb(hdmi
, HDMI_PHY_PRE_DIV_RATIO
, 0x1e);
426 hdmi_writeb(hdmi
, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW
, 0x2c);
427 hdmi_writeb(hdmi
, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH
, 0x01);
432 static int inno_hdmi_setup(struct inno_hdmi
*hdmi
,
433 struct drm_display_mode
*mode
)
435 hdmi
->hdmi_data
.vic
= drm_match_cea_mode(mode
);
437 hdmi
->hdmi_data
.enc_in_format
= HDMI_COLORSPACE_RGB
;
438 hdmi
->hdmi_data
.enc_out_format
= HDMI_COLORSPACE_RGB
;
440 if ((hdmi
->hdmi_data
.vic
== 6) || (hdmi
->hdmi_data
.vic
== 7) ||
441 (hdmi
->hdmi_data
.vic
== 21) || (hdmi
->hdmi_data
.vic
== 22) ||
442 (hdmi
->hdmi_data
.vic
== 2) || (hdmi
->hdmi_data
.vic
== 3) ||
443 (hdmi
->hdmi_data
.vic
== 17) || (hdmi
->hdmi_data
.vic
== 18))
444 hdmi
->hdmi_data
.colorimetry
= HDMI_COLORIMETRY_ITU_601
;
446 hdmi
->hdmi_data
.colorimetry
= HDMI_COLORIMETRY_ITU_709
;
448 /* Mute video and audio output */
449 hdmi_modb(hdmi
, HDMI_AV_MUTE
, m_AUDIO_MUTE
| m_VIDEO_BLACK
,
450 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
453 hdmi_writeb(hdmi
, HDMI_HDCP_CTRL
,
454 v_HDMI_DVI(hdmi
->hdmi_data
.sink_is_hdmi
));
456 inno_hdmi_config_video_timing(hdmi
, mode
);
458 inno_hdmi_config_video_csc(hdmi
);
460 if (hdmi
->hdmi_data
.sink_is_hdmi
) {
461 inno_hdmi_config_video_avi(hdmi
, mode
);
462 inno_hdmi_config_video_vsi(hdmi
, mode
);
466 * When IP controller have configured to an accurate video
467 * timing, then the TMDS clock source would be switched to
468 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
469 * clock rate, and reconfigure the DDC clock.
471 hdmi
->tmds_rate
= mode
->clock
* 1000;
472 inno_hdmi_i2c_init(hdmi
);
474 /* Unmute video and audio output */
475 hdmi_modb(hdmi
, HDMI_AV_MUTE
, m_AUDIO_MUTE
| m_VIDEO_BLACK
,
476 v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
481 static void inno_hdmi_encoder_mode_set(struct drm_encoder
*encoder
,
482 struct drm_display_mode
*mode
,
483 struct drm_display_mode
*adj_mode
)
485 struct inno_hdmi
*hdmi
= to_inno_hdmi(encoder
);
487 inno_hdmi_setup(hdmi
, adj_mode
);
489 /* Store the display mode for plugin/DPMS poweron events */
490 memcpy(&hdmi
->previous_mode
, adj_mode
, sizeof(hdmi
->previous_mode
));
493 static void inno_hdmi_encoder_enable(struct drm_encoder
*encoder
)
495 struct inno_hdmi
*hdmi
= to_inno_hdmi(encoder
);
497 inno_hdmi_set_pwr_mode(hdmi
, NORMAL
);
500 static void inno_hdmi_encoder_disable(struct drm_encoder
*encoder
)
502 struct inno_hdmi
*hdmi
= to_inno_hdmi(encoder
);
504 inno_hdmi_set_pwr_mode(hdmi
, LOWER_PWR
);
507 static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder
*encoder
,
508 const struct drm_display_mode
*mode
,
509 struct drm_display_mode
*adj_mode
)
515 inno_hdmi_encoder_atomic_check(struct drm_encoder
*encoder
,
516 struct drm_crtc_state
*crtc_state
,
517 struct drm_connector_state
*conn_state
)
519 struct rockchip_crtc_state
*s
= to_rockchip_crtc_state(crtc_state
);
521 s
->output_mode
= ROCKCHIP_OUT_MODE_P888
;
522 s
->output_type
= DRM_MODE_CONNECTOR_HDMIA
;
527 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs
= {
528 .enable
= inno_hdmi_encoder_enable
,
529 .disable
= inno_hdmi_encoder_disable
,
530 .mode_fixup
= inno_hdmi_encoder_mode_fixup
,
531 .mode_set
= inno_hdmi_encoder_mode_set
,
532 .atomic_check
= inno_hdmi_encoder_atomic_check
,
535 static struct drm_encoder_funcs inno_hdmi_encoder_funcs
= {
536 .destroy
= drm_encoder_cleanup
,
539 static enum drm_connector_status
540 inno_hdmi_connector_detect(struct drm_connector
*connector
, bool force
)
542 struct inno_hdmi
*hdmi
= to_inno_hdmi(connector
);
544 return (hdmi_readb(hdmi
, HDMI_STATUS
) & m_HOTPLUG
) ?
545 connector_status_connected
: connector_status_disconnected
;
548 static int inno_hdmi_connector_get_modes(struct drm_connector
*connector
)
550 struct inno_hdmi
*hdmi
= to_inno_hdmi(connector
);
557 edid
= drm_get_edid(connector
, hdmi
->ddc
);
559 hdmi
->hdmi_data
.sink_is_hdmi
= drm_detect_hdmi_monitor(edid
);
560 hdmi
->hdmi_data
.sink_has_audio
= drm_detect_monitor_audio(edid
);
561 drm_connector_update_edid_property(connector
, edid
);
562 ret
= drm_add_edid_modes(connector
, edid
);
569 static enum drm_mode_status
570 inno_hdmi_connector_mode_valid(struct drm_connector
*connector
,
571 struct drm_display_mode
*mode
)
577 inno_hdmi_probe_single_connector_modes(struct drm_connector
*connector
,
578 uint32_t maxX
, uint32_t maxY
)
580 return drm_helper_probe_single_connector_modes(connector
, 1920, 1080);
583 static void inno_hdmi_connector_destroy(struct drm_connector
*connector
)
585 drm_connector_unregister(connector
);
586 drm_connector_cleanup(connector
);
589 static const struct drm_connector_funcs inno_hdmi_connector_funcs
= {
590 .fill_modes
= inno_hdmi_probe_single_connector_modes
,
591 .detect
= inno_hdmi_connector_detect
,
592 .destroy
= inno_hdmi_connector_destroy
,
593 .reset
= drm_atomic_helper_connector_reset
,
594 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
595 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
598 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs
= {
599 .get_modes
= inno_hdmi_connector_get_modes
,
600 .mode_valid
= inno_hdmi_connector_mode_valid
,
603 static int inno_hdmi_register(struct drm_device
*drm
, struct inno_hdmi
*hdmi
)
605 struct drm_encoder
*encoder
= &hdmi
->encoder
;
606 struct device
*dev
= hdmi
->dev
;
608 encoder
->possible_crtcs
= drm_of_find_possible_crtcs(drm
, dev
->of_node
);
611 * If we failed to find the CRTC(s) which this encoder is
612 * supposed to be connected to, it's because the CRTC has
613 * not been registered yet. Defer probing, and hope that
614 * the required CRTC is added later.
616 if (encoder
->possible_crtcs
== 0)
617 return -EPROBE_DEFER
;
619 drm_encoder_helper_add(encoder
, &inno_hdmi_encoder_helper_funcs
);
620 drm_encoder_init(drm
, encoder
, &inno_hdmi_encoder_funcs
,
621 DRM_MODE_ENCODER_TMDS
, NULL
);
623 hdmi
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
625 drm_connector_helper_add(&hdmi
->connector
,
626 &inno_hdmi_connector_helper_funcs
);
627 drm_connector_init_with_ddc(drm
, &hdmi
->connector
,
628 &inno_hdmi_connector_funcs
,
629 DRM_MODE_CONNECTOR_HDMIA
,
632 drm_connector_attach_encoder(&hdmi
->connector
, encoder
);
637 static irqreturn_t
inno_hdmi_i2c_irq(struct inno_hdmi
*hdmi
)
639 struct inno_hdmi_i2c
*i2c
= hdmi
->i2c
;
642 stat
= hdmi_readb(hdmi
, HDMI_INTERRUPT_STATUS1
);
643 if (!(stat
& m_INT_EDID_READY
))
646 /* Clear HDMI EDID interrupt flag */
647 hdmi_writeb(hdmi
, HDMI_INTERRUPT_STATUS1
, m_INT_EDID_READY
);
654 static irqreturn_t
inno_hdmi_hardirq(int irq
, void *dev_id
)
656 struct inno_hdmi
*hdmi
= dev_id
;
657 irqreturn_t ret
= IRQ_NONE
;
661 ret
= inno_hdmi_i2c_irq(hdmi
);
663 interrupt
= hdmi_readb(hdmi
, HDMI_STATUS
);
664 if (interrupt
& m_INT_HOTPLUG
) {
665 hdmi_modb(hdmi
, HDMI_STATUS
, m_INT_HOTPLUG
, m_INT_HOTPLUG
);
666 ret
= IRQ_WAKE_THREAD
;
672 static irqreturn_t
inno_hdmi_irq(int irq
, void *dev_id
)
674 struct inno_hdmi
*hdmi
= dev_id
;
676 drm_helper_hpd_irq_event(hdmi
->connector
.dev
);
681 static int inno_hdmi_i2c_read(struct inno_hdmi
*hdmi
, struct i2c_msg
*msgs
)
683 int length
= msgs
->len
;
687 ret
= wait_for_completion_timeout(&hdmi
->i2c
->cmp
, HZ
/ 10);
692 *buf
++ = hdmi_readb(hdmi
, HDMI_EDID_FIFO_ADDR
);
697 static int inno_hdmi_i2c_write(struct inno_hdmi
*hdmi
, struct i2c_msg
*msgs
)
700 * The DDC module only support read EDID message, so
701 * we assume that each word write to this i2c adapter
702 * should be the offset of EDID word address.
704 if ((msgs
->len
!= 1) ||
705 ((msgs
->addr
!= DDC_ADDR
) && (msgs
->addr
!= DDC_SEGMENT_ADDR
)))
708 reinit_completion(&hdmi
->i2c
->cmp
);
710 if (msgs
->addr
== DDC_SEGMENT_ADDR
)
711 hdmi
->i2c
->segment_addr
= msgs
->buf
[0];
712 if (msgs
->addr
== DDC_ADDR
)
713 hdmi
->i2c
->ddc_addr
= msgs
->buf
[0];
715 /* Set edid fifo first addr */
716 hdmi_writeb(hdmi
, HDMI_EDID_FIFO_OFFSET
, 0x00);
718 /* Set edid word address 0x00/0x80 */
719 hdmi_writeb(hdmi
, HDMI_EDID_WORD_ADDR
, hdmi
->i2c
->ddc_addr
);
721 /* Set edid segment pointer */
722 hdmi_writeb(hdmi
, HDMI_EDID_SEGMENT_POINTER
, hdmi
->i2c
->segment_addr
);
727 static int inno_hdmi_i2c_xfer(struct i2c_adapter
*adap
,
728 struct i2c_msg
*msgs
, int num
)
730 struct inno_hdmi
*hdmi
= i2c_get_adapdata(adap
);
731 struct inno_hdmi_i2c
*i2c
= hdmi
->i2c
;
734 mutex_lock(&i2c
->lock
);
736 /* Clear the EDID interrupt flag and unmute the interrupt */
737 hdmi_writeb(hdmi
, HDMI_INTERRUPT_MASK1
, m_INT_EDID_READY
);
738 hdmi_writeb(hdmi
, HDMI_INTERRUPT_STATUS1
, m_INT_EDID_READY
);
740 for (i
= 0; i
< num
; i
++) {
741 DRM_DEV_DEBUG(hdmi
->dev
,
742 "xfer: num: %d/%d, len: %d, flags: %#x\n",
743 i
+ 1, num
, msgs
[i
].len
, msgs
[i
].flags
);
745 if (msgs
[i
].flags
& I2C_M_RD
)
746 ret
= inno_hdmi_i2c_read(hdmi
, &msgs
[i
]);
748 ret
= inno_hdmi_i2c_write(hdmi
, &msgs
[i
]);
757 /* Mute HDMI EDID interrupt */
758 hdmi_writeb(hdmi
, HDMI_INTERRUPT_MASK1
, 0);
760 mutex_unlock(&i2c
->lock
);
765 static u32
inno_hdmi_i2c_func(struct i2c_adapter
*adapter
)
767 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
770 static const struct i2c_algorithm inno_hdmi_algorithm
= {
771 .master_xfer
= inno_hdmi_i2c_xfer
,
772 .functionality
= inno_hdmi_i2c_func
,
775 static struct i2c_adapter
*inno_hdmi_i2c_adapter(struct inno_hdmi
*hdmi
)
777 struct i2c_adapter
*adap
;
778 struct inno_hdmi_i2c
*i2c
;
781 i2c
= devm_kzalloc(hdmi
->dev
, sizeof(*i2c
), GFP_KERNEL
);
783 return ERR_PTR(-ENOMEM
);
785 mutex_init(&i2c
->lock
);
786 init_completion(&i2c
->cmp
);
789 adap
->class = I2C_CLASS_DDC
;
790 adap
->owner
= THIS_MODULE
;
791 adap
->dev
.parent
= hdmi
->dev
;
792 adap
->dev
.of_node
= hdmi
->dev
->of_node
;
793 adap
->algo
= &inno_hdmi_algorithm
;
794 strlcpy(adap
->name
, "Inno HDMI", sizeof(adap
->name
));
795 i2c_set_adapdata(adap
, hdmi
);
797 ret
= i2c_add_adapter(adap
);
799 dev_warn(hdmi
->dev
, "cannot add %s I2C adapter\n", adap
->name
);
800 devm_kfree(hdmi
->dev
, i2c
);
806 DRM_DEV_INFO(hdmi
->dev
, "registered %s I2C bus driver\n", adap
->name
);
811 static int inno_hdmi_bind(struct device
*dev
, struct device
*master
,
814 struct platform_device
*pdev
= to_platform_device(dev
);
815 struct drm_device
*drm
= data
;
816 struct inno_hdmi
*hdmi
;
817 struct resource
*iores
;
821 hdmi
= devm_kzalloc(dev
, sizeof(*hdmi
), GFP_KERNEL
);
828 iores
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
829 hdmi
->regs
= devm_ioremap_resource(dev
, iores
);
830 if (IS_ERR(hdmi
->regs
))
831 return PTR_ERR(hdmi
->regs
);
833 hdmi
->pclk
= devm_clk_get(hdmi
->dev
, "pclk");
834 if (IS_ERR(hdmi
->pclk
)) {
835 DRM_DEV_ERROR(hdmi
->dev
, "Unable to get HDMI pclk clk\n");
836 return PTR_ERR(hdmi
->pclk
);
839 ret
= clk_prepare_enable(hdmi
->pclk
);
841 DRM_DEV_ERROR(hdmi
->dev
,
842 "Cannot enable HDMI pclk clock: %d\n", ret
);
846 irq
= platform_get_irq(pdev
, 0);
849 goto err_disable_clk
;
852 inno_hdmi_reset(hdmi
);
854 hdmi
->ddc
= inno_hdmi_i2c_adapter(hdmi
);
855 if (IS_ERR(hdmi
->ddc
)) {
856 ret
= PTR_ERR(hdmi
->ddc
);
858 goto err_disable_clk
;
862 * When IP controller haven't configured to an accurate video
863 * timing, then the TMDS clock source would be switched to
864 * PCLK_HDMI, so we need to init the TMDS rate to PCLK rate,
865 * and reconfigure the DDC clock.
867 hdmi
->tmds_rate
= clk_get_rate(hdmi
->pclk
);
868 inno_hdmi_i2c_init(hdmi
);
870 ret
= inno_hdmi_register(drm
, hdmi
);
872 goto err_put_adapter
;
874 dev_set_drvdata(dev
, hdmi
);
876 /* Unmute hotplug interrupt */
877 hdmi_modb(hdmi
, HDMI_STATUS
, m_MASK_INT_HOTPLUG
, v_MASK_INT_HOTPLUG(1));
879 ret
= devm_request_threaded_irq(dev
, irq
, inno_hdmi_hardirq
,
880 inno_hdmi_irq
, IRQF_SHARED
,
881 dev_name(dev
), hdmi
);
883 goto err_cleanup_hdmi
;
887 hdmi
->connector
.funcs
->destroy(&hdmi
->connector
);
888 hdmi
->encoder
.funcs
->destroy(&hdmi
->encoder
);
890 i2c_put_adapter(hdmi
->ddc
);
892 clk_disable_unprepare(hdmi
->pclk
);
896 static void inno_hdmi_unbind(struct device
*dev
, struct device
*master
,
899 struct inno_hdmi
*hdmi
= dev_get_drvdata(dev
);
901 hdmi
->connector
.funcs
->destroy(&hdmi
->connector
);
902 hdmi
->encoder
.funcs
->destroy(&hdmi
->encoder
);
904 i2c_put_adapter(hdmi
->ddc
);
905 clk_disable_unprepare(hdmi
->pclk
);
908 static const struct component_ops inno_hdmi_ops
= {
909 .bind
= inno_hdmi_bind
,
910 .unbind
= inno_hdmi_unbind
,
913 static int inno_hdmi_probe(struct platform_device
*pdev
)
915 return component_add(&pdev
->dev
, &inno_hdmi_ops
);
918 static int inno_hdmi_remove(struct platform_device
*pdev
)
920 component_del(&pdev
->dev
, &inno_hdmi_ops
);
925 static const struct of_device_id inno_hdmi_dt_ids
[] = {
926 { .compatible
= "rockchip,rk3036-inno-hdmi",
930 MODULE_DEVICE_TABLE(of
, inno_hdmi_dt_ids
);
932 struct platform_driver inno_hdmi_driver
= {
933 .probe
= inno_hdmi_probe
,
934 .remove
= inno_hdmi_remove
,
936 .name
= "innohdmi-rockchip",
937 .of_match_table
= inno_hdmi_dt_ids
,