drm/hdmi: fix Dolby Vision colour base at decide time#31
Closed
allolive wants to merge 1 commit into
Closed
Conversation
decide_color_attr picks the colour base from hdmi_current_eotf_type, but for Dolby Vision that is not set yet when the mode is committed (the DV core sets it later over VSIF). So a DV title gets an SDR base: no signal at 4K60, and the wrong depth after a 24/23.976 switch. is_amdv_enable() and get_amdv_ll_policy() are already valid here, so use them to pin the tunnel base for any 4K vic: TV-led is YUV444 8-bit, player-led is YUV422 12-bit. SDR and HDR10 are left alone. Needs the matching xbmc change to force the re-decide. Signed-off-by: Olivier Allauzen <olivier.allauzen@gmail.com>
3 tasks
Contributor
|
Instead force on end rewrite it complete? But maybe it's still good to check diff --git a/drivers/drm/meson_hdmi.c b/drivers/drm/meson_hdmi.c
index 69e6db48a2..1c431e8d79 100644
--- a/drivers/drm/meson_hdmi.c
+++ b/drivers/drm/meson_hdmi.c
@@ -319,140 +319,97 @@ static int meson_hdmitx_decide_color_attr
// try autoselect
// check if any colour subsampling is set
// force colour subsampling when DV mode
- switch (common->hdmi_current_eotf_type) {
- case EOTF_T_DOLBYVISION:
- case EOTF_T_LL_MODE:
- case EOTF_T_DV_AHEAD:
- {
- int cs = attr->colorformat;
- switch (common->hdmi_current_tunnel_mode) {
- case RGB_8BIT:
- case RGB_10_12BIT:
- attr->colorformat = HDMI_COLORSPACE_YUV444;
- break;
- case YUV422_BIT12:
- attr->colorformat = HDMI_COLORSPACE_YUV422;
- break;
- case YUV444_10_12BIT:
- attr->colorformat = HDMI_COLORSPACE_YUV444;
- break;
- default:
- break;
- }
- if (cs != attr->colorformat)
- DRM_INFO("[%s]: display colour subsampling is forced to %s by Dolby Vision tunneling\n", __func__,
- colour_sampling[attr->colorformat]);
- }
- break;
- default:
- if (strstr(common->fmt_attr, "rgb") == NULL &&
- strstr(common->fmt_attr, "420") == NULL &&
- strstr(common->fmt_attr, "422") == NULL &&
- strstr(common->fmt_attr, "444") == NULL) {
- if (is_hdmi4k_support_420(vic & 0xff)) {
- /*
- * Use YCbCr 4:2:2 when supported by the sink,
- * otherwise retain the existing YCbCr 4:2:0
- * behaviour.
- */
- if (is_support_y422(&common->rxcap))
- attr->colorformat = HDMI_COLORSPACE_YUV422;
- else
- attr->colorformat = HDMI_COLORSPACE_YUV420;
-
- DRM_INFO("[%s]: display colour subsampling is forced to %s because of current video information code %d\n", __func__,
- colour_sampling[attr->colorformat], vic);
- }
+ if (is_amdv_enable()) {
+ int cs = attr->colorformat;
+ if (get_amdv_ll_policy() == DOLBY_VISION_LL_YUV422) {
+ attr->colorformat = HDMI_COLORSPACE_YUV422;
+ } else {
+ attr->colorformat = HDMI_COLORSPACE_YUV444;
+ }
+ if (cs != attr->colorformat)
+ DRM_INFO("[%s]: display colour subsampling is forced to %s by Dolby Vision tunneling\n", __func__,
+ colour_sampling[attr->colorformat]);
+ } else {
+ if (strstr(common->fmt_attr, "rgb") == NULL &&
+ strstr(common->fmt_attr, "420") == NULL &&
+ strstr(common->fmt_attr, "422") == NULL &&
+ strstr(common->fmt_attr, "444") == NULL) {
+ if (is_hdmi4k_support_420(vic & 0xff)) {
+ /*
+ * Use YCbCr 4:2:2 when supported by the sink,
+ * otherwise retain the existing YCbCr 4:2:0
+ * behaviour.
+ */
+ if (is_support_y422(&common->rxcap))
+ attr->colorformat = HDMI_COLORSPACE_YUV422;
else
- DRM_INFO("[%s]: display colour subsampling is auto set to %s\n", __func__,
- colour_sampling[attr->colorformat]);
+ attr->colorformat = HDMI_COLORSPACE_YUV420;
+
+ DRM_INFO("[%s]: display colour subsampling is forced to %s because of current video information code %d\n", __func__,
+ colour_sampling[attr->colorformat], vic);
}
else
- {
- DRM_INFO("[%s]: display colour subsampling is forced by attr to %s: %s\n", __func__,
- colour_sampling[fmt_attr.colorformat], common->fmt_attr);
- attr->colorformat = fmt_attr.colorformat;
- }
- break;
+ DRM_INFO("[%s]: display colour subsampling is auto set to %s\n", __func__,
+ colour_sampling[attr->colorformat]);
+ }
+ else
+ {
+ DRM_INFO("[%s]: display colour subsampling is forced by attr to %s: %s\n", __func__,
+ colour_sampling[fmt_attr.colorformat], common->fmt_attr);
+ attr->colorformat = fmt_attr.colorformat;
+ }
}
// parse and set maximum colourdepth given by edid
// check for colour subsampling limit
- switch (common->hdmi_current_eotf_type) {
- case EOTF_T_DOLBYVISION:
- case EOTF_T_LL_MODE:
- case EOTF_T_DV_AHEAD:
- {
- const struct dv_info *dv_info = &common->rxcap.dv_info;
- int cd = bitdepth_to_colordepth(attr->bitdepth);
- switch (common->hdmi_current_tunnel_mode) {
- case RGB_8BIT:
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
- break;
- case RGB_10_12BIT:
- case YUV444_10_12BIT:
- if (dv_info->ver == 2) {
- switch (dv_info->sup_10b_12b_444) {
- case 1:
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_30B);
- break;
- case 2:
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_36B);
- break;
- default:
- break;
- }
- }
- break;
- case YUV422_BIT12:
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_36B);
- break;
- default:
+ if (is_amdv_enable()) {
+ const struct dv_info *dv_info = &common->rxcap.dv_info;
+ int cd = bitdepth_to_colordepth(attr->bitdepth);
+ if (get_amdv_ll_policy() == DOLBY_VISION_LL_YUV422) {
+ attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_36B);
+ } else {
+ attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
+ }
+ if (cd != bitdepth_to_colordepth(attr->bitdepth))
+ DRM_INFO("[%s]: display colourdepth is forced to %d bits because of Dolby Vision sink capability\n", __func__,
+ attr->bitdepth);
+ } else {
+ // check colourdepth
+ if (strstr(common->fmt_attr, "bit") != NULL) {
+ DRM_INFO("[%s]: display colourdepth is forced by attr to %d bits: %s\n", __func__,
+ fmt_attr.bitdepth, common->fmt_attr);
+ attr->bitdepth = fmt_attr.bitdepth;
+ } else {
+ if (common->rxcap.ColorDeepSupport & 0x78 && attr->colorformat != HDMI_COLORSPACE_YUV420) {
+ enum hdmi_color_depth cd;
+ for (cd = COLORDEPTH_30B; cd >= COLORDEPTH_24B; cd--) {
+ if (common->rxcap.ColorDeepSupport & (1 << (cd - 1))) {
+ attr->bitdepth = colordepth_to_bitdepth(cd);
break;
- }
- if (cd != bitdepth_to_colordepth(attr->bitdepth))
- DRM_INFO("[%s]: display colourdepth is forced to %d bits because of Dolby Vision sink capability\n", __func__,
- attr->bitdepth);
- }
- break;
- default:
- // check colourdepth
- if (strstr(common->fmt_attr, "bit") != NULL) {
- DRM_INFO("[%s]: display colourdepth is forced by attr to %d bits: %s\n", __func__,
- fmt_attr.bitdepth, common->fmt_attr);
- attr->bitdepth = fmt_attr.bitdepth;
- } else {
- if (common->rxcap.ColorDeepSupport & 0x78 && attr->colorformat != HDMI_COLORSPACE_YUV420) {
- enum hdmi_color_depth cd;
- for (cd = COLORDEPTH_30B; cd >= COLORDEPTH_24B; cd--) {
- if (common->rxcap.ColorDeepSupport & (1 << (cd - 1))) {
- attr->bitdepth = colordepth_to_bitdepth(cd);
- break;
- }
}
- } else if (common->rxcap.hf_ieeeoui == HF_IEEEOUI) {
- if (common->rxcap.dc_30bit_420)
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_30B);
- else
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
}
+ } else if (common->rxcap.hf_ieeeoui == HF_IEEEOUI) {
+ if (common->rxcap.dc_30bit_420)
+ attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_30B);
+ else
+ attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
+ }
- if (is_hdmi4k_support_420(vic & 0xff)) {
- if (attr->colorformat == HDMI_COLORSPACE_RGB || attr->colorformat == HDMI_COLORSPACE_YUV444) {
- attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
- DRM_INFO("[%s]: display colourdepth is forced to %d bits because of current video information code %d\n", __func__,
- attr->bitdepth, vic);
- }
- }
- if (common->flag_3dfp) {
+ if (is_hdmi4k_support_420(vic & 0xff)) {
+ if (attr->colorformat == HDMI_COLORSPACE_RGB || attr->colorformat == HDMI_COLORSPACE_YUV444) {
attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
- DRM_INFO("[%s]: display colourdepth is auto set to %d bits because of 3dfp mode\n", __func__,
- attr->bitdepth);
- } else
- DRM_INFO("[%s]: display colourdepth is auto set to %d bits\n", __func__,
- attr->bitdepth);
+ DRM_INFO("[%s]: display colourdepth is forced to %d bits because of current video information code %d\n", __func__,
+ attr->bitdepth, vic);
+ }
}
- break;
+ if (common->flag_3dfp) {
+ attr->bitdepth = colordepth_to_bitdepth(COLORDEPTH_24B);
+ DRM_INFO("[%s]: display colourdepth is auto set to %d bits because of 3dfp mode\n", __func__,
+ attr->bitdepth);
+ } else
+ DRM_INFO("[%s]: display colourdepth is auto set to %d bits\n", __func__,
+ attr->bitdepth);
+ }
}
DRM_INFO("[%s]:[%s,eotf:%d,vic:%d]=>attr[%s,%dbit]\n", __func__, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
decide_color_attr picks the colour base from hdmi_current_eotf_type, but for Dolby Vision that is not set yet when the mode is committed (the DV core sets it later over VSIF). So a DV title gets an SDR base: no signal at 4K60, and the wrong depth after a 24/23.976 switch.
is_amdv_enable() and get_amdv_ll_policy() are already valid here, so use them to pin the tunnel base for any 4K vic: TV-led is YUV444 8-bit, player-led is YUV422 12-bit. SDR and HDR10 are left alone.
Needs the matching xbmc change to force the re-decide.