diff --git a/include/uapi/display/drm/msm_drm_pp.h b/include/uapi/display/drm/msm_drm_pp.h index 1d410efcb10a..c014c1d6f194 100644 --- a/include/uapi/display/drm/msm_drm_pp.h +++ b/include/uapi/display/drm/msm_drm_pp.h @@ -31,9 +31,12 @@ struct drm_msm_pcc_coeff { __u32 rgb; }; +#define PCC_BEFORE (1 << 0) + /** * struct drm_msm_pcc - pcc feature structure - * @flags: for customizing operations + * @flags: for customizing operations. Values can be + * - PCC_BEFORE: Operate PCC using a 'before' arrangement * @r: red coefficients. * @g: green coefficients. * @b: blue coefficients. diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index addb4afcc1eb..dd31f5cb06f6 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -2368,6 +2368,7 @@ static void dspp_pcc_install_property(struct drm_crtc *crtc) switch (version) { case 1: case 4: + case 5: sde_cp_crtc_install_blob_property(crtc, feature_name, SDE_CP_CRTC_DSPP_PCC, sizeof(struct drm_msm_pcc)); break; diff --git a/msm/sde/sde_hw_dspp.c b/msm/sde/sde_hw_dspp.c index 17649cdf76a3..ffcb046d374c 100644 --- a/msm/sde/sde_hw_dspp.c +++ b/msm/sde/sde_hw_dspp.c @@ -70,6 +70,13 @@ static void dspp_pcc(struct sde_hw_dspp *c) c->ops.setup_pcc = reg_dmav1_setup_dspp_pccv4; else c->ops.setup_pcc = sde_setup_dspp_pccv4; + } else if (c->cap->sblk->pcc.version == + (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { + ret = reg_dmav1_init_dspp_op_v4(SDE_DSPP_PCC, c->idx); + if (!ret) + c->ops.setup_pcc = reg_dmav1_setup_dspp_pccv5; + else + c->ops.setup_pcc = NULL; } } diff --git a/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/msm/sde/sde_hw_reg_dma_v1_color_proc.c index 936ac0726790..e4630bb6ca15 100644 --- a/msm/sde/sde_hw_reg_dma_v1_color_proc.c +++ b/msm/sde/sde_hw_reg_dma_v1_color_proc.c @@ -1226,7 +1226,7 @@ exit: return rc; } -static void _dspp_pccv4_off(struct sde_hw_dspp *ctx, void *cfg) +static void _dspp_pcc_common_off(struct sde_hw_dspp *ctx, void *cfg) { struct sde_reg_dma_kickoff_cfg kick_off; struct sde_hw_cp_cfg *hw_cfg = cfg; @@ -1274,7 +1274,7 @@ static void _dspp_pccv4_off(struct sde_hw_dspp *ctx, void *cfg) DRM_ERROR("failed to kick off ret %d\n", rc); } -void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg) +void reg_dmav1_setup_dspp_pcc_common(struct sde_hw_dspp *ctx, void *cfg) { struct sde_hw_reg_dma_ops *dma_ops; struct sde_reg_dma_kickoff_cfg kick_off; @@ -1293,7 +1293,7 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg) if (!hw_cfg->payload) { DRM_DEBUG_DRIVER("disable pcc feature\n"); - _dspp_pccv4_off(ctx, cfg); + _dspp_pcc_common_off(ctx, cfg); return; } @@ -1374,7 +1374,11 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg) goto exit; } + reg = PCC_EN; + if (pcc_cfg->flags & PCC_BEFORE) + reg |= BIT(16); + REG_DMA_SETUP_OPS(dma_write_cfg, ctx->cap->sblk->pcc.base, ®, sizeof(reg), REG_SINGLE_WRITE, 0, 0, 0); @@ -1392,6 +1396,31 @@ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg) exit: kfree(data); + +} + +void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg) +{ + struct drm_msm_pcc *pcc_cfg; + struct sde_hw_cp_cfg *hw_cfg = cfg; + + if (hw_cfg->payload) { + if (hw_cfg->len != sizeof(struct drm_msm_pcc)) { + DRM_ERROR("invalid size of payload len %d exp %zd\n", + hw_cfg->len, + sizeof(struct drm_msm_pcc)); + return; + } + //Flags unsupported for PCCv4 + pcc_cfg = hw_cfg->payload; + pcc_cfg->flags = 0; + } + reg_dmav1_setup_dspp_pcc_common(ctx, cfg); +} + +void reg_dmav1_setup_dspp_pccv5(struct sde_hw_dspp *ctx, void *cfg) +{ + reg_dmav1_setup_dspp_pcc_common(ctx, cfg); } void reg_dmav1_setup_dspp_pa_hsicv17(struct sde_hw_dspp *ctx, void *cfg) diff --git a/msm/sde/sde_hw_reg_dma_v1_color_proc.h b/msm/sde/sde_hw_reg_dma_v1_color_proc.h index 12fbe2288329..6fff65f584db 100644 --- a/msm/sde/sde_hw_reg_dma_v1_color_proc.h +++ b/msm/sde/sde_hw_reg_dma_v1_color_proc.h @@ -68,6 +68,14 @@ void reg_dmav1_setup_dspp_igcv31(struct sde_hw_dspp *ctx, void *cfg); */ void reg_dmav1_setup_dspp_pccv4(struct sde_hw_dspp *ctx, void *cfg); + +/** + * reg_dmav1_setup_dspp_pccv5() - pcc v5 implementation using reg dma v1. + * @ctx: dspp ctx info + * @cfg: pointer to struct sde_hw_cp_cfg + */ +void reg_dmav1_setup_dspp_pccv5(struct sde_hw_dspp *ctx, void *cfg); + /** * reg_dmav1_setup_dspp_pa_hsicv17() - pa hsic v17 impl using reg dma v1. * @ctx: dspp ctx info