Loading drivers/gpu/drm/msm/dp/dp_ctrl.c +17 −0 Original line number Diff line number Diff line Loading @@ -883,6 +883,9 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl, u32 x_int = 0, y_frac_enum = 0; u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp; if (panel->pinfo.comp_info.comp_ratio) bpp = panel->pinfo.comp_info.dsc_info.bpp; /* min_slot_cnt */ numerator = pclk * bpp * 64 * 1000; denominator = lclk * lanes * 8 * 1000; Loading @@ -898,6 +901,20 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl, denominator = drm_fixp_from_fraction(2, 1); raw_target_sc = drm_fixp_div(numerator, denominator); pr_debug("raw_target_sc before overhead:0x%llx\n", raw_target_sc); pr_debug("dsc_overhead_fp:0x%llx\n", panel->pinfo.dsc_overhead_fp); /* apply fec and dsc overhead factor */ if (panel->pinfo.dsc_overhead_fp) raw_target_sc = drm_fixp_mul(raw_target_sc, panel->pinfo.dsc_overhead_fp); if (panel->fec_overhead_fp) raw_target_sc = drm_fixp_mul(raw_target_sc, panel->fec_overhead_fp); pr_debug("raw_target_sc after overhead:0x%llx\n", raw_target_sc); /* target_sc */ temp = drm_fixp_from_fraction(256 * lanes, 1); numerator = drm_fixp_mul(raw_target_sc, temp); Loading drivers/gpu/drm/msm/dp/dp_mst_drm.c +34 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_crtc.h> #include <drm/drm_dp_mst_helper.h> #include <drm/drm_fixed.h> #include "msm_drv.h" #include "msm_kms.h" Loading @@ -36,7 +37,7 @@ #define HPD_STRING_SIZE 30 struct dp_drm_mst_fw_helper_ops { int (*calc_pbn_mode)(int clock, int bpp); int (*calc_pbn_mode)(struct dp_display_mode *dp_mode); int (*find_vcpi_slots)(struct drm_dp_mst_topology_mgr *mgr, int pbn); int (*atomic_find_vcpi_slots)(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, Loading Loading @@ -361,8 +362,35 @@ static void _dp_mst_get_vcpi_info( vcpi, *start_slot, *num_slots); } static int dp_mst_calc_pbn_mode(struct dp_display_mode *dp_mode) { int pbn, bpp; bool dsc_en; s64 pbn_fp; dsc_en = dp_mode->timing.comp_info.comp_ratio ? true : false; bpp = dsc_en ? dp_mode->timing.comp_info.dsc_info.bpp : dp_mode->timing.bpp; pbn = drm_dp_calc_pbn_mode(dp_mode->timing.pixel_clk_khz, bpp); pbn_fp = drm_fixp_from_fraction(pbn, 1); pr_debug("before overhead pbn:%d, bpp:%d\n", pbn, bpp); if (dsc_en) pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->dsc_overhead_fp); if (dp_mode->fec_overhead_fp) pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->fec_overhead_fp); pbn = drm_fixp2int(pbn_fp); pr_debug("after overhead pbn:%d, bpp:%d\n", pbn, bpp); return pbn; } static const struct dp_drm_mst_fw_helper_ops drm_dp_mst_fw_helper_ops = { .calc_pbn_mode = drm_dp_calc_pbn_mode, .calc_pbn_mode = dp_mst_calc_pbn_mode, .find_vcpi_slots = drm_dp_find_vcpi_slots, .atomic_find_vcpi_slots = drm_dp_atomic_find_vcpi_slots, .allocate_vcpi = drm_dp_mst_allocate_vcpi, Loading @@ -379,7 +407,7 @@ static const struct dp_drm_mst_fw_helper_ops drm_dp_mst_fw_helper_ops = { }; static const struct dp_drm_mst_fw_helper_ops drm_dp_sim_mst_fw_helper_ops = { .calc_pbn_mode = drm_dp_calc_pbn_mode, .calc_pbn_mode = dp_mst_calc_pbn_mode, .find_vcpi_slots = drm_dp_find_vcpi_slots, .atomic_find_vcpi_slots = drm_dp_atomic_find_vcpi_slots, .allocate_vcpi = drm_dp_mst_allocate_vcpi, Loading Loading @@ -465,8 +493,7 @@ static int _dp_mst_compute_config(struct drm_atomic_state *state, DP_MST_DEBUG("enter\n"); pbn = mst->mst_fw_cbs->calc_pbn_mode(mode->timing.pixel_clk_khz, mode->timing.bpp); pbn = mst->mst_fw_cbs->calc_pbn_mode(mode); slots = mst->mst_fw_cbs->atomic_find_vcpi_slots(state, &mst->mst_mgr, c_conn->mst_port, pbn); Loading Loading @@ -552,9 +579,7 @@ static void _dp_mst_bridge_pre_enable_part1(struct dp_mst_bridge *dp_bridge) return; } pbn = mst->mst_fw_cbs->calc_pbn_mode( dp_bridge->dp_mode.timing.pixel_clk_khz, dp_bridge->dp_mode.timing.bpp); pbn = mst->mst_fw_cbs->calc_pbn_mode(&dp_bridge->dp_mode); slots = mst->mst_fw_cbs->find_vcpi_slots(&mst->mst_mgr, pbn); Loading Loading @@ -1042,8 +1067,7 @@ enum drm_mode_status dp_mst_connector_mode_valid( dp_display->convert_to_dp_mode(dp_display, c_conn->drv_panel, mode, &dp_mode); required_pbn = mst->mst_fw_cbs->calc_pbn_mode( dp_mode.timing.pixel_clk_khz, dp_mode.timing.bpp); required_pbn = mst->mst_fw_cbs->calc_pbn_mode(&dp_mode); required_slots = mst->mst_fw_cbs->find_vcpi_slots( &mst->mst_mgr, required_pbn); Loading drivers/gpu/drm/msm/dp/dp_panel.c +17 −5 Original line number Diff line number Diff line Loading @@ -1256,8 +1256,12 @@ static void _dp_panel_dsc_bw_overhead_calc(struct dp_panel *dp_panel, dwidth_dsc_bytes = tot_num_hor_bytes + tot_num_eoc_symbols + tot_num_dummy_bytes; pr_debug("dwidth_dsc_bytes:%d, tot_num_hor_bytes:%d\n", dwidth_dsc_bytes, tot_num_hor_bytes); dp_mode->dsc_overhead_fp = drm_fixp_from_fraction(dwidth_dsc_bytes, tot_num_hor_bytes); dp_mode->timing.dsc_overhead_fp = dp_mode->dsc_overhead_fp; } static void dp_panel_dsc_pclk_param_calc(struct dp_panel *dp_panel, Loading Loading @@ -1535,10 +1539,12 @@ static int dp_panel_dsc_prepare_basic_params( comp_info->dsc_info.pic_height = dp_mode->timing.v_active; comp_info->dsc_info.slice_width = slice_width; if (comp_info->dsc_info.pic_height % 16) if (comp_info->dsc_info.pic_height % 16 == 0) comp_info->dsc_info.slice_height = 16; else if (comp_info->dsc_info.pic_height % 12 == 0) comp_info->dsc_info.slice_height = 12; else comp_info->dsc_info.slice_height = 16; comp_info->dsc_info.slice_height = 15; comp_info->dsc_info.bpc = dp_mode->timing.bpp / 3; comp_info->dsc_info.bpp = comp_info->dsc_info.bpc; Loading Loading @@ -1798,9 +1804,9 @@ static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) dp_panel->fec_en = dp_panel->dsc_en; dp_panel->widebus_en = dp_panel->dsc_en; /* fec_overhead = 1.00 / 0.7488664 */ /* fec_overhead = 1.00 / 0.97582 */ if (dp_panel->fec_en) fec_overhead_fp = drm_fixp_from_fraction(10000000, 7488664); fec_overhead_fp = drm_fixp_from_fraction(100000, 97582); dp_panel->fec_overhead_fp = fec_overhead_fp; } Loading @@ -1810,6 +1816,7 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) int rlen; struct dp_panel_private *panel; const int fec_cap = 0x90; int dpcd_rev; if (!dp_panel) { pr_err("invalid input\n"); Loading @@ -1819,9 +1826,12 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) dp_panel->dsc_en = false; dp_panel->fec_en = false; dpcd_rev = dp_panel->dpcd[DP_DPCD_REV]; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); if (panel->parser->dsc_feature_enable) { dp_panel->fec_overhead_fp = 0; if (panel->parser->dsc_feature_enable && dpcd_rev >= 0x14) { rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DSC_SUPPORT, dp_panel->dsc_dpcd, (DP_RECEIVER_DSC_CAP_SIZE + 1)); if (rlen < (DP_RECEIVER_DSC_CAP_SIZE + 1)) { Loading Loading @@ -2234,6 +2244,7 @@ static void dp_panel_config_dsc(struct dp_panel *dp_panel, bool enable) dsc->slice_per_pkt = comp_info->dsc_info.slice_per_pkt - 1; dsc->bytes_per_pkt = comp_info->dsc_info.bytes_per_pkt; dsc->bytes_per_pkt /= comp_info->dsc_info.slice_per_pkt; dsc->eol_byte_num = comp_info->dsc_info.eol_byte_num; dsc->dto_count = comp_info->dsc_info.pclk_per_line; dsc->be_in_lane = _dp_panel_calc_be_in_lane(dp_panel); Loading Loading @@ -2741,6 +2752,7 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel, dp_mode->timing.bpp, dp_mode->timing.pixel_clk_khz); dp_mode->timing.widebus_en = dp_panel->widebus_en; dp_mode->timing.dsc_overhead_fp = 0; if (dp_panel->dsc_en) { comp_info = &dp_mode->timing.comp_info; Loading drivers/gpu/drm/msm/dp/dp_panel.h +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct dp_panel_info { u32 bpp; bool widebus_en; struct msm_compression_info comp_info; s64 dsc_overhead_fp; }; struct dp_display_mode { Loading drivers/gpu/drm/msm/sde/sde_encoder.c +42 −16 Original line number Diff line number Diff line Loading @@ -236,6 +236,7 @@ struct sde_encoder_virt { struct sde_encoder_phys *cur_master; struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC]; enum sde_dsc dirty_dsc_ids[MAX_CHANNELS_PER_ENC]; bool intfs_swapped; Loading Loading @@ -1216,11 +1217,12 @@ static bool _sde_encoder_dsc_ich_reset_override_needed(bool pu_en, static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, struct sde_hw_pingpong *hw_pp, struct msm_display_dsc_info *dsc, u32 common_mode, bool ich_reset, bool enable) u32 common_mode, bool ich_reset, bool enable, struct sde_hw_pingpong *hw_dsc_pp) { if (!enable) { if (hw_pp && hw_pp->ops.disable_dsc) hw_pp->ops.disable_dsc(hw_pp); if (hw_dsc_pp && hw_dsc_pp->ops.disable_dsc) hw_dsc_pp->ops.disable_dsc(hw_dsc_pp); if (hw_dsc && hw_dsc->ops.dsc_disable) hw_dsc->ops.dsc_disable(hw_dsc); Loading @@ -1231,8 +1233,9 @@ static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, return; } if (!dsc || !hw_dsc || !hw_pp) { SDE_ERROR("invalid params %d %d %d\n", !dsc, !hw_dsc, !hw_pp); if (!dsc || !hw_dsc || !hw_pp || !hw_dsc_pp) { SDE_ERROR("invalid params %d %d %d %d\n", !dsc, !hw_dsc, !hw_pp, !hw_dsc_pp); return; } Loading @@ -1242,14 +1245,14 @@ static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, if (hw_dsc->ops.dsc_config_thresh) hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc); if (hw_pp->ops.setup_dsc) hw_pp->ops.setup_dsc(hw_pp); if (hw_dsc_pp->ops.setup_dsc) hw_dsc_pp->ops.setup_dsc(hw_dsc_pp); if (hw_dsc->ops.bind_pingpong_blk) hw_dsc->ops.bind_pingpong_blk(hw_dsc, true, hw_pp->idx); if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); if (hw_dsc_pp->ops.enable_dsc) hw_dsc_pp->ops.enable_dsc(hw_dsc_pp); } static void _sde_encoder_get_connector_roi( Loading Loading @@ -1278,6 +1281,7 @@ static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc) int ich_res, dsc_common_mode = 0; struct sde_hw_pingpong *hw_pp = sde_enc->hw_pp[0]; struct sde_hw_pingpong *hw_dsc_pp = sde_enc->hw_dsc_pp[0]; struct sde_hw_dsc *hw_dsc = sde_enc->hw_dsc[0]; struct sde_encoder_phys *enc_master = sde_enc->cur_master; const struct sde_rect *roi = &sde_enc->cur_conn_roi; Loading Loading @@ -1321,7 +1325,7 @@ static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc) SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode); _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res, true); ich_res, true, hw_dsc_pp); cfg.dsc[cfg.dsc_count++] = hw_dsc->idx; /* setup dsc active configuration in the control path */ Loading Loading @@ -1352,6 +1356,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, const struct sde_rect *roi = &sde_enc->cur_conn_roi; struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC]; struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC]; struct msm_mode_info mode_info; bool half_panel_partial_update; Loading @@ -1364,8 +1369,9 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp[i] = sde_enc->hw_pp[i]; hw_dsc[i] = sde_enc->hw_dsc[i]; hw_dsc_pp[i] = sde_enc->hw_dsc_pp[i]; if (!hw_pp[i] || !hw_dsc[i]) { if (!hw_pp[i] || !hw_dsc[i] || !hw_dsc_pp[i]) { SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n"); return -EINVAL; } Loading Loading @@ -1433,7 +1439,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode, i, active); _sde_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], &dsc[i], dsc_common_mode, ich_res, active); dsc_common_mode, ich_res, active, hw_dsc_pp[i]); if (active) { if (cfg.dsc_count >= MAX_DSC_PER_CTL_V1) { Loading Loading @@ -1473,6 +1479,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, const struct sde_rect *roi = &sde_enc->cur_conn_roi; struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC]; struct msm_display_dsc_info *dsc = NULL; struct msm_mode_info mode_info; bool half_panel_partial_update; Loading @@ -1485,8 +1492,9 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp[i] = sde_enc->hw_pp[i]; hw_dsc[i] = sde_enc->hw_dsc[i]; hw_dsc_pp[i] = sde_enc->hw_dsc_pp[i]; if (!hw_pp[i] || !hw_dsc[i]) { if (!hw_pp[i] || !hw_dsc[i] || !hw_dsc_pp[i]) { SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n"); return -EINVAL; } Loading Loading @@ -1531,7 +1539,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, dsc_common_mode, i, params->affected_displays); _sde_encoder_dsc_pipe_cfg(hw_dsc[0], hw_pp[0], dsc, dsc_common_mode, ich_res, true); ich_res, true, hw_dsc_pp[0]); cfg.dsc[0] = hw_dsc[0]->idx; cfg.dsc_count++; if (hw_ctl->ops.update_bitmask_dsc) Loading @@ -1539,7 +1547,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, _sde_encoder_dsc_pipe_cfg(hw_dsc[1], hw_pp[1], dsc, dsc_common_mode, ich_res, !half_panel_partial_update); ich_res, !half_panel_partial_update, hw_dsc_pp[1]); if (!half_panel_partial_update) { cfg.dsc[1] = hw_dsc[1]->idx; cfg.dsc_count++; Loading Loading @@ -1755,6 +1763,7 @@ static void _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc) { int i; struct sde_hw_pingpong *hw_pp = NULL; struct sde_hw_pingpong *hw_dsc_pp = NULL; struct sde_hw_dsc *hw_dsc = NULL; struct sde_hw_ctl *hw_ctl = NULL; struct sde_ctl_dsc_cfg cfg; Loading @@ -1773,8 +1782,10 @@ static void _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc) for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp = sde_enc->hw_pp[i]; hw_dsc = sde_enc->hw_dsc[i]; hw_dsc_pp = sde_enc->hw_dsc_pp[i]; _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, NULL, 0, 0, 0); _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, NULL, 0, 0, 0, hw_dsc_pp); if (hw_dsc) sde_enc->dirty_dsc_ids[i] = hw_dsc->idx; Loading Loading @@ -2669,6 +2680,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct sde_connector_state *sde_conn_state = NULL; struct sde_connector *sde_conn = NULL; struct sde_rm_hw_iter dsc_iter, pp_iter; struct sde_rm_hw_request request_hw; int i = 0, ret; if (!drm_enc) { Loading Loading @@ -2770,6 +2782,20 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, sde_enc->hw_dsc[i] = (struct sde_hw_dsc *) dsc_iter.hw; } /* Get PP for DSC configuration */ for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { sde_enc->hw_dsc_pp[i] = NULL; if (!sde_enc->hw_dsc[i]) continue; request_hw.id = sde_enc->hw_dsc[i]->base.id; request_hw.type = SDE_HW_BLK_PINGPONG; if (!sde_rm_request_hw_blk(&sde_kms->rm, &request_hw)) break; sde_enc->hw_dsc_pp[i] = (struct sde_hw_pingpong *) request_hw.hw; } for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading Loading
drivers/gpu/drm/msm/dp/dp_ctrl.c +17 −0 Original line number Diff line number Diff line Loading @@ -883,6 +883,9 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl, u32 x_int = 0, y_frac_enum = 0; u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp; if (panel->pinfo.comp_info.comp_ratio) bpp = panel->pinfo.comp_info.dsc_info.bpp; /* min_slot_cnt */ numerator = pclk * bpp * 64 * 1000; denominator = lclk * lanes * 8 * 1000; Loading @@ -898,6 +901,20 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl, denominator = drm_fixp_from_fraction(2, 1); raw_target_sc = drm_fixp_div(numerator, denominator); pr_debug("raw_target_sc before overhead:0x%llx\n", raw_target_sc); pr_debug("dsc_overhead_fp:0x%llx\n", panel->pinfo.dsc_overhead_fp); /* apply fec and dsc overhead factor */ if (panel->pinfo.dsc_overhead_fp) raw_target_sc = drm_fixp_mul(raw_target_sc, panel->pinfo.dsc_overhead_fp); if (panel->fec_overhead_fp) raw_target_sc = drm_fixp_mul(raw_target_sc, panel->fec_overhead_fp); pr_debug("raw_target_sc after overhead:0x%llx\n", raw_target_sc); /* target_sc */ temp = drm_fixp_from_fraction(256 * lanes, 1); numerator = drm_fixp_mul(raw_target_sc, temp); Loading
drivers/gpu/drm/msm/dp/dp_mst_drm.c +34 −10 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_crtc.h> #include <drm/drm_dp_mst_helper.h> #include <drm/drm_fixed.h> #include "msm_drv.h" #include "msm_kms.h" Loading @@ -36,7 +37,7 @@ #define HPD_STRING_SIZE 30 struct dp_drm_mst_fw_helper_ops { int (*calc_pbn_mode)(int clock, int bpp); int (*calc_pbn_mode)(struct dp_display_mode *dp_mode); int (*find_vcpi_slots)(struct drm_dp_mst_topology_mgr *mgr, int pbn); int (*atomic_find_vcpi_slots)(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, Loading Loading @@ -361,8 +362,35 @@ static void _dp_mst_get_vcpi_info( vcpi, *start_slot, *num_slots); } static int dp_mst_calc_pbn_mode(struct dp_display_mode *dp_mode) { int pbn, bpp; bool dsc_en; s64 pbn_fp; dsc_en = dp_mode->timing.comp_info.comp_ratio ? true : false; bpp = dsc_en ? dp_mode->timing.comp_info.dsc_info.bpp : dp_mode->timing.bpp; pbn = drm_dp_calc_pbn_mode(dp_mode->timing.pixel_clk_khz, bpp); pbn_fp = drm_fixp_from_fraction(pbn, 1); pr_debug("before overhead pbn:%d, bpp:%d\n", pbn, bpp); if (dsc_en) pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->dsc_overhead_fp); if (dp_mode->fec_overhead_fp) pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->fec_overhead_fp); pbn = drm_fixp2int(pbn_fp); pr_debug("after overhead pbn:%d, bpp:%d\n", pbn, bpp); return pbn; } static const struct dp_drm_mst_fw_helper_ops drm_dp_mst_fw_helper_ops = { .calc_pbn_mode = drm_dp_calc_pbn_mode, .calc_pbn_mode = dp_mst_calc_pbn_mode, .find_vcpi_slots = drm_dp_find_vcpi_slots, .atomic_find_vcpi_slots = drm_dp_atomic_find_vcpi_slots, .allocate_vcpi = drm_dp_mst_allocate_vcpi, Loading @@ -379,7 +407,7 @@ static const struct dp_drm_mst_fw_helper_ops drm_dp_mst_fw_helper_ops = { }; static const struct dp_drm_mst_fw_helper_ops drm_dp_sim_mst_fw_helper_ops = { .calc_pbn_mode = drm_dp_calc_pbn_mode, .calc_pbn_mode = dp_mst_calc_pbn_mode, .find_vcpi_slots = drm_dp_find_vcpi_slots, .atomic_find_vcpi_slots = drm_dp_atomic_find_vcpi_slots, .allocate_vcpi = drm_dp_mst_allocate_vcpi, Loading Loading @@ -465,8 +493,7 @@ static int _dp_mst_compute_config(struct drm_atomic_state *state, DP_MST_DEBUG("enter\n"); pbn = mst->mst_fw_cbs->calc_pbn_mode(mode->timing.pixel_clk_khz, mode->timing.bpp); pbn = mst->mst_fw_cbs->calc_pbn_mode(mode); slots = mst->mst_fw_cbs->atomic_find_vcpi_slots(state, &mst->mst_mgr, c_conn->mst_port, pbn); Loading Loading @@ -552,9 +579,7 @@ static void _dp_mst_bridge_pre_enable_part1(struct dp_mst_bridge *dp_bridge) return; } pbn = mst->mst_fw_cbs->calc_pbn_mode( dp_bridge->dp_mode.timing.pixel_clk_khz, dp_bridge->dp_mode.timing.bpp); pbn = mst->mst_fw_cbs->calc_pbn_mode(&dp_bridge->dp_mode); slots = mst->mst_fw_cbs->find_vcpi_slots(&mst->mst_mgr, pbn); Loading Loading @@ -1042,8 +1067,7 @@ enum drm_mode_status dp_mst_connector_mode_valid( dp_display->convert_to_dp_mode(dp_display, c_conn->drv_panel, mode, &dp_mode); required_pbn = mst->mst_fw_cbs->calc_pbn_mode( dp_mode.timing.pixel_clk_khz, dp_mode.timing.bpp); required_pbn = mst->mst_fw_cbs->calc_pbn_mode(&dp_mode); required_slots = mst->mst_fw_cbs->find_vcpi_slots( &mst->mst_mgr, required_pbn); Loading
drivers/gpu/drm/msm/dp/dp_panel.c +17 −5 Original line number Diff line number Diff line Loading @@ -1256,8 +1256,12 @@ static void _dp_panel_dsc_bw_overhead_calc(struct dp_panel *dp_panel, dwidth_dsc_bytes = tot_num_hor_bytes + tot_num_eoc_symbols + tot_num_dummy_bytes; pr_debug("dwidth_dsc_bytes:%d, tot_num_hor_bytes:%d\n", dwidth_dsc_bytes, tot_num_hor_bytes); dp_mode->dsc_overhead_fp = drm_fixp_from_fraction(dwidth_dsc_bytes, tot_num_hor_bytes); dp_mode->timing.dsc_overhead_fp = dp_mode->dsc_overhead_fp; } static void dp_panel_dsc_pclk_param_calc(struct dp_panel *dp_panel, Loading Loading @@ -1535,10 +1539,12 @@ static int dp_panel_dsc_prepare_basic_params( comp_info->dsc_info.pic_height = dp_mode->timing.v_active; comp_info->dsc_info.slice_width = slice_width; if (comp_info->dsc_info.pic_height % 16) if (comp_info->dsc_info.pic_height % 16 == 0) comp_info->dsc_info.slice_height = 16; else if (comp_info->dsc_info.pic_height % 12 == 0) comp_info->dsc_info.slice_height = 12; else comp_info->dsc_info.slice_height = 16; comp_info->dsc_info.slice_height = 15; comp_info->dsc_info.bpc = dp_mode->timing.bpp / 3; comp_info->dsc_info.bpp = comp_info->dsc_info.bpc; Loading Loading @@ -1798,9 +1804,9 @@ static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel) dp_panel->fec_en = dp_panel->dsc_en; dp_panel->widebus_en = dp_panel->dsc_en; /* fec_overhead = 1.00 / 0.7488664 */ /* fec_overhead = 1.00 / 0.97582 */ if (dp_panel->fec_en) fec_overhead_fp = drm_fixp_from_fraction(10000000, 7488664); fec_overhead_fp = drm_fixp_from_fraction(100000, 97582); dp_panel->fec_overhead_fp = fec_overhead_fp; } Loading @@ -1810,6 +1816,7 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) int rlen; struct dp_panel_private *panel; const int fec_cap = 0x90; int dpcd_rev; if (!dp_panel) { pr_err("invalid input\n"); Loading @@ -1819,9 +1826,12 @@ static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel) dp_panel->dsc_en = false; dp_panel->fec_en = false; dpcd_rev = dp_panel->dpcd[DP_DPCD_REV]; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); if (panel->parser->dsc_feature_enable) { dp_panel->fec_overhead_fp = 0; if (panel->parser->dsc_feature_enable && dpcd_rev >= 0x14) { rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DSC_SUPPORT, dp_panel->dsc_dpcd, (DP_RECEIVER_DSC_CAP_SIZE + 1)); if (rlen < (DP_RECEIVER_DSC_CAP_SIZE + 1)) { Loading Loading @@ -2234,6 +2244,7 @@ static void dp_panel_config_dsc(struct dp_panel *dp_panel, bool enable) dsc->slice_per_pkt = comp_info->dsc_info.slice_per_pkt - 1; dsc->bytes_per_pkt = comp_info->dsc_info.bytes_per_pkt; dsc->bytes_per_pkt /= comp_info->dsc_info.slice_per_pkt; dsc->eol_byte_num = comp_info->dsc_info.eol_byte_num; dsc->dto_count = comp_info->dsc_info.pclk_per_line; dsc->be_in_lane = _dp_panel_calc_be_in_lane(dp_panel); Loading Loading @@ -2741,6 +2752,7 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel, dp_mode->timing.bpp, dp_mode->timing.pixel_clk_khz); dp_mode->timing.widebus_en = dp_panel->widebus_en; dp_mode->timing.dsc_overhead_fp = 0; if (dp_panel->dsc_en) { comp_info = &dp_mode->timing.comp_info; Loading
drivers/gpu/drm/msm/dp/dp_panel.h +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct dp_panel_info { u32 bpp; bool widebus_en; struct msm_compression_info comp_info; s64 dsc_overhead_fp; }; struct dp_display_mode { Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +42 −16 Original line number Diff line number Diff line Loading @@ -236,6 +236,7 @@ struct sde_encoder_virt { struct sde_encoder_phys *cur_master; struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC]; enum sde_dsc dirty_dsc_ids[MAX_CHANNELS_PER_ENC]; bool intfs_swapped; Loading Loading @@ -1216,11 +1217,12 @@ static bool _sde_encoder_dsc_ich_reset_override_needed(bool pu_en, static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, struct sde_hw_pingpong *hw_pp, struct msm_display_dsc_info *dsc, u32 common_mode, bool ich_reset, bool enable) u32 common_mode, bool ich_reset, bool enable, struct sde_hw_pingpong *hw_dsc_pp) { if (!enable) { if (hw_pp && hw_pp->ops.disable_dsc) hw_pp->ops.disable_dsc(hw_pp); if (hw_dsc_pp && hw_dsc_pp->ops.disable_dsc) hw_dsc_pp->ops.disable_dsc(hw_dsc_pp); if (hw_dsc && hw_dsc->ops.dsc_disable) hw_dsc->ops.dsc_disable(hw_dsc); Loading @@ -1231,8 +1233,9 @@ static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, return; } if (!dsc || !hw_dsc || !hw_pp) { SDE_ERROR("invalid params %d %d %d\n", !dsc, !hw_dsc, !hw_pp); if (!dsc || !hw_dsc || !hw_pp || !hw_dsc_pp) { SDE_ERROR("invalid params %d %d %d %d\n", !dsc, !hw_dsc, !hw_pp, !hw_dsc_pp); return; } Loading @@ -1242,14 +1245,14 @@ static void _sde_encoder_dsc_pipe_cfg(struct sde_hw_dsc *hw_dsc, if (hw_dsc->ops.dsc_config_thresh) hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc); if (hw_pp->ops.setup_dsc) hw_pp->ops.setup_dsc(hw_pp); if (hw_dsc_pp->ops.setup_dsc) hw_dsc_pp->ops.setup_dsc(hw_dsc_pp); if (hw_dsc->ops.bind_pingpong_blk) hw_dsc->ops.bind_pingpong_blk(hw_dsc, true, hw_pp->idx); if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); if (hw_dsc_pp->ops.enable_dsc) hw_dsc_pp->ops.enable_dsc(hw_dsc_pp); } static void _sde_encoder_get_connector_roi( Loading Loading @@ -1278,6 +1281,7 @@ static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc) int ich_res, dsc_common_mode = 0; struct sde_hw_pingpong *hw_pp = sde_enc->hw_pp[0]; struct sde_hw_pingpong *hw_dsc_pp = sde_enc->hw_dsc_pp[0]; struct sde_hw_dsc *hw_dsc = sde_enc->hw_dsc[0]; struct sde_encoder_phys *enc_master = sde_enc->cur_master; const struct sde_rect *roi = &sde_enc->cur_conn_roi; Loading Loading @@ -1321,7 +1325,7 @@ static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc) SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode); _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res, true); ich_res, true, hw_dsc_pp); cfg.dsc[cfg.dsc_count++] = hw_dsc->idx; /* setup dsc active configuration in the control path */ Loading Loading @@ -1352,6 +1356,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, const struct sde_rect *roi = &sde_enc->cur_conn_roi; struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC]; struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC]; struct msm_mode_info mode_info; bool half_panel_partial_update; Loading @@ -1364,8 +1369,9 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp[i] = sde_enc->hw_pp[i]; hw_dsc[i] = sde_enc->hw_dsc[i]; hw_dsc_pp[i] = sde_enc->hw_dsc_pp[i]; if (!hw_pp[i] || !hw_dsc[i]) { if (!hw_pp[i] || !hw_dsc[i] || !hw_dsc_pp[i]) { SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n"); return -EINVAL; } Loading Loading @@ -1433,7 +1439,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode, i, active); _sde_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], &dsc[i], dsc_common_mode, ich_res, active); dsc_common_mode, ich_res, active, hw_dsc_pp[i]); if (active) { if (cfg.dsc_count >= MAX_DSC_PER_CTL_V1) { Loading Loading @@ -1473,6 +1479,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, const struct sde_rect *roi = &sde_enc->cur_conn_roi; struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC]; struct msm_display_dsc_info *dsc = NULL; struct msm_mode_info mode_info; bool half_panel_partial_update; Loading @@ -1485,8 +1492,9 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp[i] = sde_enc->hw_pp[i]; hw_dsc[i] = sde_enc->hw_dsc[i]; hw_dsc_pp[i] = sde_enc->hw_dsc_pp[i]; if (!hw_pp[i] || !hw_dsc[i]) { if (!hw_pp[i] || !hw_dsc[i] || !hw_dsc_pp[i]) { SDE_ERROR_ENC(sde_enc, "invalid params for DSC\n"); return -EINVAL; } Loading Loading @@ -1531,7 +1539,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, dsc_common_mode, i, params->affected_displays); _sde_encoder_dsc_pipe_cfg(hw_dsc[0], hw_pp[0], dsc, dsc_common_mode, ich_res, true); ich_res, true, hw_dsc_pp[0]); cfg.dsc[0] = hw_dsc[0]->idx; cfg.dsc_count++; if (hw_ctl->ops.update_bitmask_dsc) Loading @@ -1539,7 +1547,7 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc, _sde_encoder_dsc_pipe_cfg(hw_dsc[1], hw_pp[1], dsc, dsc_common_mode, ich_res, !half_panel_partial_update); ich_res, !half_panel_partial_update, hw_dsc_pp[1]); if (!half_panel_partial_update) { cfg.dsc[1] = hw_dsc[1]->idx; cfg.dsc_count++; Loading Loading @@ -1755,6 +1763,7 @@ static void _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc) { int i; struct sde_hw_pingpong *hw_pp = NULL; struct sde_hw_pingpong *hw_dsc_pp = NULL; struct sde_hw_dsc *hw_dsc = NULL; struct sde_hw_ctl *hw_ctl = NULL; struct sde_ctl_dsc_cfg cfg; Loading @@ -1773,8 +1782,10 @@ static void _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc) for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { hw_pp = sde_enc->hw_pp[i]; hw_dsc = sde_enc->hw_dsc[i]; hw_dsc_pp = sde_enc->hw_dsc_pp[i]; _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, NULL, 0, 0, 0); _sde_encoder_dsc_pipe_cfg(hw_dsc, hw_pp, NULL, 0, 0, 0, hw_dsc_pp); if (hw_dsc) sde_enc->dirty_dsc_ids[i] = hw_dsc->idx; Loading Loading @@ -2669,6 +2680,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct sde_connector_state *sde_conn_state = NULL; struct sde_connector *sde_conn = NULL; struct sde_rm_hw_iter dsc_iter, pp_iter; struct sde_rm_hw_request request_hw; int i = 0, ret; if (!drm_enc) { Loading Loading @@ -2770,6 +2782,20 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, sde_enc->hw_dsc[i] = (struct sde_hw_dsc *) dsc_iter.hw; } /* Get PP for DSC configuration */ for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { sde_enc->hw_dsc_pp[i] = NULL; if (!sde_enc->hw_dsc[i]) continue; request_hw.id = sde_enc->hw_dsc[i]->base.id; request_hw.type = SDE_HW_BLK_PINGPONG; if (!sde_rm_request_hw_blk(&sde_kms->rm, &request_hw)) break; sde_enc->hw_dsc_pp[i] = (struct sde_hw_pingpong *) request_hw.hw; } for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; Loading