From fa0f035c02f23b2072af980330bb754b2c1dbe75 Mon Sep 17 00:00:00 2001 From: Davide Garberi Date: Wed, 23 Aug 2023 03:43:43 +0200 Subject: [PATCH] drm: msm: sde: Fallback to PCC for color invert * After the conversion from PCC to CSC for color trasformation, all filters work correctly and are converted properly to CSC, except for the color invert filter * This filter is the only one using the `c` constant coefficient in PCC, and it's almost impossible to conver to CSC, because the PCC reported values are far off from the regular scale of values that is being used, which makes converting the filter to CSC extra complex * To work around this, force PCC for all color filters when color invert is enabled, which has the downside of not behaving as well as CSC when using FOD, but still works just as good for all other contexts * We can use the `c` coefficient to understand if color invert is enabled, since this is the only color filter that sets the value to anything other than 0 (`32640`). Change-Id: I097413be9c519c22ee71483bdc084512f05e0465 --- drivers/gpu/drm/msm/sde/sde_color_processing.c | 13 +++++++++++-- drivers/gpu/drm/msm/sde/sde_crtc.h | 1 + drivers/gpu/drm/msm/sde/sde_plane.c | 12 +++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c index a752d1b7f667..78544bfd00b0 100755 --- a/drivers/gpu/drm/msm/sde/sde_color_processing.c +++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c @@ -642,13 +642,22 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node, bool feature_enabled = false; int ret = 0; struct sde_ad_hw_cfg ad_cfg; + struct drm_property_blob *blob; + struct drm_msm_pcc *pcc_cfg; sde_cp_get_hw_payload(prop_node, &hw_cfg, &feature_enabled); hw_cfg.num_of_mixers = sde_crtc->num_mixers; hw_cfg.last_feature = 0; - if (prop_node->feature == SDE_CP_CRTC_DSPP_PCC) - return; + if (prop_node->feature == SDE_CP_CRTC_DSPP_PCC) { + blob = prop_node->blob_ptr; + pcc_cfg = (struct drm_msm_pcc*)blob->data; + + if (pcc_cfg->r.c == 0 && pcc_cfg->b.c == 0 && pcc_cfg->g.c == 0) { + hw_cfg.payload = NULL; + hw_cfg.len = 0; + } + } for (i = 0; i < num_mixers && !ret; i++) { hw_lm = sde_crtc->mixers[i].hw_lm; diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h index 0fc1e20a8213..6a4c7692bd77 100755 --- a/drivers/gpu/drm/msm/sde/sde_crtc.h +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -438,6 +438,7 @@ struct sde_crtc_state { u32 padding_dummy; struct sde_crtc_respool rp; + bool color_invert_on; }; enum sde_crtc_irq_state { diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index 2ef817ae3c0a..9ed92ca83ec5 100755 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -3964,11 +3964,13 @@ struct sde_csc_cfg *sde_plane_get_csc_cfg(struct drm_plane *plane) struct sde_plane_state *pstate; struct sde_csc_cfg *csc_ptr; struct sde_plane *psde; + struct drm_crtc *drm_crtc = plane->state->crtc; + struct sde_crtc_state *cstate = to_sde_crtc_state(drm_crtc->state); psde = to_sde_plane(plane); pstate = to_sde_plane_state(plane->state); - if (sde_plane_is_fod_layer(&pstate->base)) + if (sde_plane_is_fod_layer(&pstate->base) || cstate->color_invert_on) csc_ptr = NULL; else if (psde->csc_pcc_ptr) csc_ptr = psde->csc_pcc_ptr; @@ -4032,10 +4034,18 @@ static inline void _sde_plane_set_csc_pcc(struct sde_plane *psde, struct drm_crtc *crtc) { const struct drm_msm_pcc *pcc_cfg = sde_cp_crtc_get_pcc_cfg(crtc); + struct sde_crtc_state *cstate = to_sde_crtc_state(crtc->state); if (pcc_cfg == psde->pcc_cfg) return; + if (pcc_cfg->r.c != 0 || pcc_cfg->b.c != 0 || pcc_cfg->g.c != 0) { + cstate->color_invert_on = true; + return; + } + + cstate->color_invert_on = false; + psde->pcc_cfg = pcc_cfg; if (pcc_cfg) {