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
fourteen
Davide Garberi 9 months ago committed by Jenna
parent 125e63334f
commit fa0f035c02
  1. 13
      drivers/gpu/drm/msm/sde/sde_color_processing.c
  2. 1
      drivers/gpu/drm/msm/sde/sde_crtc.h
  3. 12
      drivers/gpu/drm/msm/sde/sde_plane.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;

@ -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 {

@ -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) {

Loading…
Cancel
Save