From e3f23771bab9b3411686d84c5464df4dd818afe5 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Thu, 14 Nov 2019 19:17:52 -0800 Subject: [PATCH] disp: msm: add support for variable compression ratios Currently the compression ratio is hard-coded to either 2:1 or 3:1 in several places. This is not sufficient for new compression algorithms as they can support higher compression ratios. Add support for calculating the compression ratios from the source and target bpp thereby eliminating hard-coding. Change-Id: I6383f3d0c781193d0a9ed74df5a95d8e856edb3d Signed-off-by: Abhinav Kumar --- msm/dsi/dsi_drm.c | 18 ++++++++++++++---- msm/msm_drv.c | 24 +++++++++++++++++++++++- msm/msm_drv.h | 20 +++++--------------- msm/sde/sde_encoder_phys.h | 2 +- msm/sde/sde_encoder_phys_vid.c | 19 ++++++------------- 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 43984cb9e4f1..90f03add80eb 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -472,6 +472,8 @@ int dsi_conn_get_mode_info(struct drm_connector *connector, { struct dsi_display_mode dsi_mode; struct dsi_mode_info *timing; + int chroma_format; + int src_bpp, tar_bpp; if (!drm_mode || !mode_info) return -EINVAL; @@ -498,17 +500,25 @@ int dsi_conn_get_mode_info(struct drm_connector *connector, mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_NONE; if (dsi_mode.priv_info->dsc_enabled) { + chroma_format = dsi_mode.priv_info->dsc.chroma_format; mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_DSC; memcpy(&mode_info->comp_info.dsc_info, &dsi_mode.priv_info->dsc, sizeof(dsi_mode.priv_info->dsc)); - mode_info->comp_info.comp_ratio = - MSM_DISPLAY_COMPRESSION_RATIO_3_TO_1; + tar_bpp = dsi_mode.priv_info->dsc.config.bits_per_pixel >> 4; + src_bpp = msm_get_src_bpc(chroma_format, + dsi_mode.priv_info->dsc.config.bits_per_component); + mode_info->comp_info.comp_ratio = mult_frac(1, src_bpp, + tar_bpp); } else if (dsi_mode.priv_info->vdc_enabled) { + chroma_format = dsi_mode.priv_info->vdc.chroma_format; mode_info->comp_info.comp_type = MSM_DISPLAY_COMPRESSION_VDC; memcpy(&mode_info->comp_info.vdc_info, &dsi_mode.priv_info->vdc, sizeof(dsi_mode.priv_info->vdc)); - mode_info->comp_info.comp_ratio = - MSM_DISPLAY_COMPRESSION_RATIO_4_TO_1; + tar_bpp = dsi_mode.priv_info->vdc.bits_per_pixel >> 4; + src_bpp = msm_get_src_bpc(chroma_format, + dsi_mode.priv_info->vdc.bits_per_component); + mode_info->comp_info.comp_ratio = mult_frac(1, src_bpp, + tar_bpp); } if (dsi_mode.priv_info->roi_caps.enabled) { diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 4e315bdcf38a..2623c4bdefbc 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -301,6 +301,28 @@ u32 msm_readl(const void __iomem *addr) return val; } +int msm_get_src_bpc(int chroma_format, + int bpc) +{ + int src_bpp; + + switch (chroma_format) { + case MSM_CHROMA_444: + src_bpp = bpc * 3; + break; + case MSM_CHROMA_422: + src_bpp = bpc * 2; + break; + case MSM_CHROMA_420: + src_bpp = mult_frac(bpc, 3, 2); + break; + default: + src_bpp = bpc * 3; + break; + } + return src_bpp; +} + struct vblank_work { struct kthread_work work; int crtc_id; diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 4bf64fa57c0c..d8fb43e25b31 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -228,20 +228,8 @@ enum msm_display_compression_type { MSM_DISPLAY_COMPRESSION_VDC }; -/** - * enum msm_display_compression_ratio - compression ratio - * @MSM_DISPLAY_COMPRESSION_NONE: no compression - * @MSM_DISPLAY_COMPRESSION_RATIO_2_TO_1: 2 to 1 compression - * @MSM_DISPLAY_COMPRESSION_RATIO_3_TO_1: 3 to 1 compression - * @MSM_DISPLAY_COMPRESSION_RATIO_4_TO_1: 4 to 1 compression - */ -enum msm_display_compression_ratio { - MSM_DISPLAY_COMPRESSION_RATIO_NONE, - MSM_DISPLAY_COMPRESSION_RATIO_2_TO_1, - MSM_DISPLAY_COMPRESSION_RATIO_3_TO_1, - MSM_DISPLAY_COMPRESSION_RATIO_4_TO_1, - MSM_DISPLAY_COMPRESSION_RATIO_MAX, -}; +#define MSM_DISPLAY_COMPRESSION_RATIO_NONE 1 +#define MSM_DISPLAY_COMPRESSION_RATIO_MAX 5 /** * enum msm_display_caps - features/capabilities supported by displays @@ -606,7 +594,7 @@ struct msm_display_vdc_info { */ struct msm_compression_info { enum msm_display_compression_type comp_type; - enum msm_display_compression_ratio comp_ratio; + u32 comp_ratio; union{ struct msm_display_dsc_info dsc_info; @@ -1231,4 +1219,6 @@ int msm_get_mixer_count(struct msm_drm_private *priv, const struct drm_display_mode *mode, const struct msm_resource_caps_info *res, u32 *num_lm); +int msm_get_src_bpc(int chroma_format, int bpc); + #endif /* __MSM_DRV_H__ */ diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index 59ea2cc1aea2..6cea9324f8e2 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -310,7 +310,7 @@ struct sde_encoder_phys { struct sde_hw_intf_cfg intf_cfg; struct sde_hw_intf_cfg_v1 intf_cfg_v1; enum msm_display_compression_type comp_type; - enum msm_display_compression_ratio comp_ratio; + u32 comp_ratio; u32 dsc_extra_pclk_cycle_cnt; u32 dsc_extra_disp_width; bool wide_bus_en; diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index a8e779ab1a25..31a1eb6167b5 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -50,8 +50,6 @@ static void drm_mode_to_intf_timing_params( struct intf_timing_params *timing) { const struct sde_encoder_phys *phys_enc = &vid_enc->base; - enum msm_display_compression_ratio comp_ratio = - MSM_DISPLAY_COMPRESSION_RATIO_NONE; memset(timing, 0, sizeof(*timing)); @@ -82,17 +80,12 @@ static void drm_mode_to_intf_timing_params( */ timing->width = mode->hdisplay; /* active width */ - if (phys_enc->hw_intf->cap->type != INTF_DP && - vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_DSC) { - comp_ratio = vid_enc->base.comp_ratio; - if (comp_ratio == MSM_DISPLAY_COMPRESSION_RATIO_2_TO_1) - timing->width = DIV_ROUND_UP(timing->width, 2); - else - timing->width = DIV_ROUND_UP(timing->width, 3); - } else if (phys_enc->hw_intf->cap->type != INTF_DP && - vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_VDC) { - comp_ratio = vid_enc->base.comp_ratio; - timing->width = DIV_ROUND_UP(timing->width, comp_ratio); + if (phys_enc->hw_intf->cap->type != INTF_DP) { + if ((vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_DSC) || + (vid_enc->base.comp_type == + MSM_DISPLAY_COMPRESSION_VDC)) + timing->width = DIV_ROUND_UP(timing->width, + vid_enc->base.comp_ratio); } timing->height = mode->vdisplay; /* active height */