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

Commit 7c04b56c authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 1d5f7b89 on remote branch

Change-Id: I9ecd7676dc02dc23f65c18df530a6339e70df96c
parents 86fe4ea2 1d5f7b89
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 */

@@ -771,11 +772,16 @@ static int dp_aux_configure_aux_switch(struct dp_aux *dp_aux,
	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);

	if (!aux->aux_switch_node) {
		DP_DEBUG("undefined fsa4480 handle\n");
		DP_DEBUG("undefined aux switch handle\n");
		rc = -EINVAL;
		goto end;
	}

	if (strcmp(aux->aux_switch_node->name, "fsa4480")) {
		DP_DEBUG("Not an fsa4480 aux switch\n");
		goto end;
	}

	if (enable) {
		switch (orientation) {
		case ORIENTATION_CC1:
+2 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

@@ -2284,6 +2285,7 @@ struct dp_debug *dp_debug_get(struct dp_debug_in *in)
	dp_debug->dp_mst_connector_list.con_id = -1;
	dp_debug->dp_mst_connector_list.conn = NULL;
	dp_debug->dp_mst_connector_list.debug_en = false;
	mutex_init(&dp_debug->dp_mst_connector_list.lock);

	dp_debug->max_pclk_khz = debug->parser->max_pclk_khz;

+109 −40
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

@@ -721,6 +722,11 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp)
	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE,
			envp);

	if (dev->mode_config.funcs->output_poll_changed)
		dev->mode_config.funcs->output_poll_changed(dev);

	drm_client_dev_hotplug(dev);

	if (connector->status == connector_status_connected) {
		dp_display_state_add(DP_STATE_CONNECT_NOTIFIED);
		dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED);
@@ -976,6 +982,8 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)

	dp->dp_display.max_pclk_khz = min(dp->parser->max_pclk_khz,
					dp->debug->max_pclk_khz);
	dp->dp_display.max_hdisplay = dp->parser->max_hdisplay;
	dp->dp_display.max_vdisplay = dp->parser->max_vdisplay;

	/*
	 * If dp video session is not restored from a previous session teardown
@@ -2316,43 +2324,22 @@ static int dp_display_unprepare(struct dp_display *dp_display, void *panel)
	return 0;
}

static enum drm_mode_status dp_display_validate_mode(
static int dp_display_validate_resources(
		struct dp_display *dp_display,
		void *panel, struct drm_display_mode *mode,
		const struct msm_resource_caps_info *avail_res)
{
	struct dp_display_private *dp;
	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
	struct dp_panel *dp_panel;
	struct dp_debug *debug;
	enum drm_mode_status mode_status = MODE_BAD;
	bool in_list = false;
	struct dp_mst_connector *mst_connector;
	int hdis, vdis, vref, ar, _hdis, _vdis, _vref, _ar, rate;
	struct dp_display_mode dp_mode;
	u32 mode_rate_khz, supported_rate_khz, mode_bpp, num_lm;
	int rc, tmds_max_clock, rate;
	bool dsc_en;
	u32 num_lm = 0;
	int rc = 0, tmds_max_clock = 0;

	if (!dp_display || !mode || !panel ||
			!avail_res || !avail_res->max_mixer_width) {
		DP_ERR("invalid params\n");
		return mode_status;
	}

	dp = container_of(dp_display, struct dp_display_private, dp_display);

	mutex_lock(&dp->session_lock);

	dp_panel = panel;
	if (!dp_panel->connector) {
		DP_ERR("invalid connector\n");
		goto end;
	}

	debug = dp->debug;
	if (!debug)
		goto end;

	dp_display->convert_to_dp_mode(dp_display, panel, mode, &dp_mode);

@@ -2366,36 +2353,65 @@ static enum drm_mode_status dp_display_validate_mode(
	tmds_max_clock = dp_panel->connector->display_info.max_tmds_clock;

	if (mode_rate_khz > supported_rate_khz) {
		DP_MST_DEBUG("pclk:%d, supported_rate:%d\n",
		DP_DEBUG("pclk:%d, supported_rate:%d\n",
				mode->clock, supported_rate_khz);
		goto end;
		return -EINVAL;
	}

	if (mode->clock > dp_display->max_pclk_khz) {
		DP_MST_DEBUG("clk:%d, max:%d\n", mode->clock,
		DP_DEBUG("clk:%d, max:%d\n", mode->clock,
				dp_display->max_pclk_khz);
		goto end;
		return -EINVAL;
	}

	if ((dp_display->max_hdisplay > 0) && (dp_display->max_vdisplay > 0) &&
			((mode->hdisplay > dp_display->max_hdisplay) ||
			(mode->vdisplay > dp_display->max_vdisplay))) {
		DP_DEBUG("hdisplay:%d, max-hdisplay:%d",
			mode->hdisplay, dp_display->max_hdisplay);
		DP_DEBUG("vdisplay:%d, max-vdisplay:%d\n",
			mode->vdisplay, dp_display->max_vdisplay);
		return -EINVAL;
	}

	if (tmds_max_clock > 0 && mode->clock > tmds_max_clock) {
		DP_MST_DEBUG("clk:%d, max tmds:%d\n", mode->clock,
		DP_DEBUG("clk:%d, max tmds:%d\n", mode->clock,
				tmds_max_clock);
		goto end;
		return -EINVAL;
	}

	rc = msm_get_mixer_count(dp->priv, mode, avail_res, &num_lm);
	if (rc) {
		DP_ERR("error getting mixer count. rc:%d\n", rc);
		goto end;
		return -EINVAL;
	}

	if (num_lm > avail_res->num_lm ||
			(num_lm == 2 && !avail_res->num_3dmux)) {
		DP_MST_DEBUG("num_lm:%d, req lm:%d 3dmux:%d\n", num_lm,
		DP_DEBUG("num_lm:%d, req lm:%d 3dmux:%d\n", num_lm,
				avail_res->num_lm, avail_res->num_3dmux);
		goto end;
		return -EINVAL;
	}

	return 0;
}

static int dp_display_check_overrides(
		struct dp_display *dp_display,
		void *panel, struct drm_display_mode *mode,
		const struct msm_resource_caps_info *avail_res)
{
	struct dp_mst_connector *mst_connector;
	struct dp_display_private *dp;
	struct dp_panel *dp_panel;
	struct dp_debug *debug;
	bool in_list = false;
	int hdis, vdis, vref, ar, _hdis, _vdis, _vref, _ar;

	dp = container_of(dp_display, struct dp_display_private, dp_display);
	dp_panel = panel;
	debug = dp->debug;

	/*
	 * If the connector exists in the mst connector list and if debug is
	 * enabled for that connector, use the mst connector settings from the
@@ -2404,6 +2420,7 @@ static enum drm_mode_status dp_display_validate_mode(
	mutex_lock(&debug->dp_mst_connector_list.lock);

	if (list_empty(&debug->dp_mst_connector_list.list)) {
		DP_MST_DEBUG("MST connect list is empty\n");
		mutex_unlock(&debug->dp_mst_connector_list.lock);
		goto verify_default;
	}
@@ -2414,10 +2431,9 @@ static enum drm_mode_status dp_display_validate_mode(
			in_list = true;

			if (!mst_connector->debug_en) {
				mode_status = MODE_OK;
				mutex_unlock(
				&debug->dp_mst_connector_list.lock);
				goto end;
				return 0;
			}

			hdis = mst_connector->hdisplay;
@@ -2432,28 +2448,76 @@ static enum drm_mode_status dp_display_validate_mode(

			if (hdis == _hdis && vdis == _vdis && vref == _vref &&
					ar == _ar) {
				mode_status = MODE_OK;
				mutex_unlock(
				&debug->dp_mst_connector_list.lock);
				goto end;
				return 0;
			}

			break;
		}
	}

	mutex_unlock(&debug->dp_mst_connector_list.lock);

	if (in_list)
		goto end;
		return -EINVAL;

verify_default:
	if (debug->debug_en && (mode->hdisplay != debug->hdisplay ||
			mode->vdisplay != debug->vdisplay ||
			mode->vrefresh != debug->vrefresh ||
			mode->picture_aspect_ratio != debug->aspect_ratio))
		return -EINVAL;

	return 0;
}

static enum drm_mode_status dp_display_validate_mode(
		struct dp_display *dp_display,
		void *panel, struct drm_display_mode *mode,
		const struct msm_resource_caps_info *avail_res)
{
	struct dp_display_private *dp;

	struct dp_panel *dp_panel;
	struct dp_debug *debug;
	enum drm_mode_status mode_status = MODE_BAD;

	if (!dp_display || !mode || !panel ||
			!avail_res || !avail_res->max_mixer_width) {
		DP_ERR("invalid params\n");
		return mode_status;
	}

	dp = container_of(dp_display, struct dp_display_private, dp_display);

	mutex_lock(&dp->session_lock);

	dp_panel = panel;
	if (!dp_panel->connector) {
		DP_ERR("invalid connector\n");
		goto end;
	}

	debug = dp->debug;
	if (!debug) {
		DP_ERR("invalid debug node\n");
		goto end;
	}

	if (dp_display_validate_resources(dp_display, panel, mode, avail_res)) {
		DP_DEBUG("DP bad mode %dx%d@%d\n",
			mode->hdisplay, mode->vdisplay, mode->clock);
		goto end;
	}

	if (dp_display_check_overrides(dp_display, panel,
				mode, avail_res)) {
		DP_MST_DEBUG("DP overrides ignore mode %dx%d@%d\n",
			mode->hdisplay, mode->vdisplay, mode->clock);
		goto end;
	}

	DP_DEBUG("DP ok mode %dx%d@%d\n",
			mode->hdisplay, mode->vdisplay, mode->clock);
	mode_status = MODE_OK;
end:
	mutex_unlock(&dp->session_lock);
@@ -2656,6 +2720,11 @@ static int dp_display_init_aux_switch(struct dp_display_private *dp)
		goto end;
	}

	if (strcmp(dp->aux_switch_node->name, "fsa4480")) {
		DP_DEBUG("Not an fsa4480 aux switch\n");
		goto end;
	}

	nb.notifier_call = dp_display_fsa4480_callback;
	nb.priority = 0;

+3 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */

@@ -70,6 +71,8 @@ struct dp_display {
	bool is_sst_connected;
	bool is_mst_supported;
	u32 max_pclk_khz;
	u32 max_hdisplay;
	u32 max_vdisplay;
	u32 no_mst_encoder;
	void *dp_mst_prv_info;
	bool is_primary;
+11 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
 */

@@ -170,6 +171,16 @@ static int dp_parser_misc(struct dp_parser *parser)
	if (!parser->display_type)
		parser->display_type = "unknown";

	rc = of_property_read_u32(of_node,
		"qcom,max-hdisplay", &parser->max_hdisplay);
	if (rc)
		parser->max_hdisplay = 0;

	rc = of_property_read_u32(of_node,
		"qcom,max-vdisplay", &parser->max_vdisplay);
	if (rc)
		parser->max_vdisplay = 0;

	return 0;
}

Loading