disp: msm: dp: fix pbn value for MST RG calculation
The DP MST driver calculates the PBN value for each mode during mode enumeration. This PBN value is later used to calculate slot count and also MST RG parameters. But if DSC and/or FEC is enabled, then the slot calculation needs the PBN with overhead, but RG calculator needs the one without. But currently, the driver is using the PBN with overhead for both. This double counting of the overhead for RG calculation causes MST FIFO overflow for certain usecases. This change fixes this by caching both PBN values during mode enumeration and using the PBN value without overhead as input to RG calculation. Change-Id: Id58e91068c25202e6528a793ab736bc51732961f Signed-off-by: Rajkumar Subbiah <quic_rsubbia@quicinc.com>
Bu işleme şunda yer alıyor:
@@ -1122,7 +1122,7 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl,
|
||||
u64 lclk = 0;
|
||||
u64 lanes = ctrl->link->link_params.lane_count;
|
||||
u64 bpp = panel->pinfo.bpp;
|
||||
u64 pbn = panel->pbn;
|
||||
u64 pbn = panel->pinfo.pbn_no_overhead; // before dsc/fec overhead
|
||||
u64 numerator, denominator, temp, temp1, temp2;
|
||||
u32 x_int = 0, y_frac_enum = 0;
|
||||
u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp;
|
||||
|
@@ -2350,6 +2350,9 @@ static int dp_display_set_mode(struct dp_display *dp_display, void *panel,
|
||||
mode->timing.bpp = dp->panel->get_mode_bpp(dp->panel,
|
||||
mode->timing.bpp, mode->timing.pixel_clk_khz, dsc_en);
|
||||
|
||||
if (dp->mst.mst_active)
|
||||
dp->mst.cbs.set_mst_mode_params(&dp->dp_display, mode);
|
||||
|
||||
dp_panel->pinfo = mode->timing;
|
||||
mutex_unlock(&dp->session_lock);
|
||||
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, dp->state);
|
||||
|
@@ -24,6 +24,7 @@ struct dp_mst_drm_cbs {
|
||||
void (*set_drv_state)(void *dp_display,
|
||||
enum dp_drv_state mst_state);
|
||||
int (*set_mgr_state)(void *dp_display, bool state);
|
||||
void (*set_mst_mode_params)(void *dp_display, struct dp_display_mode *mode);
|
||||
};
|
||||
|
||||
struct dp_mst_drm_install_info {
|
||||
|
@@ -309,16 +309,14 @@ static int dp_mst_calc_pbn_mode(struct dp_display_mode *dp_mode)
|
||||
int pbn, bpp;
|
||||
bool dsc_en;
|
||||
s64 pbn_fp;
|
||||
struct dp_panel_info *pinfo = &dp_mode->timing;
|
||||
|
||||
dsc_en = dp_mode->timing.comp_info.enabled;
|
||||
bpp = dsc_en ?
|
||||
DSC_BPP(dp_mode->timing.comp_info.dsc_info.config)
|
||||
: dp_mode->timing.bpp;
|
||||
dsc_en = pinfo->comp_info.enabled;
|
||||
bpp = dsc_en ? DSC_BPP(pinfo->comp_info.dsc_info.config) : pinfo->bpp;
|
||||
|
||||
pbn = drm_dp_calc_pbn_mode(dp_mode->timing.pixel_clk_khz, bpp, false);
|
||||
pbn = drm_dp_calc_pbn_mode(pinfo->pixel_clk_khz, bpp, false);
|
||||
pbn_fp = drm_fixp_from_fraction(pbn, 1);
|
||||
|
||||
DP_DEBUG_V("before overhead pbn:%d, bpp:%d\n", pbn, bpp);
|
||||
pinfo->pbn_no_overhead = pbn;
|
||||
|
||||
if (dsc_en)
|
||||
pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->dsc_overhead_fp);
|
||||
@@ -327,8 +325,11 @@ static int dp_mst_calc_pbn_mode(struct dp_display_mode *dp_mode)
|
||||
pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->fec_overhead_fp);
|
||||
|
||||
pbn = drm_fixp2int(pbn_fp);
|
||||
pinfo->pbn = pbn;
|
||||
|
||||
DP_DEBUG_V("pbn before overhead:%d pbn final:%d, bpp:%d\n", pinfo->pbn_no_overhead, pbn,
|
||||
bpp);
|
||||
|
||||
DP_DEBUG_V("after overhead pbn:%d, bpp:%d\n", pbn, bpp);
|
||||
return pbn;
|
||||
}
|
||||
|
||||
@@ -2024,6 +2025,12 @@ static void dp_mst_set_state(void *dp_display, enum dp_drv_state mst_state)
|
||||
DP_MST_INFO("mst power state:%d\n", mst_state);
|
||||
}
|
||||
|
||||
static void dp_mst_display_set_mst_mode_params(void *dp_display, struct dp_display_mode *mode)
|
||||
{
|
||||
// update pbn values that will later be used for rg calculation
|
||||
dp_mst_calc_pbn_mode(mode);
|
||||
}
|
||||
|
||||
/* DP MST APIs */
|
||||
|
||||
static const struct dp_mst_drm_cbs dp_mst_display_cbs = {
|
||||
@@ -2031,6 +2038,7 @@ static const struct dp_mst_drm_cbs dp_mst_display_cbs = {
|
||||
.hpd_irq = dp_mst_display_hpd_irq,
|
||||
.set_drv_state = dp_mst_set_state,
|
||||
.set_mgr_state = dp_mst_display_set_mgr_state,
|
||||
.set_mst_mode_params = dp_mst_display_set_mst_mode_params,
|
||||
};
|
||||
|
||||
static const struct drm_dp_mst_topology_cbs dp_mst_drm_cbs = {
|
||||
|
@@ -64,6 +64,8 @@ struct dp_panel_info {
|
||||
bool widebus_en;
|
||||
struct msm_compression_info comp_info;
|
||||
s64 dsc_overhead_fp;
|
||||
u32 pbn_no_overhead;
|
||||
u32 pbn;
|
||||
};
|
||||
|
||||
struct dp_display_mode {
|
||||
|
Yeni konuda referans
Bir kullanıcı engelle