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

Commit 184d6620 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: populate display topology in atomic check"

parents b7e6543b 586d0920
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -367,6 +367,14 @@ Optional properties:
				match the number of xin-ids defined in
				property: qcom,sde-inline-rot-xin
- #power-domain-cells:		Number of cells in a power-domain specifier and should contain 0.
- qcom,sde-mixer-display-pref:  A string array indicating the preferred display type
				for the mixer block. Possible values:
				"primary" - preferred for primary display
				"none" - no preference on display
- qcom,sde-ctl-display-pref:    A string array indicating the preferred display type
                                for the ctl block. Possible values:
				"primary" - preferred for primary display
				"none" - no preference on display

Bus Scaling Subnodes:
- qcom,sde-reg-bus:		Property to provide Bus scaling for register access for
@@ -452,8 +460,12 @@ Example:
    qcom,sde-off = <0x1000>;
    qcom,sde-ctl-off = <0x00002000 0x00002200 0x00002400
		     0x00002600 0x00002800>;
    qcom,sde-ctl-display-pref = "primary", "none", "none",
	             "none", "none";
    qcom,sde-mixer-off = <0x00045000 0x00046000
			0x00047000 0x0004a000>;
    qcom,sde-mixer-display-pref = "primary", "none",
	                "none", "none";
    qcom,sde-dspp-top-off = <0x1300>;
    qcom,sde-dspp-off = <0x00055000 0x00057000>;
    qcom,sde-dspp-ad-off = <0x24000 0x22800>;
+5 −2
Original line number Diff line number Diff line
@@ -55,10 +55,13 @@
		qcom,sde-ctl-off = <0x2000 0x2200 0x2400
				     0x2600 0x2800>;
		qcom,sde-ctl-size = <0xE4>;
		qcom,sde-ctl-display-pref = "primary", "primary", "none",
					    "none", "none";

		qcom,sde-mixer-off = <0x45000 0x46000 0x47000
				      0x48000 0x49000 0x4a000>;
		qcom,sde-mixer-off = <0x45000 0x46000 0x47000 0 0 0x4a000>;
		qcom,sde-mixer-size = <0x320>;
		qcom,sde-mixer-display-pref = "primary", "primary", "none",
					      "none", "none", "none";

		qcom,sde-dspp-top-off = <0x1300>;
		qcom,sde-dspp-top-size = <0xc>;
+3 −3
Original line number Diff line number Diff line
@@ -319,7 +319,7 @@ struct sde_connector {
 * Returns: Pointer to associated private display structure
 */
#define sde_connector_get_display(C) \
	((C) ? to_sde_connector((C))->display : 0)
	((C) ? to_sde_connector((C))->display : NULL)

/**
 * sde_connector_get_panel - get sde connector's private panel pointer
@@ -335,7 +335,7 @@ struct sde_connector {
 * Returns: Pointer to associated private encoder structure
 */
#define sde_connector_get_encoder(C) \
	((C) ? to_sde_connector((C))->encoder : 0)
	((C) ? to_sde_connector((C))->encoder : NULL)

/**
 * sde_connector_get_propinfo - get sde connector's property info pointer
@@ -343,7 +343,7 @@ struct sde_connector {
 * Returns: Pointer to associated private property info structure
 */
#define sde_connector_get_propinfo(C) \
	((C) ? &to_sde_connector((C))->property_info : 0)
	((C) ? &to_sde_connector((C))->property_info : NULL)

/**
 * struct sde_connector_state - private connector status structure
+47 −91
Original line number Diff line number Diff line
@@ -194,7 +194,6 @@ enum sde_enc_rc_states {
 *				clks and resources after IDLE_TIMEOUT time.
 * @vsync_event_work:		worker to handle vsync event for autorefresh
 * @topology:                   topology of the display
 * @mode_set_complete:          flag to indicate modeset completion
 * @rsc_config:			rsc configuration for display vtotal, fps, etc.
 * @cur_conn_roi:		current connector roi
 * @prv_conn_roi:		previous connector roi to optimize if unchanged
@@ -241,7 +240,6 @@ struct sde_encoder_virt {
	struct kthread_delayed_work delayed_off_work;
	struct kthread_work vsync_event_work;
	struct msm_display_topology topology;
	bool mode_set_complete;

	struct sde_rsc_cmd_config rsc_config;
	struct sde_rect cur_conn_roi;
@@ -559,6 +557,7 @@ void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc,
	}

	hw_res->topology = sde_enc->mode_info.topology;
	hw_res->is_primary = sde_enc->disp_info.is_primary;
}

void sde_encoder_destroy(struct drm_encoder *drm_enc)
@@ -697,6 +696,7 @@ static int sde_encoder_virt_atomic_check(
	struct sde_kms *sde_kms;
	const struct drm_display_mode *mode;
	struct drm_display_mode *adj_mode;
	struct sde_connector *sde_conn = NULL;
	int i = 0;
	int ret = 0;

@@ -713,6 +713,7 @@ static int sde_encoder_virt_atomic_check(
	sde_kms = to_sde_kms(priv->kms);
	mode = &crtc_state->mode;
	adj_mode = &crtc_state->adjusted_mode;
	sde_conn = to_sde_connector(conn_state->connector);
	SDE_EVT32(DRMID(drm_enc));

	/*
@@ -742,17 +743,42 @@ static int sde_encoder_virt_atomic_check(
		}
	}

	/* Reserve dynamic resources now. Indicating AtomicTest phase */
	if (!ret) {
		/*
		 * Avoid reserving resources when mode set is pending. Topology
		 * info may not be available to complete reservation.
		 */
		if (drm_atomic_crtc_needs_modeset(crtc_state)
				&& sde_enc->mode_set_complete) {

	if (!ret && sde_conn && drm_atomic_crtc_needs_modeset(crtc_state)) {
		struct msm_display_topology *topology = NULL;

		ret = sde_conn->ops.get_mode_info(adj_mode,
				&sde_enc->mode_info,
				sde_kms->catalog->max_mixer_width);
		if (ret) {
			SDE_ERROR_ENC(sde_enc,
				"failed to get mode info, rc = %d\n", ret);
			return ret;
		}

		/* Reserve dynamic resources, indicating atomic_check phase */
		ret = sde_rm_reserve(&sde_kms->rm, drm_enc, crtc_state,
			conn_state, true);
			sde_enc->mode_set_complete = false;
		if (ret) {
			SDE_ERROR_ENC(sde_enc,
				"RM failed to reserve resources, rc = %d\n",
				ret);
			return ret;
		}

		/**
		 * Update connector state with the topology selected for the
		 * resource set validated. Reset the topology if we are
		 * de-activating crtc.
		 */
		if (crtc_state->active)
			topology = &sde_enc->mode_info.topology;

		ret = sde_rm_update_topology(conn_state, topology);
		if (ret) {
			SDE_ERROR_ENC(sde_enc,
				"RM failed to update topology, rc: %d\n", ret);
			return ret;
		}
	}

@@ -1243,13 +1269,9 @@ static void _sde_encoder_update_vsync_source(struct sde_encoder_virt *sde_enc,

static int _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc)
{
	enum sde_rm_topology_name topology;
	struct drm_connector *drm_conn;
	int i, ret = 0;
	struct sde_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
	struct sde_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC] = {NULL};
	int pp_count = 0;
	int dsc_count = 0;
	struct sde_hw_pingpong *hw_pp = NULL;
	struct sde_hw_dsc *hw_dsc = NULL;

	if (!sde_enc || !sde_enc->phys_encs[0] ||
			!sde_enc->phys_encs[0]->connector) {
@@ -1258,80 +1280,16 @@ static int _sde_encoder_dsc_disable(struct sde_encoder_virt *sde_enc)
		return -EINVAL;
	}

	drm_conn = sde_enc->phys_encs[0]->connector;

	topology = sde_connector_get_topology_name(drm_conn);
	if (topology == SDE_RM_TOPOLOGY_NONE) {
		SDE_ERROR_ENC(sde_enc, "topology not set yet\n");
		return -EINVAL;
	}

	switch (topology) {
	case SDE_RM_TOPOLOGY_SINGLEPIPE:
	case SDE_RM_TOPOLOGY_SINGLEPIPE_DSC:
		/* single PP */
		hw_pp[0] = sde_enc->hw_pp[0];
		hw_dsc[0] = sde_enc->hw_dsc[0];
		pp_count = 1;
		dsc_count = 1;
		break;
	case SDE_RM_TOPOLOGY_DUALPIPE_DSC:
	case SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC:
	case SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE:
		/* dual dsc */
		for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
			hw_dsc[i] = sde_enc->hw_dsc[i];
			if (hw_dsc[i])
				dsc_count++;
		}
		/* fall through */
	case SDE_RM_TOPOLOGY_DUALPIPE:
	case SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE:
		/* dual pp */
		for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
			hw_pp[i] = sde_enc->hw_pp[i];
			if (hw_pp[i])
				pp_count++;
		}
		break;
	default:
		SDE_DEBUG_ENC(sde_enc, "Unexpected topology:%d\n", topology);
		return -EINVAL;
	};

	SDE_EVT32(DRMID(&sde_enc->base), topology, pp_count, dsc_count);

	if (pp_count > MAX_CHANNELS_PER_ENC ||
		dsc_count > MAX_CHANNELS_PER_ENC) {
		SDE_ERROR_ENC(sde_enc, "Wrong count pp:%d dsc:%d top:%d\n",
				pp_count, dsc_count, topology);
		return -EINVAL;
	}

	/* Disable DSC for all the pp's present in this topology */
	for (i = 0; i < pp_count; i++) {

		if (!hw_pp[i]) {
			SDE_ERROR_ENC(sde_enc, "null pp:%d top:%d cnt:%d\n",
					i, topology, pp_count);
			return -EINVAL;
		}

		if (hw_pp[i]->ops.disable_dsc)
			hw_pp[i]->ops.disable_dsc(hw_pp[i]);
	}

	/* Disable DSC HW */
	for (i = 0; i < dsc_count; i++) {
	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
		hw_pp = sde_enc->hw_pp[i];
		hw_dsc = sde_enc->hw_dsc[i];

		if (!hw_dsc[i]) {
			SDE_ERROR_ENC(sde_enc, "null dsc:%d top:%d cnt:%d\n",
					i, topology, dsc_count);
			return -EINVAL;
		}
		if (hw_pp && hw_pp->ops.disable_dsc)
			hw_pp->ops.disable_dsc(hw_pp);

		if (hw_dsc[i]->ops.dsc_disable)
			hw_dsc[i]->ops.dsc_disable(hw_dsc[i]);
		if (hw_dsc && hw_dsc->ops.dsc_disable)
			hw_dsc->ops.dsc_disable(hw_dsc);
	}

	return ret;
@@ -2031,8 +1989,6 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	if (msm_is_mode_seamless_dms(adj_mode))
		sde_encoder_resource_control(&sde_enc->base,
						SDE_ENC_RC_EVENT_POST_MODESET);

	sde_enc->mode_set_complete = true;
}

static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
 * @needs_cdm:	Encoder requests a CDM based on pixel format conversion needs
 * @display_num_of_h_tiles: Number of horizontal tiles in case of split
 *                          interface
 * @is_primary: set to true if the display is primary display
 * @topology:   Topology of the display
 */
struct sde_encoder_hw_resources {
@@ -47,6 +48,7 @@ struct sde_encoder_hw_resources {
	enum sde_intf_mode wbs[WB_MAX];
	bool needs_cdm;
	u32 display_num_of_h_tiles;
	bool is_primary;
	struct msm_display_topology topology;
};

Loading