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

Commit 1d8b3d68 authored by Govinda Rajulu Chenna's avatar Govinda Rajulu Chenna Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/dp: check for dsc resources before enabling dsc



Parse the dsc resource capabilities available for platform
and enable dsc only if enough dsc resources are available
for the selected display mode of the stream/panel.

CRs-Fixed: 2325207
Change-Id: I01e50b5504c324361c7d62dbdaf78ef3da5bad33
Signed-off-by: default avatarGovinda Rajulu Chenna <gchenna@codeaurora.org>
parent abe1cb8f
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ struct dp_display_private {
	u32 active_stream_cnt;
	struct dp_mst mst;

	u32 tot_dsc_blks_in_use;

	struct notifier_block usb_nb;
};

@@ -1255,6 +1257,8 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
		goto error_debug;
	}

	dp->tot_dsc_blks_in_use = 0;

	dp->debug->hdcp_disabled = hdcp_disabled;
	dp_display_update_hdcp_status(dp, true);

@@ -1456,6 +1460,29 @@ static int dp_display_set_stream_info(struct dp_display *dp_display,
	return rc;
}

static void dp_display_update_dsc_resources(struct dp_display_private *dp,
		struct dp_panel *panel, bool enable)
{
	u32 dsc_blk_cnt = 0;

	if (panel->pinfo.comp_info.comp_type == MSM_DISPLAY_COMPRESSION_DSC &&
		panel->pinfo.comp_info.comp_ratio) {
		dsc_blk_cnt = panel->pinfo.h_active /
				dp->parser->max_dp_dsc_input_width_pixs;
		if (panel->pinfo.h_active %
				dp->parser->max_dp_dsc_input_width_pixs)
			dsc_blk_cnt++;
	}

	if (enable) {
		dp->tot_dsc_blks_in_use += dsc_blk_cnt;
		panel->tot_dsc_blks_in_use += dsc_blk_cnt;
	} else {
		dp->tot_dsc_blks_in_use -= dsc_blk_cnt;
		panel->tot_dsc_blks_in_use -= dsc_blk_cnt;
	}
}

static int dp_display_enable(struct dp_display *dp_display, void *panel)
{
	int rc = 0;
@@ -1479,6 +1506,7 @@ static int dp_display_enable(struct dp_display *dp_display, void *panel)
	if (rc)
		goto end;

	dp_display_update_dsc_resources(dp, panel, true);
	dp->power_on = true;
end:
	mutex_unlock(&dp->session_lock);
@@ -1599,6 +1627,7 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel)
	}

	dp_display_stream_disable(dp, dp_panel);
	dp_display_update_dsc_resources(dp, dp_panel, false);
end:
	mutex_unlock(&dp->session_lock);
	return 0;
@@ -1861,6 +1890,7 @@ static void dp_display_convert_to_dp_mode(struct dp_display *dp_display,
{
	struct dp_display_private *dp;
	struct dp_panel *dp_panel;
	u32 free_dsc_blks = 0, required_dsc_blks = 0;

	if (!dp_display || !drm_mode || !dp_mode || !panel) {
		pr_err("invalid input\n");
@@ -1871,6 +1901,23 @@ static void dp_display_convert_to_dp_mode(struct dp_display *dp_display,
	dp_panel = panel;

	memset(dp_mode, 0, sizeof(*dp_mode));

	free_dsc_blks = dp->parser->max_dp_dsc_blks -
				dp->tot_dsc_blks_in_use +
				dp_panel->tot_dsc_blks_in_use;
	required_dsc_blks = drm_mode->hdisplay /
				dp->parser->max_dp_dsc_input_width_pixs;
	if (drm_mode->hdisplay % dp->parser->max_dp_dsc_input_width_pixs)
		required_dsc_blks++;

	if (free_dsc_blks >= required_dsc_blks)
		dp_mode->capabilities |= DP_PANEL_CAPS_DSC;

	pr_debug("in_use:%d, max:%d, free:%d, req:%d, caps:0x%x, width:%d",
			dp->tot_dsc_blks_in_use, dp->parser->max_dp_dsc_blks,
			free_dsc_blks, required_dsc_blks, dp_mode->capabilities,
			dp->parser->max_dp_dsc_input_width_pixs);

	dp_panel->convert_to_dp_mode(dp_panel, drm_mode, dp_mode);
}

+6 −3
Original line number Diff line number Diff line
@@ -375,8 +375,10 @@ int dp_connector_get_mode_info(struct drm_connector *connector,
	struct sde_connector *sde_conn;
	struct dp_panel *dp_panel;
	struct dp_display_mode dp_mode;
	struct dp_display *dp_disp = display;

	if (!drm_mode || !mode_info || !max_mixer_width || !connector) {
	if (!drm_mode || !mode_info || !max_mixer_width || !connector ||
			!display) {
		pr_err("invalid params\n");
		return -EINVAL;
	}
@@ -397,8 +399,9 @@ int dp_connector_get_mode_info(struct drm_connector *connector,

	mode_info->wide_bus_en = dp_panel->widebus_en;

	if (dp_panel->dsc_en) {
		dp_panel->convert_to_dp_mode(dp_panel, drm_mode, &dp_mode);
	dp_disp->convert_to_dp_mode(dp_disp, dp_panel, drm_mode, &dp_mode);

	if (dp_mode.timing.comp_info.comp_ratio) {
		memcpy(&mode_info->comp_info,
			&dp_mode.timing.comp_info,
			sizeof(mode_info->comp_info));
+3 −1
Original line number Diff line number Diff line
@@ -2722,6 +2722,8 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel,
{
	const u32 num_components = 3, default_bpp = 24;
	struct msm_compression_info *comp_info;
	bool dsc_cap = (dp_mode->capabilities & DP_PANEL_CAPS_DSC) ?
				true : false;

	dp_mode->timing.h_active = drm_mode->hdisplay;
	dp_mode->timing.h_back_porch = drm_mode->htotal - drm_mode->hsync_end;
@@ -2760,7 +2762,7 @@ static void dp_panel_convert_to_dp_mode(struct dp_panel *dp_panel,
	dp_mode->timing.widebus_en = dp_panel->widebus_en;
	dp_mode->timing.dsc_overhead_fp = 0;

	if (dp_panel->dsc_en) {
	if (dp_panel->dsc_en && dsc_cap) {
		comp_info = &dp_mode->timing.comp_info;

		if (dp_panel_dsc_prepare_basic_params(comp_info,
+3 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ struct dp_dsc_caps {

struct dp_audio;

#define DP_PANEL_CAPS_DSC	BIT(0)

struct dp_panel {
	/* dpcd raw data */
	u8 dpcd[DP_RECEIVER_CAP_SIZE + 1];
@@ -121,6 +123,7 @@ struct dp_panel {
	u32 channel_total_slots;
	u32 pbn;

	u32 tot_dsc_blks_in_use;
	/* DRM connector assosiated with this panel */
	struct drm_connector *connector;

+16 −2
Original line number Diff line number Diff line
@@ -695,13 +695,27 @@ static int dp_parser_mst(struct dp_parser *parser)

static void dp_parser_dsc(struct dp_parser *parser)
{
	int rc;
	struct device *dev = &parser->pdev->dev;

	parser->dsc_feature_enable = of_property_read_bool(dev->of_node,
			"qcom,dsc-feature-enable");

	pr_debug("dsc parsing successful. dsc:%d\n",
			parser->dsc_feature_enable);
	rc = of_property_read_u32(dev->of_node,
		"qcom,max-dp-dsc-blks", &parser->max_dp_dsc_blks);
	if (rc || !parser->max_dp_dsc_blks)
		parser->dsc_feature_enable = false;

	rc = of_property_read_u32(dev->of_node,
		"qcom,max-dp-dsc-input-width-pixs",
		&parser->max_dp_dsc_input_width_pixs);
	if (rc || !parser->max_dp_dsc_input_width_pixs)
		parser->dsc_feature_enable = false;

	pr_debug("dsc parsing successful. dsc:%d, blks:%d, width:%d\n",
			parser->dsc_feature_enable,
			parser->max_dp_dsc_blks,
			parser->max_dp_dsc_input_width_pixs);
}

static void dp_parser_fec(struct dp_parser *parser)
Loading