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/mod_devicetable.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/platform_device.h>
18 #include <drm/drm_atomic.h>
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_edid.h>
21 #include <drm/drm_of.h>
22 #include <drm/drm_probe_helper.h>
23 #include <drm/drm_simple_kms_helper.h>
25 #include "rockchip_drm_drv.h"
27 #include "inno_hdmi.h"
29 #define INNO_HDMI_MIN_TMDS_CLOCK 25000000U
31 struct inno_hdmi_phy_config
{
32 unsigned long pixelclock
;
34 u8 voltage_level_control
;
37 struct inno_hdmi_variant
{
38 struct inno_hdmi_phy_config
*phy_configs
;
39 struct inno_hdmi_phy_config
*default_phy_config
;
42 struct inno_hdmi_i2c
{
43 struct i2c_adapter adap
;
49 struct completion cmp
;
59 struct drm_connector connector
;
60 struct rockchip_encoder encoder
;
62 struct inno_hdmi_i2c
*i2c
;
63 struct i2c_adapter
*ddc
;
65 const struct inno_hdmi_variant
*variant
;
68 struct inno_hdmi_connector_state
{
69 struct drm_connector_state base
;
70 unsigned int enc_out_format
;
71 unsigned int colorimetry
;
72 bool rgb_limited_range
;
75 static struct inno_hdmi
*encoder_to_inno_hdmi(struct drm_encoder
*encoder
)
77 struct rockchip_encoder
*rkencoder
= to_rockchip_encoder(encoder
);
79 return container_of(rkencoder
, struct inno_hdmi
, encoder
);
82 static struct inno_hdmi
*connector_to_inno_hdmi(struct drm_connector
*connector
)
84 return container_of(connector
, struct inno_hdmi
, connector
);
87 #define to_inno_hdmi_conn_state(conn_state) \
88 container_of_const(conn_state, struct inno_hdmi_connector_state, base)
91 CSC_RGB_0_255_TO_ITU601_16_235_8BIT
,
92 CSC_RGB_0_255_TO_ITU709_16_235_8BIT
,
93 CSC_RGB_0_255_TO_RGB_16_235_8BIT
,
96 static const char coeff_csc
[][24] = {
98 * RGB2YUV:601 SD mode:
99 * Cb = -0.291G - 0.148R + 0.439B + 128
100 * Y = 0.504G + 0.257R + 0.098B + 16
101 * Cr = -0.368G + 0.439R - 0.071B + 128
104 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
105 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
106 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
109 * RGB2YUV:709 HD mode:
110 * Cb = - 0.338G - 0.101R + 0.439B + 128
111 * Y = 0.614G + 0.183R + 0.062B + 16
112 * Cr = - 0.399G + 0.439R - 0.040B + 128
115 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
116 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
117 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
120 * RGB[0:255]2RGB[16:235]:
121 * R' = R x (235-16)/255 + 16;
122 * G' = G x (235-16)/255 + 16;
123 * B' = B x (235-16)/255 + 16;
126 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
127 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
128 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10
132 static struct inno_hdmi_phy_config rk3036_hdmi_phy_configs
[] = {
133 { 74250000, 0x3f, 0xbb },
134 { 165000000, 0x6f, 0xbb },
138 static struct inno_hdmi_phy_config rk3128_hdmi_phy_configs
[] = {
139 { 74250000, 0x3f, 0xaa },
140 { 165000000, 0x5f, 0xaa },
144 static int inno_hdmi_find_phy_config(struct inno_hdmi
*hdmi
,
145 unsigned long pixelclk
)
147 const struct inno_hdmi_phy_config
*phy_configs
=
148 hdmi
->variant
->phy_configs
;
151 for (i
= 0; phy_configs
[i
].pixelclock
!= ~0UL; i
++) {
152 if (pixelclk
<= phy_configs
[i
].pixelclock
)
156 DRM_DEV_DEBUG(hdmi
->dev
, "No phy configuration for pixelclock %lu\n",
162 static inline u8
hdmi_readb(struct inno_hdmi
*hdmi
, u16 offset
)
164 return readl_relaxed(hdmi
->regs
+ (offset
) * 0x04);
167 static inline void hdmi_writeb(struct inno_hdmi
*hdmi
, u16 offset
, u32 val
)
169 writel_relaxed(val
, hdmi
->regs
+ (offset
) * 0x04);
172 static inline void hdmi_modb(struct inno_hdmi
*hdmi
, u16 offset
,
175 u8 temp
= hdmi_readb(hdmi
, offset
) & ~msk
;
178 hdmi_writeb(hdmi
, offset
, temp
);
181 static void inno_hdmi_i2c_init(struct inno_hdmi
*hdmi
, unsigned long long rate
)
183 unsigned long long ddc_bus_freq
= rate
>> 2;
185 do_div(ddc_bus_freq
, HDMI_SCL_RATE
);
187 hdmi_writeb(hdmi
, DDC_BUS_FREQ_L
, ddc_bus_freq
& 0xFF);
188 hdmi_writeb(hdmi
, DDC_BUS_FREQ_H
, (ddc_bus_freq
>> 8) & 0xFF);
190 /* Clear the EDID interrupt flag and mute the interrupt */
191 hdmi_writeb(hdmi
, HDMI_INTERRUPT_MASK1
, 0);
192 hdmi_writeb(hdmi
, HDMI_INTERRUPT_STATUS1
, m_INT_EDID_READY
);
195 static void inno_hdmi_sys_power(struct inno_hdmi
*hdmi
, bool enable
)
198 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, m_POWER
, v_PWR_ON
);
200 hdmi_modb(hdmi
, HDMI_SYS_CTRL
, m_POWER
, v_PWR_OFF
);
203 static void inno_hdmi_standby(struct inno_hdmi
*hdmi
)
205 inno_hdmi_sys_power(hdmi
, false);
207 hdmi_writeb(hdmi
, HDMI_PHY_DRIVER
, 0x00);
208 hdmi_writeb(hdmi
, HDMI_PHY_PRE_EMPHASIS
, 0x00);
209 hdmi_writeb(hdmi
, HDMI_PHY_CHG_PWR
, 0x00);
210 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x15);
213 static void inno_hdmi_power_up(struct inno_hdmi
*hdmi
,
214 unsigned long mpixelclock
)
216 struct inno_hdmi_phy_config
*phy_config
;
217 int ret
= inno_hdmi_find_phy_config(hdmi
, mpixelclock
);
220 phy_config
= hdmi
->variant
->default_phy_config
;
221 DRM_DEV_ERROR(hdmi
->dev
,
222 "Using default phy configuration for TMDS rate %lu",
225 phy_config
= &hdmi
->variant
->phy_configs
[ret
];
228 inno_hdmi_sys_power(hdmi
, false);
230 hdmi_writeb(hdmi
, HDMI_PHY_PRE_EMPHASIS
, phy_config
->pre_emphasis
);
231 hdmi_writeb(hdmi
, HDMI_PHY_DRIVER
, phy_config
->voltage_level_control
);
232 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x15);
233 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x14);
234 hdmi_writeb(hdmi
, HDMI_PHY_SYS_CTL
, 0x10);
235 hdmi_writeb(hdmi
, HDMI_PHY_CHG_PWR
, 0x0f);
236 hdmi_writeb(hdmi
, HDMI_PHY_SYNC
, 0x00);
237 hdmi_writeb(hdmi
, HDMI_PHY_SYNC
, 0x01);
239 inno_hdmi_sys_power(hdmi
, true);
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_standby(hdmi
);
260 static void inno_hdmi_disable_frame(struct inno_hdmi
*hdmi
,
261 enum hdmi_infoframe_type type
)
263 struct drm_connector
*connector
= &hdmi
->connector
;
265 if (type
!= HDMI_INFOFRAME_TYPE_AVI
) {
266 drm_err(connector
->dev
,
267 "Unsupported infoframe type: %u\n", type
);
271 hdmi_writeb(hdmi
, HDMI_CONTROL_PACKET_BUF_INDEX
, INFOFRAME_AVI
);
274 static int inno_hdmi_upload_frame(struct inno_hdmi
*hdmi
,
275 union hdmi_infoframe
*frame
, enum hdmi_infoframe_type type
)
277 struct drm_connector
*connector
= &hdmi
->connector
;
278 u8 packed_frame
[HDMI_MAXIMUM_INFO_FRAME_SIZE
];
281 if (type
!= HDMI_INFOFRAME_TYPE_AVI
) {
282 drm_err(connector
->dev
,
283 "Unsupported infoframe type: %u\n", type
);
287 inno_hdmi_disable_frame(hdmi
, type
);
289 rc
= hdmi_infoframe_pack(frame
, packed_frame
,
290 sizeof(packed_frame
));
294 for (i
= 0; i
< rc
; i
++)
295 hdmi_writeb(hdmi
, HDMI_CONTROL_PACKET_ADDR
+ i
,
301 static int inno_hdmi_config_video_avi(struct inno_hdmi
*hdmi
,
302 struct drm_display_mode
*mode
)
304 struct drm_connector
*connector
= &hdmi
->connector
;
305 struct drm_connector_state
*conn_state
= connector
->state
;
306 struct inno_hdmi_connector_state
*inno_conn_state
=
307 to_inno_hdmi_conn_state(conn_state
);
308 union hdmi_infoframe frame
;
311 rc
= drm_hdmi_avi_infoframe_from_display_mode(&frame
.avi
,
315 inno_hdmi_disable_frame(hdmi
, HDMI_INFOFRAME_TYPE_AVI
);
319 if (inno_conn_state
->enc_out_format
== HDMI_COLORSPACE_YUV444
)
320 frame
.avi
.colorspace
= HDMI_COLORSPACE_YUV444
;
321 else if (inno_conn_state
->enc_out_format
== HDMI_COLORSPACE_YUV422
)
322 frame
.avi
.colorspace
= HDMI_COLORSPACE_YUV422
;
324 frame
.avi
.colorspace
= HDMI_COLORSPACE_RGB
;
326 if (inno_conn_state
->enc_out_format
== HDMI_COLORSPACE_RGB
) {
327 drm_hdmi_avi_infoframe_quant_range(&frame
.avi
,
329 inno_conn_state
->rgb_limited_range
?
330 HDMI_QUANTIZATION_RANGE_LIMITED
:
331 HDMI_QUANTIZATION_RANGE_FULL
);
333 frame
.avi
.quantization_range
= HDMI_QUANTIZATION_RANGE_DEFAULT
;
334 frame
.avi
.ycc_quantization_range
=
335 HDMI_YCC_QUANTIZATION_RANGE_LIMITED
;
338 return inno_hdmi_upload_frame(hdmi
, &frame
, HDMI_INFOFRAME_TYPE_AVI
);
341 static int inno_hdmi_config_video_csc(struct inno_hdmi
*hdmi
)
343 struct drm_connector
*connector
= &hdmi
->connector
;
344 struct drm_connector_state
*conn_state
= connector
->state
;
345 struct inno_hdmi_connector_state
*inno_conn_state
=
346 to_inno_hdmi_conn_state(conn_state
);
347 int c0_c2_change
= 0;
354 /* Input video mode is SDR RGB24bit, data enable signal from external */
355 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL1
, v_DE_EXTERNAL
|
356 v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444
));
358 /* Input color hardcode to RGB, and output color hardcode to RGB888 */
359 value
= v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS
) |
360 v_VIDEO_OUTPUT_COLOR(0) |
361 v_VIDEO_INPUT_CSP(0);
362 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL2
, value
);
364 if (inno_conn_state
->enc_out_format
== HDMI_COLORSPACE_RGB
) {
365 if (inno_conn_state
->rgb_limited_range
) {
366 csc_mode
= CSC_RGB_0_255_TO_RGB_16_235_8BIT
;
367 auto_csc
= AUTO_CSC_DISABLE
;
368 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
369 csc_enable
= v_CSC_ENABLE
;
372 value
= v_SOF_DISABLE
| v_COLOR_DEPTH_NOT_INDICATED(1);
373 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL3
, value
);
375 hdmi_modb(hdmi
, HDMI_VIDEO_CONTRL
,
376 m_VIDEO_AUTO_CSC
| m_VIDEO_C0_C2_SWAP
,
377 v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE
) |
378 v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE
));
382 if (inno_conn_state
->colorimetry
== HDMI_COLORIMETRY_ITU_601
) {
383 if (inno_conn_state
->enc_out_format
== HDMI_COLORSPACE_YUV444
) {
384 csc_mode
= CSC_RGB_0_255_TO_ITU601_16_235_8BIT
;
385 auto_csc
= AUTO_CSC_DISABLE
;
386 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
387 csc_enable
= v_CSC_ENABLE
;
390 if (inno_conn_state
->enc_out_format
== HDMI_COLORSPACE_YUV444
) {
391 csc_mode
= CSC_RGB_0_255_TO_ITU709_16_235_8BIT
;
392 auto_csc
= AUTO_CSC_DISABLE
;
393 c0_c2_change
= C0_C2_CHANGE_DISABLE
;
394 csc_enable
= v_CSC_ENABLE
;
399 for (i
= 0; i
< 24; i
++)
400 hdmi_writeb(hdmi
, HDMI_VIDEO_CSC_COEF
+ i
,
401 coeff_csc
[csc_mode
][i
]);
403 value
= v_SOF_DISABLE
| csc_enable
| v_COLOR_DEPTH_NOT_INDICATED(1);
404 hdmi_writeb(hdmi
, HDMI_VIDEO_CONTRL3
, value
);
405 hdmi_modb(hdmi
, HDMI_VIDEO_CONTRL
, m_VIDEO_AUTO_CSC
|
406 m_VIDEO_C0_C2_SWAP
, v_VIDEO_AUTO_CSC(auto_csc
) |
407 v_VIDEO_C0_C2_SWAP(c0_c2_change
));
412 static int inno_hdmi_config_video_timing(struct inno_hdmi
*hdmi
,
413 struct drm_display_mode
*mode
)
417 /* Set detail external video timing polarity and interlace mode */
418 value
= v_EXTERANL_VIDEO(1);
419 value
|= mode
->flags
& DRM_MODE_FLAG_PHSYNC
?
420 v_HSYNC_POLARITY(1) : v_HSYNC_POLARITY(0);
421 value
|= mode
->flags
& DRM_MODE_FLAG_PVSYNC
?
422 v_VSYNC_POLARITY(1) : v_VSYNC_POLARITY(0);
423 value
|= mode
->flags
& DRM_MODE_FLAG_INTERLACE
?
424 v_INETLACE(1) : v_INETLACE(0);
425 hdmi_writeb(hdmi
, HDMI_VIDEO_TIMING_CTL
, value
);
427 /* Set detail external video timing */
428 value
= mode
->htotal
;
429 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HTOTAL_L
, value
& 0xFF);
430 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HTOTAL_H
, (value
>> 8) & 0xFF);
432 value
= mode
->htotal
- mode
->hdisplay
;
433 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HBLANK_L
, value
& 0xFF);
434 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HBLANK_H
, (value
>> 8) & 0xFF);
436 value
= mode
->htotal
- mode
->hsync_start
;
437 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDELAY_L
, value
& 0xFF);
438 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDELAY_H
, (value
>> 8) & 0xFF);
440 value
= mode
->hsync_end
- mode
->hsync_start
;
441 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDURATION_L
, value
& 0xFF);
442 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_HDURATION_H
, (value
>> 8) & 0xFF);
444 value
= mode
->vtotal
;
445 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VTOTAL_L
, value
& 0xFF);
446 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VTOTAL_H
, (value
>> 8) & 0xFF);
448 value
= mode
->vtotal
- mode
->vdisplay
;
449 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VBLANK
, value
& 0xFF);
451 value
= mode
->vtotal
- mode
->vsync_start
;
452 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VDELAY
, value
& 0xFF);
454 value
= mode
->vsync_end
- mode
->vsync_start
;
455 hdmi_writeb(hdmi
, HDMI_VIDEO_EXT_VDURATION
, value
& 0xFF);
457 hdmi_writeb(hdmi
, HDMI_PHY_PRE_DIV_RATIO
, 0x1e);
458 hdmi_writeb(hdmi
, HDMI_PHY_FEEDBACK_DIV_RATIO_LOW
, 0x2c);
459 hdmi_writeb(hdmi
, HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH
, 0x01);
464 static int inno_hdmi_setup(struct inno_hdmi
*hdmi
,
465 struct drm_display_mode
*mode
)
467 struct drm_display_info
*display
= &hdmi
->connector
.display_info
;
468 unsigned long mpixelclock
= mode
->clock
* 1000;
470 /* Mute video and audio output */
471 hdmi_modb(hdmi
, HDMI_AV_MUTE
, m_AUDIO_MUTE
| m_VIDEO_BLACK
,
472 v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
475 hdmi_writeb(hdmi
, HDMI_HDCP_CTRL
,
476 v_HDMI_DVI(display
->is_hdmi
));
478 inno_hdmi_config_video_timing(hdmi
, mode
);
480 inno_hdmi_config_video_csc(hdmi
);
482 if (display
->is_hdmi
)
483 inno_hdmi_config_video_avi(hdmi
, mode
);
486 * When IP controller have configured to an accurate video
487 * timing, then the TMDS clock source would be switched to
488 * DCLK_LCDC, so we need to init the TMDS rate to mode pixel
489 * clock rate, and reconfigure the DDC clock.
491 inno_hdmi_i2c_init(hdmi
, mpixelclock
);
493 /* Unmute video and audio output */
494 hdmi_modb(hdmi
, HDMI_AV_MUTE
, m_AUDIO_MUTE
| m_VIDEO_BLACK
,
495 v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
497 inno_hdmi_power_up(hdmi
, mpixelclock
);
502 static enum drm_mode_status
inno_hdmi_display_mode_valid(struct inno_hdmi
*hdmi
,
503 struct drm_display_mode
*mode
)
505 unsigned long mpixelclk
, max_tolerance
;
508 /* No support for double-clock modes */
509 if (mode
->flags
& DRM_MODE_FLAG_DBLCLK
)
512 mpixelclk
= mode
->clock
* 1000;
514 if (mpixelclk
< INNO_HDMI_MIN_TMDS_CLOCK
)
515 return MODE_CLOCK_LOW
;
517 if (inno_hdmi_find_phy_config(hdmi
, mpixelclk
) < 0)
518 return MODE_CLOCK_HIGH
;
521 rounded_refclk
= clk_round_rate(hdmi
->refclk
, mpixelclk
);
522 if (rounded_refclk
< 0)
525 /* Vesa DMT standard mentions +/- 0.5% max tolerance */
526 max_tolerance
= mpixelclk
/ 200;
527 if (abs_diff((unsigned long)rounded_refclk
, mpixelclk
) > max_tolerance
)
534 static void inno_hdmi_encoder_enable(struct drm_encoder
*encoder
,
535 struct drm_atomic_state
*state
)
537 struct inno_hdmi
*hdmi
= encoder_to_inno_hdmi(encoder
);
538 struct drm_connector_state
*conn_state
;
539 struct drm_crtc_state
*crtc_state
;
541 conn_state
= drm_atomic_get_new_connector_state(state
, &hdmi
->connector
);
542 if (WARN_ON(!conn_state
))
545 crtc_state
= drm_atomic_get_new_crtc_state(state
, conn_state
->crtc
);
546 if (WARN_ON(!crtc_state
))
549 inno_hdmi_setup(hdmi
, &crtc_state
->adjusted_mode
);
552 static void inno_hdmi_encoder_disable(struct drm_encoder
*encoder
,
553 struct drm_atomic_state
*state
)
555 struct inno_hdmi
*hdmi
= encoder_to_inno_hdmi(encoder
);
557 inno_hdmi_standby(hdmi
);
561 inno_hdmi_encoder_atomic_check(struct drm_encoder
*encoder
,
562 struct drm_crtc_state
*crtc_state
,
563 struct drm_connector_state
*conn_state
)
565 struct rockchip_crtc_state
*s
= to_rockchip_crtc_state(crtc_state
);
566 struct inno_hdmi
*hdmi
= encoder_to_inno_hdmi(encoder
);
567 struct drm_display_mode
*mode
= &crtc_state
->adjusted_mode
;
568 u8 vic
= drm_match_cea_mode(mode
);
569 struct inno_hdmi_connector_state
*inno_conn_state
=
570 to_inno_hdmi_conn_state(conn_state
);
572 s
->output_mode
= ROCKCHIP_OUT_MODE_P888
;
573 s
->output_type
= DRM_MODE_CONNECTOR_HDMIA
;
575 if (vic
== 6 || vic
== 7 ||
576 vic
== 21 || vic
== 22 ||
577 vic
== 2 || vic
== 3 ||
578 vic
== 17 || vic
== 18)
579 inno_conn_state
->colorimetry
= HDMI_COLORIMETRY_ITU_601
;
581 inno_conn_state
->colorimetry
= HDMI_COLORIMETRY_ITU_709
;
583 inno_conn_state
->enc_out_format
= HDMI_COLORSPACE_RGB
;
584 inno_conn_state
->rgb_limited_range
=
585 drm_default_rgb_quant_range(mode
) == HDMI_QUANTIZATION_RANGE_LIMITED
;
587 return inno_hdmi_display_mode_valid(hdmi
,
588 &crtc_state
->adjusted_mode
) == MODE_OK
? 0 : -EINVAL
;
591 static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs
= {
592 .atomic_check
= inno_hdmi_encoder_atomic_check
,
593 .atomic_enable
= inno_hdmi_encoder_enable
,
594 .atomic_disable
= inno_hdmi_encoder_disable
,
597 static enum drm_connector_status
598 inno_hdmi_connector_detect(struct drm_connector
*connector
, bool force
)
600 struct inno_hdmi
*hdmi
= connector_to_inno_hdmi(connector
);
602 return (hdmi_readb(hdmi
, HDMI_STATUS
) & m_HOTPLUG
) ?
603 connector_status_connected
: connector_status_disconnected
;
606 static int inno_hdmi_connector_get_modes(struct drm_connector
*connector
)
608 struct inno_hdmi
*hdmi
= connector_to_inno_hdmi(connector
);
615 edid
= drm_get_edid(connector
, hdmi
->ddc
);
617 drm_connector_update_edid_property(connector
, edid
);
618 ret
= drm_add_edid_modes(connector
, edid
);
625 static enum drm_mode_status
626 inno_hdmi_connector_mode_valid(struct drm_connector
*connector
,
627 struct drm_display_mode
*mode
)
629 struct inno_hdmi
*hdmi
= connector_to_inno_hdmi(connector
);
631 return inno_hdmi_display_mode_valid(hdmi
, mode
);
634 static void inno_hdmi_connector_destroy(struct drm_connector
*connector
)
636 drm_connector_unregister(connector
);
637 drm_connector_cleanup(connector
);
641 inno_hdmi_connector_destroy_state(struct drm_connector
*connector
,
642 struct drm_connector_state
*state
)
644 struct inno_hdmi_connector_state
*inno_conn_state
=
645 to_inno_hdmi_conn_state(state
);
647 __drm_atomic_helper_connector_destroy_state(&inno_conn_state
->base
);
648 kfree(inno_conn_state
);
651 static void inno_hdmi_connector_reset(struct drm_connector
*connector
)
653 struct inno_hdmi_connector_state
*inno_conn_state
;
655 if (connector
->state
) {
656 inno_hdmi_connector_destroy_state(connector
, connector
->state
);
657 connector
->state
= NULL
;
660 inno_conn_state
= kzalloc(sizeof(*inno_conn_state
), GFP_KERNEL
);
661 if (!inno_conn_state
)
664 __drm_atomic_helper_connector_reset(connector
, &inno_conn_state
->base
);
666 inno_conn_state
->colorimetry
= HDMI_COLORIMETRY_ITU_709
;
667 inno_conn_state
->enc_out_format
= HDMI_COLORSPACE_RGB
;
668 inno_conn_state
->rgb_limited_range
= false;
671 static struct drm_connector_state
*
672 inno_hdmi_connector_duplicate_state(struct drm_connector
*connector
)
674 struct inno_hdmi_connector_state
*inno_conn_state
;
676 if (WARN_ON(!connector
->state
))
679 inno_conn_state
= kmemdup(to_inno_hdmi_conn_state(connector
->state
),
680 sizeof(*inno_conn_state
), GFP_KERNEL
);
682 if (!inno_conn_state
)
685 __drm_atomic_helper_connector_duplicate_state(connector
,
686 &inno_conn_state
->base
);
688 return &inno_conn_state
->base
;
691 static const struct drm_connector_funcs inno_hdmi_connector_funcs
= {
692 .fill_modes
= drm_helper_probe_single_connector_modes
,
693 .detect
= inno_hdmi_connector_detect
,
694 .destroy
= inno_hdmi_connector_destroy
,
695 .reset
= inno_hdmi_connector_reset
,
696 .atomic_duplicate_state
= inno_hdmi_connector_duplicate_state
,
697 .atomic_destroy_state
= inno_hdmi_connector_destroy_state
,
700 static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs
= {
701 .get_modes
= inno_hdmi_connector_get_modes
,
702 .mode_valid
= inno_hdmi_connector_mode_valid
,
705 static int inno_hdmi_register(struct drm_device
*drm
, struct inno_hdmi
*hdmi
)
707 struct drm_encoder
*encoder
= &hdmi
->encoder
.encoder
;
708 struct device
*dev
= hdmi
->dev
;
710 encoder
->possible_crtcs
= drm_of_find_possible_crtcs(drm
, dev
->of_node
);
713 * If we failed to find the CRTC(s) which this encoder is
714 * supposed to be connected to, it's because the CRTC has
715 * not been registered yet. Defer probing, and hope that
716 * the required CRTC is added later.
718 if (encoder
->possible_crtcs
== 0)
719 return -EPROBE_DEFER
;
721 drm_encoder_helper_add(encoder
, &inno_hdmi_encoder_helper_funcs
);
722 drm_simple_encoder_init(drm
, encoder
, DRM_MODE_ENCODER_TMDS
);
724 hdmi
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
726 drm_connector_helper_add(&hdmi
->connector
,
727 &inno_hdmi_connector_helper_funcs
);
728 drm_connector_init_with_ddc(drm
, &hdmi
->connector
,
729 &inno_hdmi_connector_funcs
,
730 DRM_MODE_CONNECTOR_HDMIA
,
733 drm_connector_attach_encoder(&hdmi
->connector
, encoder
);
738 static irqreturn_t
inno_hdmi_i2c_irq(struct inno_hdmi
*hdmi
)
740 struct inno_hdmi_i2c
*i2c
= hdmi
->i2c
;
743 stat
= hdmi_readb(hdmi
, HDMI_INTERRUPT_STATUS1
);
744 if (!(stat
& m_INT_EDID_READY
))
747 /* Clear HDMI EDID interrupt flag */
748 hdmi_writeb(hdmi
, HDMI_INTERRUPT_STATUS1
, m_INT_EDID_READY
);
755 static irqreturn_t
inno_hdmi_hardirq(int irq
, void *dev_id
)
757 struct inno_hdmi
*hdmi
= dev_id
;
758 irqreturn_t ret
= IRQ_NONE
;
762 ret
= inno_hdmi_i2c_irq(hdmi
);
764 interrupt
= hdmi_readb(hdmi
, HDMI_STATUS
);
765 if (interrupt
& m_INT_HOTPLUG
) {
766 hdmi_modb(hdmi
, HDMI_STATUS
, m_INT_HOTPLUG
, m_INT_HOTPLUG
);
767 ret
= IRQ_WAKE_THREAD
;
773 static irqreturn_t
inno_hdmi_irq(int irq
, void *dev_id
)
775 struct inno_hdmi
*hdmi
= dev_id
;
777 drm_helper_hpd_irq_event(hdmi
->connector
.dev
);
782 static int inno_hdmi_i2c_read(struct inno_hdmi
*hdmi
, struct i2c_msg
*msgs
)
784 int length
= msgs
->len
;
788 ret
= wait_for_completion_timeout(&hdmi
->i2c
->cmp
, HZ
/ 10);
793 *buf
++ = hdmi_readb(hdmi
, HDMI_EDID_FIFO_ADDR
);
798 static int inno_hdmi_i2c_write(struct inno_hdmi
*hdmi
, struct i2c_msg
*msgs
)
801 * The DDC module only support read EDID message, so
802 * we assume that each word write to this i2c adapter
803 * should be the offset of EDID word address.
805 if ((msgs
->len
!= 1) ||
806 ((msgs
->addr
!= DDC_ADDR
) && (msgs
->addr
!= DDC_SEGMENT_ADDR
)))
809 reinit_completion(&hdmi
->i2c
->cmp
);
811 if (msgs
->addr
== DDC_SEGMENT_ADDR
)
812 hdmi
->i2c
->segment_addr
= msgs
->buf
[0];
813 if (msgs
->addr
== DDC_ADDR
)
814 hdmi
->i2c
->ddc_addr
= msgs
->buf
[0];
816 /* Set edid fifo first addr */
817 hdmi_writeb(hdmi
, HDMI_EDID_FIFO_OFFSET
, 0x00);
819 /* Set edid word address 0x00/0x80 */
820 hdmi_writeb(hdmi
, HDMI_EDID_WORD_ADDR
, hdmi
->i2c
->ddc_addr
);
822 /* Set edid segment pointer */
823 hdmi_writeb(hdmi
, HDMI_EDID_SEGMENT_POINTER
, hdmi
->i2c
->segment_addr
);
828 static int inno_hdmi_i2c_xfer(struct i2c_adapter
*adap
,
829 struct i2c_msg
*msgs
, int num
)
831 struct inno_hdmi
*hdmi
= i2c_get_adapdata(adap
);
832 struct inno_hdmi_i2c
*i2c
= hdmi
->i2c
;
835 mutex_lock(&i2c
->lock
);
837 /* Clear the EDID interrupt flag and unmute the interrupt */
838 hdmi_writeb(hdmi
, HDMI_INTERRUPT_MASK1
, m_INT_EDID_READY
);
839 hdmi_writeb(hdmi
, HDMI_INTERRUPT_STATUS1
, m_INT_EDID_READY
);
841 for (i
= 0; i
< num
; i
++) {
842 DRM_DEV_DEBUG(hdmi
->dev
,
843 "xfer: num: %d/%d, len: %d, flags: %#x\n",
844 i
+ 1, num
, msgs
[i
].len
, msgs
[i
].flags
);
846 if (msgs
[i
].flags
& I2C_M_RD
)
847 ret
= inno_hdmi_i2c_read(hdmi
, &msgs
[i
]);
849 ret
= inno_hdmi_i2c_write(hdmi
, &msgs
[i
]);
858 /* Mute HDMI EDID interrupt */
859 hdmi_writeb(hdmi
, HDMI_INTERRUPT_MASK1
, 0);
861 mutex_unlock(&i2c
->lock
);
866 static u32
inno_hdmi_i2c_func(struct i2c_adapter
*adapter
)
868 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
871 static const struct i2c_algorithm inno_hdmi_algorithm
= {
872 .master_xfer
= inno_hdmi_i2c_xfer
,
873 .functionality
= inno_hdmi_i2c_func
,
876 static struct i2c_adapter
*inno_hdmi_i2c_adapter(struct inno_hdmi
*hdmi
)
878 struct i2c_adapter
*adap
;
879 struct inno_hdmi_i2c
*i2c
;
882 i2c
= devm_kzalloc(hdmi
->dev
, sizeof(*i2c
), GFP_KERNEL
);
884 return ERR_PTR(-ENOMEM
);
886 mutex_init(&i2c
->lock
);
887 init_completion(&i2c
->cmp
);
890 adap
->owner
= THIS_MODULE
;
891 adap
->dev
.parent
= hdmi
->dev
;
892 adap
->dev
.of_node
= hdmi
->dev
->of_node
;
893 adap
->algo
= &inno_hdmi_algorithm
;
894 strscpy(adap
->name
, "Inno HDMI", sizeof(adap
->name
));
895 i2c_set_adapdata(adap
, hdmi
);
897 ret
= i2c_add_adapter(adap
);
899 dev_warn(hdmi
->dev
, "cannot add %s I2C adapter\n", adap
->name
);
900 devm_kfree(hdmi
->dev
, i2c
);
906 DRM_DEV_INFO(hdmi
->dev
, "registered %s I2C bus driver\n", adap
->name
);
911 static int inno_hdmi_bind(struct device
*dev
, struct device
*master
,
914 struct platform_device
*pdev
= to_platform_device(dev
);
915 struct drm_device
*drm
= data
;
916 struct inno_hdmi
*hdmi
;
917 const struct inno_hdmi_variant
*variant
;
921 hdmi
= devm_kzalloc(dev
, sizeof(*hdmi
), GFP_KERNEL
);
927 variant
= of_device_get_match_data(hdmi
->dev
);
931 hdmi
->variant
= variant
;
933 hdmi
->regs
= devm_platform_ioremap_resource(pdev
, 0);
934 if (IS_ERR(hdmi
->regs
))
935 return PTR_ERR(hdmi
->regs
);
937 hdmi
->pclk
= devm_clk_get(hdmi
->dev
, "pclk");
938 if (IS_ERR(hdmi
->pclk
)) {
939 DRM_DEV_ERROR(hdmi
->dev
, "Unable to get HDMI pclk clk\n");
940 return PTR_ERR(hdmi
->pclk
);
943 ret
= clk_prepare_enable(hdmi
->pclk
);
945 DRM_DEV_ERROR(hdmi
->dev
,
946 "Cannot enable HDMI pclk clock: %d\n", ret
);
950 hdmi
->refclk
= devm_clk_get_optional(hdmi
->dev
, "ref");
951 if (IS_ERR(hdmi
->refclk
)) {
952 DRM_DEV_ERROR(hdmi
->dev
, "Unable to get HDMI reference clock\n");
953 ret
= PTR_ERR(hdmi
->refclk
);
954 goto err_disable_pclk
;
957 ret
= clk_prepare_enable(hdmi
->refclk
);
959 DRM_DEV_ERROR(hdmi
->dev
,
960 "Cannot enable HDMI reference clock: %d\n", ret
);
961 goto err_disable_pclk
;
964 irq
= platform_get_irq(pdev
, 0);
967 goto err_disable_clk
;
970 inno_hdmi_reset(hdmi
);
972 hdmi
->ddc
= inno_hdmi_i2c_adapter(hdmi
);
973 if (IS_ERR(hdmi
->ddc
)) {
974 ret
= PTR_ERR(hdmi
->ddc
);
976 goto err_disable_clk
;
980 * When the controller isn't configured to an accurate
981 * video timing and there is no reference clock available,
982 * then the TMDS clock source would be switched to PCLK_HDMI,
983 * so we need to init the TMDS rate to PCLK rate, and
984 * reconfigure the DDC clock.
987 inno_hdmi_i2c_init(hdmi
, clk_get_rate(hdmi
->refclk
));
989 inno_hdmi_i2c_init(hdmi
, clk_get_rate(hdmi
->pclk
));
991 ret
= inno_hdmi_register(drm
, hdmi
);
993 goto err_put_adapter
;
995 dev_set_drvdata(dev
, hdmi
);
997 /* Unmute hotplug interrupt */
998 hdmi_modb(hdmi
, HDMI_STATUS
, m_MASK_INT_HOTPLUG
, v_MASK_INT_HOTPLUG(1));
1000 ret
= devm_request_threaded_irq(dev
, irq
, inno_hdmi_hardirq
,
1001 inno_hdmi_irq
, IRQF_SHARED
,
1002 dev_name(dev
), hdmi
);
1004 goto err_cleanup_hdmi
;
1008 hdmi
->connector
.funcs
->destroy(&hdmi
->connector
);
1009 hdmi
->encoder
.encoder
.funcs
->destroy(&hdmi
->encoder
.encoder
);
1011 i2c_put_adapter(hdmi
->ddc
);
1013 clk_disable_unprepare(hdmi
->refclk
);
1015 clk_disable_unprepare(hdmi
->pclk
);
1019 static void inno_hdmi_unbind(struct device
*dev
, struct device
*master
,
1022 struct inno_hdmi
*hdmi
= dev_get_drvdata(dev
);
1024 hdmi
->connector
.funcs
->destroy(&hdmi
->connector
);
1025 hdmi
->encoder
.encoder
.funcs
->destroy(&hdmi
->encoder
.encoder
);
1027 i2c_put_adapter(hdmi
->ddc
);
1028 clk_disable_unprepare(hdmi
->refclk
);
1029 clk_disable_unprepare(hdmi
->pclk
);
1032 static const struct component_ops inno_hdmi_ops
= {
1033 .bind
= inno_hdmi_bind
,
1034 .unbind
= inno_hdmi_unbind
,
1037 static int inno_hdmi_probe(struct platform_device
*pdev
)
1039 return component_add(&pdev
->dev
, &inno_hdmi_ops
);
1042 static void inno_hdmi_remove(struct platform_device
*pdev
)
1044 component_del(&pdev
->dev
, &inno_hdmi_ops
);
1047 static const struct inno_hdmi_variant rk3036_inno_hdmi_variant
= {
1048 .phy_configs
= rk3036_hdmi_phy_configs
,
1049 .default_phy_config
= &rk3036_hdmi_phy_configs
[1],
1052 static const struct inno_hdmi_variant rk3128_inno_hdmi_variant
= {
1053 .phy_configs
= rk3128_hdmi_phy_configs
,
1054 .default_phy_config
= &rk3128_hdmi_phy_configs
[1],
1057 static const struct of_device_id inno_hdmi_dt_ids
[] = {
1058 { .compatible
= "rockchip,rk3036-inno-hdmi",
1059 .data
= &rk3036_inno_hdmi_variant
,
1061 { .compatible
= "rockchip,rk3128-inno-hdmi",
1062 .data
= &rk3128_inno_hdmi_variant
,
1066 MODULE_DEVICE_TABLE(of
, inno_hdmi_dt_ids
);
1068 struct platform_driver inno_hdmi_driver
= {
1069 .probe
= inno_hdmi_probe
,
1070 .remove_new
= inno_hdmi_remove
,
1072 .name
= "innohdmi-rockchip",
1073 .of_match_table
= inno_hdmi_dt_ids
,