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 <quic_tangudu@quicinc.com>
Signed-off-by: Kirill Shpin <quic_kshpin@quicinc.com>
This commit is contained in:
Kirill Shpin
2023-04-12 16:43:35 -07:00
committed by Rohith Iyer
parent f993f4d8e0
commit 7b4616f157
11 changed files with 77 additions and 37 deletions

View File

@@ -1581,7 +1581,7 @@ static int dp_panel_dsc_prepare_basic_params(
comp_info->comp_type = MSM_DISPLAY_COMPRESSION_DSC; comp_info->comp_type = MSM_DISPLAY_COMPRESSION_DSC;
comp_info->tgt_bpp = DSC_TGT_BPP; comp_info->tgt_bpp = DSC_TGT_BPP;
comp_info->src_bpp = dp_mode->timing.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; comp_info->enabled = true;
return 0; return 0;
@@ -3007,7 +3007,7 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel,
comp_info->src_bpp = default_bpp; comp_info->src_bpp = default_bpp;
comp_info->tgt_bpp = default_bpp; comp_info->tgt_bpp = default_bpp;
comp_info->comp_type = MSM_DISPLAY_COMPRESSION_NONE; 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; comp_info->enabled = false;
/* As YUV was not supported now, so set the default format to RGB */ /* As YUV was not supported now, so set the default format to RGB */
@@ -3042,7 +3042,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, 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) { if (rc) {
DP_DEBUG("failed populating other dsc params\n"); DP_DEBUG("failed populating other dsc params\n");
return; return;

View File

@@ -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; this_frame_slices = pic_width / dsc.config.slice_width;
intf_ip_w = this_frame_slices * 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; width_final = dsc.bytes_per_pkt * dsc.pkt_per_line;
stride_final = dsc.bytes_per_pkt; stride_final = dsc.bytes_per_pkt;

View File

@@ -7083,12 +7083,23 @@ int dsi_display_get_modes_helper(struct dsi_display *display,
memset(&display_mode, 0, sizeof(display_mode)); 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, rc = dsi_panel_get_mode(display->panel, mode_idx,
&display_mode, &display_mode,
topology_override); topology_override);
if (rc) { if (rc) {
DSI_ERR("[%s] failed to get mode idx %d from panel\n", DSI_ERR("[%s] failed to get mode idx %d from panel\n",
display->name, mode_idx); display->name, mode_idx);
kfree(display_mode.priv_info);
display_mode.priv_info = NULL;
rc = -EINVAL; rc = -EINVAL;
return rc; return rc;
} }
@@ -7106,9 +7117,18 @@ int dsi_display_get_modes_helper(struct dsi_display *display,
else else
nondsc_modes++; nondsc_modes++;
/* Setup widebus support */ /*
display_mode.priv_info->widebus_support = * Update the host_config.dst_format for compressed RGB101010 pixel format
ctrl->ctrl->hw.widebus_support; * 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 || num_dfps_rates = ((!dfps_caps.dfps_support ||
!support_video_mode) ? 1 : dfps_caps.dfps_list_len); !support_video_mode) ? 1 : dfps_caps.dfps_list_len);

View File

@@ -686,7 +686,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
if (mode_info->comp_info.comp_type) { if (mode_info->comp_info.comp_type) {
tar_bpp = dsi_mode->priv_info->pclk_scale.numer; tar_bpp = dsi_mode->priv_info->pclk_scale.numer;
src_bpp = dsi_mode->priv_info->pclk_scale.denom; 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); tar_bpp);
mode_info->wide_bus_en = dsi_mode->priv_info->widebus_support; mode_info->wide_bus_en = dsi_mode->priv_info->widebus_support;
} }

View File

@@ -2821,7 +2821,8 @@ static int dsi_panel_parse_dsc_params(struct dsi_display_mode *mode,
goto error; 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) { if (rc) {
DSI_DEBUG("failed populating other dsc params\n"); DSI_DEBUG("failed populating other dsc params\n");
rc = -EINVAL; rc = -EINVAL;
@@ -4188,12 +4189,6 @@ int dsi_panel_get_mode(struct dsi_panel *panel,
mutex_lock(&panel->panel_lock); mutex_lock(&panel->panel_lock);
utils = &panel->utils; 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; prv_info = mode->priv_info;
timings_np = utils->get_child_by_name(utils->data, timings_np = utils->get_child_by_name(utils->data,
@@ -4287,12 +4282,8 @@ int dsi_panel_get_mode(struct dsi_panel *panel,
if (rc) if (rc)
DSI_ERR("failed to partial update caps, rc=%d\n", rc); DSI_ERR("failed to partial update caps, rc=%d\n", rc);
} }
goto done;
parse_fail: parse_fail:
kfree(mode->priv_info);
mode->priv_info = NULL;
done:
utils->data = utils_data; utils->data = utils_data;
mutex_unlock(&panel->panel_lock); mutex_unlock(&panel->panel_lock);
return rc; return rc;

View File

@@ -286,8 +286,11 @@ enum msm_display_wd_jitter_type {
MSM_DISPLAY_WD_LTJ_JITTER = BIT(2), 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 * enum msm_display_spr_pack_type - sub pixel rendering pack patterns supported
@@ -719,11 +722,17 @@ struct msm_display_vdc_info {
*/ */
#define DSC_BPP(config) ((config).bits_per_pixel >> 4) #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 * struct msm_compression_info - defined panel compression
* @enabled: enabled/disabled * @enabled: enabled/disabled
* @comp_type: type of compression supported * @comp_type: type of compression supported
* @comp_ratio: compression ratio * @comp_ratio: compression ratio multiplied by 100
* @src_bpp: bits per pixel before compression * @src_bpp: bits per pixel before compression
* @tgt_bpp: bits per pixel after compression * @tgt_bpp: bits per pixel after compression
* @dsc_info: dsc configuration if the compression * @dsc_info: dsc configuration if the compression

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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. * 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_pic_width;
int dsc_common_mode = 0; int dsc_common_mode = 0;
int i, rc = 0; int i, rc = 0;
bool widebus_en;
sde_kms = sde_encoder_get_kms(&sde_enc->base); 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)) else if ((dsc_common_mode & DSC_MODE_MULTIPLEX) || (dsc->half_panel_pu))
dsc->num_active_ss_per_enc = dsc->config.slice_count >> 1; 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); _dce_dsc_initial_line_calc(dsc, enc_ip_w, dsc_common_mode);

View File

@@ -305,7 +305,7 @@ struct sde_encoder_irq {
* @intf_cfg_v1: Interface hardware configuration to be used if control * @intf_cfg_v1: Interface hardware configuration to be used if control
* path supports SDE_CTL_ACTIVE_CFG * path supports SDE_CTL_ACTIVE_CFG
* @comp_type: Type of compression supported * @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_pclk_cycle_cnt: Extra pclk cycle count for DSC over DP
* @dsc_extra_disp_width: Additional display width for DSC over DP * @dsc_extra_disp_width: Additional display width for DSC over DP
* @poms_align_vsync: poms with vsync aligned * @poms_align_vsync: poms with vsync aligned

View File

@@ -11,6 +11,7 @@
#include "sde_formats.h" #include "sde_formats.h"
#include "dsi_display.h" #include "dsi_display.h"
#include "sde_trace.h" #include "sde_trace.h"
#include <drm/drm_fixed.h>
#define SDE_DEBUG_VIDENC(e, fmt, ...) SDE_DEBUG("enc%d intf%d " fmt, \ #define SDE_DEBUG_VIDENC(e, fmt, ...) SDE_DEBUG("enc%d intf%d " fmt, \
(e) && (e)->base.parent ? \ (e) && (e)->base.parent ? \
@@ -48,6 +49,7 @@ static void drm_mode_to_intf_timing_params(
struct intf_timing_params *timing) struct intf_timing_params *timing)
{ {
const struct sde_encoder_phys *phys_enc = &vid_enc->base; const struct sde_encoder_phys *phys_enc = &vid_enc->base;
s64 comp_ratio, width;
memset(timing, 0, sizeof(*timing)); 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 && if (phys_enc->hw_intf->cap->type == INTF_DP &&
(timing->wide_bus_en || (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->width = timing->width >> 1;
timing->xres = timing->xres >> 1; timing->xres = timing->xres >> 1;
timing->h_back_porch = timing->h_back_porch >> 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; timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
if (vid_enc->base.comp_type == MSM_DISPLAY_COMPRESSION_DSC && 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 = timing->extra_dto_cycles =
vid_enc->base.dsc_extra_pclk_cycle_cnt; vid_enc->base.dsc_extra_pclk_cycle_cnt;
timing->width += vid_enc->base.dsc_extra_disp_width; 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 == (vid_enc->base.comp_type ==
MSM_DISPLAY_COMPRESSION_VDC))) { MSM_DISPLAY_COMPRESSION_VDC))) {
// adjust active dimensions // adjust active dimensions
timing->width = DIV_ROUND_UP(timing->width, width = drm_fixp_from_fraction(timing->width, 1);
vid_enc->base.comp_ratio); comp_ratio = drm_fixp_from_fraction(vid_enc->base.comp_ratio, 100);
timing->xres = DIV_ROUND_UP(timing->xres, width = drm_fixp_div(width, comp_ratio);
vid_enc->base.comp_ratio); timing->width = drm_fixp2int_ceil(width);
timing->xres = timing->width;
} }
/* /*

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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. * 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 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 mod_offset;
int slice_per_pkt, slice_per_intf; int slice_per_pkt, slice_per_intf;
int bytes_in_slice, total_bytes_per_intf; int bytes_in_slice, total_bytes_per_intf;
u16 bpp; u16 bpp;
u16 bpc;
u32 bytes_in_dsc_pair; u32 bytes_in_dsc_pair;
u32 total_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; slice_per_pkt = 1;
bpp = DSC_BPP(dsc_info->config); bpp = DSC_BPP(dsc_info->config);
bpc = DSC_BPC(dsc_info->config);
bytes_in_slice = DIV_ROUND_UP(dsc_info->config.slice_width * bytes_in_slice = DIV_ROUND_UP(dsc_info->config.slice_width *
bpp, 8); bpp, 8);
total_bytes_per_intf = bytes_in_slice * slice_per_intf; total_bytes_per_intf = bytes_in_slice * slice_per_intf;
dsc_info->eol_byte_num = total_bytes_per_intf % 3; 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_in_slice = bytes_in_slice;
dsc_info->bytes_per_pkt = bytes_in_slice * slice_per_pkt; dsc_info->bytes_per_pkt = bytes_in_slice * slice_per_pkt;
dsc_info->pkt_per_line = slice_per_intf / 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; return 0;
} }

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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. * 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_config(struct drm_dsc_config *dsc, int scr_ver);
int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info, 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, int sde_dsc_create_pps_buf_cmd(struct msm_display_dsc_info *dsc_info,
char *buf, int pps_id, u32 len); char *buf, int pps_id, u32 len);
#endif /* __SDE_DSC_HELPER_H__ */ #endif /* __SDE_DSC_HELPER_H__ */