From 6d38542accbd10d3ac983e1063e937be30789c40 Mon Sep 17 00:00:00 2001 From: Kirill Shpin Date: Wed, 12 Apr 2023 16:43:35 -0700 Subject: [PATCH] disp: msm: dsi: follow the HPG guidelines for DATABUS_WIDEN In case of DATABUS_WIDEN, follow the HPG to calculate bitclk, byteclk and pclk. Configure the DST_FORMAT and the clock dividers in DSI PHY and DISP_CC w.r.t. the bpp before compression. Change-Id: I526eab5bc88b8d667b8b1a0d257b2f147998286a Signed-off-by: Srihitha Tangudu Signed-off-by: Kirill Shpin Signed-off-by: Ayushi Makhija --- msm/dp/dp_panel.c | 6 +++--- msm/dsi/dsi_ctrl_hw_cmn.c | 2 +- msm/dsi/dsi_display.c | 37 +++++++++++++++++++++------------- msm/dsi/dsi_drm.c | 2 +- msm/dsi/dsi_panel.c | 13 ++---------- msm/msm_drv.h | 15 +++++++++++--- msm/sde/sde_encoder_dce.c | 7 +++++-- msm/sde/sde_encoder_phys.h | 2 +- msm/sde/sde_encoder_phys_vid.c | 15 ++++++++------ msm/sde_dsc_helper.c | 22 ++++++++++++++++---- msm/sde_dsc_helper.h | 4 ++-- 11 files changed, 77 insertions(+), 48 deletions(-) diff --git a/msm/dp/dp_panel.c b/msm/dp/dp_panel.c index 0fb2e68b..ca3ec2ab 100644 --- a/msm/dp/dp_panel.c +++ b/msm/dp/dp_panel.c @@ -1575,7 +1575,7 @@ static int dp_panel_dsc_prepare_basic_params( comp_info->comp_type = MSM_DISPLAY_COMPRESSION_DSC; comp_info->tgt_bpp = DSC_TGT_BPP; comp_info->src_bpp = dp_mode->timing.bpp; - comp_info->comp_ratio = dp_mode->timing.bpp / DSC_TGT_BPP; + comp_info->comp_ratio = mult_frac(100, dp_mode->timing.bpp, DSC_TGT_BPP); comp_info->enabled = true; return 0; @@ -3001,7 +3001,7 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel, comp_info->src_bpp = default_bpp; comp_info->tgt_bpp = default_bpp; comp_info->comp_type = MSM_DISPLAY_COMPRESSION_NONE; - comp_info->comp_ratio = 1; + comp_info->comp_ratio = MSM_DISPLAY_COMPRESSION_RATIO_NONE; comp_info->enabled = false; /* As YUV was not supported now, so set the default format to RGB */ @@ -3036,7 +3036,7 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel, } rc = sde_dsc_populate_dsc_private_params(&comp_info->dsc_info, - dp_mode->timing.h_active); + dp_mode->timing.h_active, dp_mode->timing.widebus_en); if (rc) { DP_DEBUG("failed populating other dsc params\n"); return; diff --git a/msm/dsi/dsi_ctrl_hw_cmn.c b/msm/dsi/dsi_ctrl_hw_cmn.c index 10ad6321..9fded27d 100644 --- a/msm/dsi/dsi_ctrl_hw_cmn.c +++ b/msm/dsi/dsi_ctrl_hw_cmn.c @@ -567,7 +567,7 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, this_frame_slices = pic_width / dsc.config.slice_width; intf_ip_w = this_frame_slices * dsc.config.slice_width; - sde_dsc_populate_dsc_private_params(&dsc, intf_ip_w); + sde_dsc_populate_dsc_private_params(&dsc, intf_ip_w, ctrl->widebus_support); width_final = dsc.bytes_per_pkt * dsc.pkt_per_line; stride_final = dsc.bytes_per_pkt; diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index f9ce0b15..16ffc421 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -7090,27 +7090,27 @@ int dsi_display_get_modes_helper(struct dsi_display *display, memset(&display_mode, 0, sizeof(display_mode)); + display_mode.priv_info = kzalloc(sizeof(*display_mode.priv_info), GFP_KERNEL); + if (!display_mode.priv_info) { + rc = -ENOMEM; + return rc; + } + + /* Setup widebus support */ + display_mode.priv_info->widebus_support = ctrl->ctrl->hw.widebus_support; + rc = dsi_panel_get_mode(display->panel, mode_idx, &display_mode, topology_override); if (rc) { DSI_ERR("[%s] failed to get mode idx %d from panel\n", display->name, mode_idx); + kfree(display_mode.priv_info); + display_mode.priv_info = NULL; rc = -EINVAL; return rc; } - /* - * Update the host_config.dst_format for compressed RGB101010 pixel format. - */ - if (display->panel->host_config.dst_format == DSI_PIXEL_FORMAT_RGB101010 && - display_mode.timing.dsc_enabled) { - display->panel->host_config.dst_format = DSI_PIXEL_FORMAT_RGB888; - DSI_DEBUG("updated dst_format from %d to %d\n", - DSI_PIXEL_FORMAT_RGB101010, - display->panel->host_config.dst_format); - } - if (display->cmdline_timing == display_mode.mode_idx) { topology_override = display->cmdline_topology; is_preferred = true; @@ -7124,9 +7124,18 @@ int dsi_display_get_modes_helper(struct dsi_display *display, else nondsc_modes++; - /* Setup widebus support */ - display_mode.priv_info->widebus_support = - ctrl->ctrl->hw.widebus_support; + /* + * Update the host_config.dst_format for compressed RGB101010 pixel format + * when there is no widebus support. + */ + if (host->dst_format == DSI_PIXEL_FORMAT_RGB101010 && + display_mode.timing.dsc_enabled && + !display_mode.priv_info->widebus_support) { + host->dst_format = DSI_PIXEL_FORMAT_RGB888; + DSI_DEBUG("updated dst_format from %d to %d\n", + DSI_PIXEL_FORMAT_RGB101010, host->dst_format); + } + num_dfps_rates = ((!dfps_caps.dfps_support || !support_video_mode) ? 1 : dfps_caps.dfps_list_len); diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 62c37e7d..bb89f478 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -692,7 +692,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector, if (mode_info->comp_info.comp_type) { tar_bpp = dsi_mode->priv_info->pclk_scale.numer; src_bpp = dsi_mode->priv_info->pclk_scale.denom; - mode_info->comp_info.comp_ratio = mult_frac(1, src_bpp, + mode_info->comp_info.comp_ratio = mult_frac(100, src_bpp, tar_bpp); mode_info->wide_bus_en = dsi_mode->priv_info->widebus_support; } diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index a156e5f3..c9771fcf 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -2812,7 +2812,8 @@ static int dsi_panel_parse_dsc_params(struct dsi_display_mode *mode, goto error; } - rc = sde_dsc_populate_dsc_private_params(&priv_info->dsc, intf_width); + rc = sde_dsc_populate_dsc_private_params(&priv_info->dsc, intf_width, + priv_info->widebus_support); if (rc) { DSI_DEBUG("failed populating other dsc params\n"); rc = -EINVAL; @@ -4173,12 +4174,6 @@ int dsi_panel_get_mode(struct dsi_panel *panel, mutex_lock(&panel->panel_lock); utils = &panel->utils; - mode->priv_info = kzalloc(sizeof(*mode->priv_info), GFP_KERNEL); - if (!mode->priv_info) { - rc = -ENOMEM; - goto done; - } - prv_info = mode->priv_info; timings_np = utils->get_child_by_name(utils->data, @@ -4272,12 +4267,8 @@ int dsi_panel_get_mode(struct dsi_panel *panel, if (rc) DSI_ERR("failed to partial update caps, rc=%d\n", rc); } - goto done; parse_fail: - kfree(mode->priv_info); - mode->priv_info = NULL; -done: utils->data = utils_data; mutex_unlock(&panel->panel_lock); return rc; diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 1f79a3fa..cee29439 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -270,8 +270,11 @@ enum msm_display_wd_jitter_type { MSM_DISPLAY_WD_LTJ_JITTER = BIT(2), }; -#define MSM_DISPLAY_COMPRESSION_RATIO_NONE 1 -#define MSM_DISPLAY_COMPRESSION_RATIO_MAX 5 +/** + * Scale macros so that compression ratio is a factor of 100 everywhere + */ +#define MSM_DISPLAY_COMPRESSION_RATIO_NONE 100 +#define MSM_DISPLAY_COMPRESSION_RATIO_MAX 500 /** * enum msm_display_spr_pack_type - sub pixel rendering pack patterns supported @@ -703,11 +706,17 @@ struct msm_display_vdc_info { */ #define DSC_BPP(config) ((config).bits_per_pixel >> 4) +/** + * Bits/component + * returns the integer bpc value from the drm_dsc_config struct + */ +#define DSC_BPC(config) ((config).bits_per_component) + /** * struct msm_compression_info - defined panel compression * @enabled: enabled/disabled * @comp_type: type of compression supported - * @comp_ratio: compression ratio + * @comp_ratio: compression ratio multiplied by 100 * @src_bpp: bits per pixel before compression * @tgt_bpp: bits per pixel after compression * @dsc_info: dsc configuration if the compression diff --git a/msm/sde/sde_encoder_dce.c b/msm/sde/sde_encoder_dce.c index 6501a4e6..1615b12f 100644 --- a/msm/sde/sde_encoder_dce.c +++ b/msm/sde/sde_encoder_dce.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. */ @@ -418,6 +418,7 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc, int dsc_pic_width; int dsc_common_mode = 0; int i, rc = 0; + bool widebus_en; sde_kms = sde_encoder_get_kms(&sde_enc->base); @@ -486,7 +487,9 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc, else if ((dsc_common_mode & DSC_MODE_MULTIPLEX) || (dsc->half_panel_pu)) dsc->num_active_ss_per_enc = dsc->config.slice_count >> 1; - sde_dsc_populate_dsc_private_params(dsc, intf_ip_w); + widebus_en = sde_encoder_is_widebus_enabled(enc_master->parent); + + sde_dsc_populate_dsc_private_params(dsc, intf_ip_w, widebus_en); _dce_dsc_initial_line_calc(dsc, enc_ip_w, dsc_common_mode); diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index f7363b21..69c8fbed 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -287,7 +287,7 @@ struct sde_encoder_irq { * @intf_cfg_v1: Interface hardware configuration to be used if control * path supports SDE_CTL_ACTIVE_CFG * @comp_type: Type of compression supported - * @comp_ratio: Compression ratio + * @comp_ratio: Compression ratio multiplied by 100 * @dsc_extra_pclk_cycle_cnt: Extra pclk cycle count for DSC over DP * @dsc_extra_disp_width: Additional display width for DSC over DP * @poms_align_vsync: poms with vsync aligned diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index 6bfb61af..3c1c81ed 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -11,6 +11,7 @@ #include "sde_formats.h" #include "dsi_display.h" #include "sde_trace.h" +#include #define SDE_DEBUG_VIDENC(e, fmt, ...) SDE_DEBUG("enc%d intf%d " fmt, \ (e) && (e)->base.parent ? \ @@ -48,6 +49,7 @@ static void drm_mode_to_intf_timing_params( struct intf_timing_params *timing) { const struct sde_encoder_phys *phys_enc = &vid_enc->base; + s64 comp_ratio, width; memset(timing, 0, sizeof(*timing)); @@ -124,7 +126,7 @@ static void drm_mode_to_intf_timing_params( */ if (phys_enc->hw_intf->cap->type == INTF_DP && (timing->wide_bus_en || - (vid_enc->base.comp_ratio > 1))) { + (vid_enc->base.comp_ratio > MSM_DISPLAY_COMPRESSION_RATIO_NONE))) { timing->width = timing->width >> 1; timing->xres = timing->xres >> 1; timing->h_back_porch = timing->h_back_porch >> 1; @@ -132,7 +134,7 @@ static void drm_mode_to_intf_timing_params( timing->hsync_pulse_width = timing->hsync_pulse_width >> 1; if (vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_DSC && - (vid_enc->base.comp_ratio > 1)) { + (vid_enc->base.comp_ratio > MSM_DISPLAY_COMPRESSION_RATIO_NONE)) { timing->extra_dto_cycles = vid_enc->base.dsc_extra_pclk_cycle_cnt; timing->width += vid_enc->base.dsc_extra_disp_width; @@ -151,10 +153,11 @@ static void drm_mode_to_intf_timing_params( (vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_VDC))) { // adjust active dimensions - timing->width = DIV_ROUND_UP(timing->width, - vid_enc->base.comp_ratio); - timing->xres = DIV_ROUND_UP(timing->xres, - vid_enc->base.comp_ratio); + width = drm_fixp_from_fraction(timing->width, 1); + comp_ratio = drm_fixp_from_fraction(vid_enc->base.comp_ratio, 100); + width = drm_fixp_div(width, comp_ratio); + timing->width = drm_fixp2int_ceil(width); + timing->xres = timing->width; } /* diff --git a/msm/sde_dsc_helper.c b/msm/sde_dsc_helper.c index eeda0785..1fee8407 100644 --- a/msm/sde_dsc_helper.c +++ b/msm/sde_dsc_helper.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. */ @@ -372,12 +372,13 @@ int sde_dsc_populate_dsc_config(struct drm_dsc_config *dsc, int scr_ver) { } int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info, - int intf_width) + int intf_width, bool widebus_en) { int mod_offset; int slice_per_pkt, slice_per_intf; int bytes_in_slice, total_bytes_per_intf; u16 bpp; + u16 bpc; u32 bytes_in_dsc_pair; u32 total_bytes_in_dsc_pair; @@ -421,12 +422,26 @@ int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info, slice_per_pkt = 1; bpp = DSC_BPP(dsc_info->config); + bpc = DSC_BPC(dsc_info->config); bytes_in_slice = DIV_ROUND_UP(dsc_info->config.slice_width * bpp, 8); total_bytes_per_intf = bytes_in_slice * slice_per_intf; dsc_info->eol_byte_num = total_bytes_per_intf % 3; - dsc_info->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3); + + /* + * In DATABUS-WIDEN mode, MDP always sends out 48-bit compressed data per pclk + * and on average, DSI consumes an amount of compressed data equivalent to the + * uncompressed pixel depth per pclk. + * + * In NON-DATABUS-WIDEN mode, MDP always sends out 24-bit compressed data per + * pclk and DSI always consumes 24-bit compressed data per pclk. + */ + if (widebus_en) + dsc_info->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf * 8, + msm_get_src_bpc(dsc_info->chroma_format, bpc)); + else + dsc_info->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf * 8, 24); dsc_info->bytes_in_slice = bytes_in_slice; dsc_info->bytes_per_pkt = bytes_in_slice * slice_per_pkt; dsc_info->pkt_per_line = slice_per_intf / slice_per_pkt; @@ -571,4 +586,3 @@ int sde_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc_info, return 0; } - diff --git a/msm/sde_dsc_helper.h b/msm/sde_dsc_helper.h index b6304210..6ac7ec81 100644 --- a/msm/sde_dsc_helper.h +++ b/msm/sde_dsc_helper.h @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2020 The Linux Foundation. All rights reserved. */ @@ -13,10 +14,9 @@ int sde_dsc_populate_dsc_config(struct drm_dsc_config *dsc, int scr_ver); int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info, - int intf_width); + int intf_width, bool widebus_en); int sde_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc_info, char *buf, int pps_id, u32 len); #endif /* __SDE_DSC_HELPER_H__ */ -