mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
drm/rockchip: inno_hdmi: Correctly setup HDMI quantization range
The display controller will always give full range RGB regardless of the mode set, but HDMI requires certain modes to be transmitted in limited range RGB. This is especially required for HDMI sinks which do not support non-standard quantization ranges. This enables color space conversion for those modes and sets the quantization range accordingly in the AVI infoframe. Signed-off-by: Alex Bee <knaerzche@gmail.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20231222174220.55249-21-knaerzche@gmail.com
This commit is contained in:
parent
ceeb0f0104
commit
164abbd2b7
@ -52,6 +52,7 @@ struct inno_hdmi_connector_state {
|
||||
struct drm_connector_state base;
|
||||
unsigned int enc_out_format;
|
||||
unsigned int colorimetry;
|
||||
bool rgb_limited_range;
|
||||
};
|
||||
|
||||
static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
|
||||
@ -269,6 +270,18 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
|
||||
else
|
||||
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
|
||||
|
||||
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
|
||||
drm_hdmi_avi_infoframe_quant_range(&frame.avi,
|
||||
connector, mode,
|
||||
inno_conn_state->rgb_limited_range ?
|
||||
HDMI_QUANTIZATION_RANGE_LIMITED :
|
||||
HDMI_QUANTIZATION_RANGE_FULL);
|
||||
} else {
|
||||
frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
|
||||
frame.avi.ycc_quantization_range =
|
||||
HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
|
||||
}
|
||||
|
||||
return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
|
||||
}
|
||||
|
||||
@ -296,29 +309,37 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
|
||||
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
|
||||
|
||||
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
|
||||
value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
|
||||
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
|
||||
|
||||
hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
|
||||
m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
|
||||
v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
|
||||
v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
|
||||
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
|
||||
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
|
||||
if (inno_conn_state->rgb_limited_range) {
|
||||
csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
|
||||
auto_csc = AUTO_CSC_DISABLE;
|
||||
c0_c2_change = C0_C2_CHANGE_DISABLE;
|
||||
csc_enable = v_CSC_ENABLE;
|
||||
|
||||
} else {
|
||||
value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
|
||||
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
|
||||
|
||||
hdmi_modb(hdmi, HDMI_VIDEO_CONTRL,
|
||||
m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
|
||||
v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
|
||||
v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
|
||||
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
|
||||
auto_csc = AUTO_CSC_DISABLE;
|
||||
c0_c2_change = C0_C2_CHANGE_DISABLE;
|
||||
csc_enable = v_CSC_ENABLE;
|
||||
if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
|
||||
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
|
||||
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
|
||||
auto_csc = AUTO_CSC_DISABLE;
|
||||
c0_c2_change = C0_C2_CHANGE_DISABLE;
|
||||
csc_enable = v_CSC_ENABLE;
|
||||
}
|
||||
} else {
|
||||
if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
|
||||
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
|
||||
auto_csc = AUTO_CSC_DISABLE;
|
||||
c0_c2_change = C0_C2_CHANGE_DISABLE;
|
||||
csc_enable = v_CSC_ENABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,6 +493,8 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
|
||||
|
||||
inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
|
||||
inno_conn_state->rgb_limited_range =
|
||||
drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -558,6 +581,7 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)
|
||||
|
||||
inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
|
||||
inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
|
||||
inno_conn_state->rgb_limited_range = false;
|
||||
}
|
||||
|
||||
static struct drm_connector_state *
|
||||
|
Loading…
Reference in New Issue
Block a user