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

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

Merge "Merge remote-tracking branch 'quic/dev/msm-4.14-display' into msm-4.14"

parents 6bdd790d 275317b5
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 {
+42 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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;
	}

@@ -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(
@@ -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;
@@ -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 */
@@ -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;
@@ -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;
		}
@@ -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) {
@@ -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;
@@ -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;
		}
@@ -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)
@@ -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++;
@@ -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;
@@ -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;
@@ -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) {
@@ -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