Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88033a60 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dp: check dpcd version before dsc dpcd read"

parents c9979434 fee5038e
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
+34 −10
Original line number Diff line number Diff line
@@ -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"
@@ -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,
@@ -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,
@@ -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,
@@ -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);
@@ -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);

@@ -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);

+17 −5
Original line number Diff line number Diff line
@@ -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,
@@ -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;
@@ -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;
}
@@ -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");
@@ -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)) {
@@ -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);
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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 {