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

Commit 6701a612 authored by Jayaprakash Madisetty's avatar Jayaprakash Madisetty Committed by Jayaprakash
Browse files

disp: msm: sde: correct num_datapath during PM resume with CWB



In PM resume with CWB concurrency usecase, crtc pointer in
conn->state is NULL since drm_mode_config_reset operation is
performed on pm_resume. This change relies on conn_mask in
new_crtc_state for primary connector retrieval and also adds
get_num_lm_from_mode callback to DSI for LM count retrieval
from dsi panel topology. Existing get_mode_info api cannot
retrieve the topology info because mode->priv_info is NULL.
This occurs as WB encoder is added in the drm encoder_list
before primary encoder, introduced as part of commit d28ebf05
("disp: msm: sde: populate WB display encoder list before dsi").

Change-Id: I55358fd88ab778bd81475cf3628be13335de1cb5
Signed-off-by: default avatarJayaprakash Madisetty <jmadiset@codeaurora.org>
parent c93cae7d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -426,6 +426,14 @@ int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm);
 */
int dsi_display_get_qsync_min_fps(void *dsi_display, u32 mode_fps);

/**
 * dsi_conn_get_lm_from_mode() - retrieves LM count from dsi mode priv info
 * @display:            Handle to display.
 * @mode:               Pointer to DRM mode structure
 *
 * Return: LM count from dsi panel topology
 */
int dsi_conn_get_lm_from_mode(void *dsi_display, const struct drm_display_mode *mode);

/**
 * dsi_display_find_mode() - retrieve cached DSI mode given relevant params
+23 −0
Original line number Diff line number Diff line
@@ -511,6 +511,29 @@ u64 dsi_drm_find_bit_clk_rate(void *display,
	return bit_clk_rate;
}

int dsi_conn_get_lm_from_mode(void *display, const struct drm_display_mode *drm_mode)
{
	struct dsi_display *dsi_display = display;
	struct dsi_display_mode dsi_mode, *panel_dsi_mode;
	int rc = -EINVAL;

	if (!dsi_display || !drm_mode) {
		DSI_ERR("Invalid params %d %d\n", !display, !drm_mode);
		return rc;
	}

	convert_to_dsi_mode(drm_mode, &dsi_mode);

	rc = dsi_display_find_mode(dsi_display, &dsi_mode, &panel_dsi_mode);
	if (rc) {
		DSI_ERR("mode not found %d\n", rc);
		drm_mode_debug_printmodeline(drm_mode);
		return rc;
	}

	return panel_dsi_mode->priv_info->topology.num_lm;
}

int dsi_conn_get_mode_info(struct drm_connector *connector,
		const struct drm_display_mode *drm_mode,
		struct msm_mode_info *mode_info,
+14 −0
Original line number Diff line number Diff line
@@ -421,6 +421,20 @@ static void sde_connector_get_avail_res_info(struct drm_connector *conn,
	avail_res->max_mixer_width = sde_kms->catalog->max_mixer_width;
}

int sde_connector_get_lm_cnt_from_topology(struct drm_connector *conn,
		const struct drm_display_mode *drm_mode)
{
	struct sde_connector *c_conn;

	c_conn = to_sde_connector(conn);

	if (!c_conn || c_conn->connector_type != DRM_MODE_CONNECTOR_DSI ||
		!c_conn->ops.get_num_lm_from_mode)
		return -EINVAL;

	return c_conn->ops.get_num_lm_from_mode(c_conn->display, drm_mode);
}

int sde_connector_get_mode_info(struct drm_connector *conn,
		const struct drm_display_mode *drm_mode,
		struct msm_mode_info *mode_info)
+18 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _SDE_CONNECTOR_H_
@@ -382,6 +382,14 @@ struct sde_connector_ops {
	 * Returns: Qsync min fps value on success
	 */
	int (*get_qsync_min_fps)(void *display, u32 mode_fps);

	/**
	 * get_num_lm_from_mode - Get LM count from topology for this drm mode
	 * @display: Pointer to private display structure
	 * @mode: Pointer to drm mode info structure
	 */
	int (*get_num_lm_from_mode)(void *display, const struct drm_display_mode *mode);

};

/**
@@ -981,6 +989,15 @@ int sde_connector_helper_reset_custom_properties(
int sde_connector_state_get_mode_info(struct drm_connector_state *conn_state,
	struct msm_mode_info *mode_info);

/**
 * sde_connector_get_lm_cnt_from_topology - retrieves the topology info
 *	from the panel mode and returns the lm count.
 * conn: Pointer to DRM connector object
 * drm_mode: Pointer to the drm mode structure
 */
int sde_connector_get_lm_cnt_from_topology(struct drm_connector *conn,
	 const struct drm_display_mode *drm_mode);

/**
 * sde_connector_state_get_topology - get topology from given connector state
 * conn_state: Pointer to the DRM connector state object
+28 −11
Original line number Diff line number Diff line
@@ -5075,40 +5075,57 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
}

/**
 * sde_crtc_get_num_datapath - get the number of datapath active
 *				of primary connector
 * sde_crtc_get_num_datapath - get the number of layermixers active
 *				on primary connector
 * @crtc: Pointer to DRM crtc object
 * @connector: Pointer to DRM connector object of WB in CWB case
 * @virtual_conn: Pointer to DRM connector object of WB in CWB case
 * @crtc_state:	Pointer to DRM crtc state
 */
int sde_crtc_get_num_datapath(struct drm_crtc *crtc,
		struct drm_connector *connector)
	struct drm_connector *virtual_conn, struct drm_crtc_state *crtc_state)
{
	struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
	struct drm_connector *conn, *primary_conn = NULL;
	struct sde_connector_state *sde_conn_state = NULL;
	struct drm_connector *conn;
	struct drm_connector_list_iter conn_iter;
	int num_lm = 0;

	if (!sde_crtc || !connector) {
	if (!sde_crtc || !virtual_conn || !crtc_state) {
		SDE_DEBUG("Invalid argument\n");
		return 0;
	}

	/* return num_mixers used for primary when available in sde_crtc */
	if (sde_crtc->num_mixers)
		return sde_crtc->num_mixers;

	drm_connector_list_iter_begin(crtc->dev, &conn_iter);
	drm_for_each_connector_iter(conn, &conn_iter) {
		if (conn->state && conn->state->crtc == crtc &&
				 conn != connector)
		if ((drm_connector_mask(conn) & crtc_state->connector_mask)
			 && conn != virtual_conn) {
			sde_conn_state = to_sde_connector_state(conn->state);
			primary_conn = conn;
			break;
		}
	}

	drm_connector_list_iter_end(&conn_iter);

	/* if primary sde_conn_state has mode info available, return num_lm from here */
	if (sde_conn_state)
		return sde_conn_state->mode_info.topology.num_lm;
		num_lm = sde_conn_state->mode_info.topology.num_lm;

	return 0;
	/* if PM resume occurs with CWB enabled, retrieve num_lm from primary dsi panel mode */
	if (primary_conn && !num_lm) {
		num_lm = sde_connector_get_lm_cnt_from_topology(primary_conn,
				&crtc_state->adjusted_mode);
		if (num_lm < 0) {
			SDE_DEBUG("lm cnt fail for conn:%d num_lm:%d\n",
					 primary_conn->base.id, num_lm);
			num_lm = 0;
		}
	}

	return num_lm;
}

int sde_crtc_vblank(struct drm_crtc *crtc, bool en)
Loading