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

Commit 257ac9e1 authored by Steve Cohen's avatar Steve Cohen
Browse files

disp: msm: sde: reduce complexity in sde_encoder_virt_mode_set



Lower the cyclomatic complexity for this function by splitting
the work into helpers.

Change-Id: I9e32d4ff13d31360a2baa77e013751ee8f0773fb
Signed-off-by: default avatarSteve Cohen <cohens@codeaurora.org>
parent a60fc941
Loading
Loading
Loading
Loading
+136 −101
Original line number Diff line number Diff line
@@ -2066,54 +2066,13 @@ static void sde_encoder_virt_mode_switch(struct drm_encoder *drm_enc,
	}
}

static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
				      struct drm_display_mode *mode,
				      struct drm_display_mode *adj_mode)
static struct drm_connector *_sde_encoder_get_connector(
		struct drm_device *dev, struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc;
	struct sde_kms *sde_kms;
	struct drm_connector_list_iter conn_iter;
	struct drm_connector *conn = NULL, *conn_search;
	struct sde_rm_hw_iter dsc_iter, pp_iter, qdss_iter;
	struct sde_rm_hw_iter vdc_iter;
	struct sde_rm_hw_request request_hw;
	enum sde_intf_mode intf_mode;
	bool is_cmd_mode = false;
	int i = 0, ret;

	if (!drm_enc) {
		SDE_ERROR("invalid encoder\n");
		return;
	}

	if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	SDE_DEBUG_ENC(sde_enc, "\n");

	if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE))
		is_cmd_mode = true;

	sde_kms = sde_encoder_get_kms(drm_enc);
	if (!sde_kms)
		return;

	SDE_EVT32(DRMID(drm_enc));

	/*
	 * cache the crtc in sde_enc on enable for duration of use case
	 * for correctly servicing asynchronous irq events and timers
	 */
	if (!drm_enc->crtc) {
		SDE_ERROR("invalid crtc\n");
		return;
	}
	sde_enc->crtc = drm_enc->crtc;

	drm_connector_list_iter_begin(sde_kms->dev, &conn_iter);
	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(conn_search, &conn_iter) {
		if (conn_search->encoder == drm_enc) {
			conn = conn_search;
@@ -2122,56 +2081,17 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	}
	drm_connector_list_iter_end(&conn_iter);

	sde_crtc_set_qos_dirty(sde_enc->crtc);

	if (!conn) {
		SDE_ERROR_ENC(sde_enc, "failed to find attached connector\n");
		return;
	} else if (!conn->state) {
		SDE_ERROR_ENC(sde_enc, "invalid connector state\n");
		return;
	}

	intf_mode = sde_encoder_get_intf_mode(drm_enc);

	/* store the mode_info */
	sde_connector_state_get_mode_info(conn->state, &sde_enc->mode_info);

	sde_encoder_dce_set_bpp(sde_enc->mode_info, sde_enc->crtc);

	/* release resources before seamless mode change */
	if (msm_is_mode_seamless_dms(adj_mode) ||
			(msm_is_mode_seamless_dyn_clk(adj_mode) &&
			 is_cmd_mode)) {
		/* restore resource state before releasing them */
		ret = sde_encoder_resource_control(drm_enc,
				SDE_ENC_RC_EVENT_PRE_MODESET);
		if (ret) {
			SDE_ERROR_ENC(sde_enc,
					"sde resource control failed: %d\n",
					ret);
			return;
		}

		/*
		 * Disable dce before switch the mode and after pre_modeset,
		 * to guarantee that previous kickoff finished.
		 */
		sde_encoder_dce_disable(sde_enc);
	} else if (msm_is_mode_seamless_poms(adj_mode)) {
		_sde_encoder_modeset_helper_locked(drm_enc,
					SDE_ENC_RC_EVENT_PRE_MODESET);
		sde_encoder_virt_mode_switch(drm_enc, intf_mode, adj_mode);
	return conn;
}

	/* Reserve dynamic resources now. Indicating non-AtomicTest phase */
	ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state,
			conn->state, false);
	if (ret) {
		SDE_ERROR_ENC(sde_enc,
				"failed to reserve hw resources, %d\n", ret);
		return;
	}
static void _sde_encoder_virt_populate_hw_res(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_kms *sde_kms = sde_encoder_get_kms(drm_enc);
	struct sde_rm_hw_iter pp_iter, qdss_iter;
	struct sde_rm_hw_iter dsc_iter, vdc_iter;
	struct sde_rm_hw_request request_hw;
	int i;

	sde_rm_init_hw_iter(&pp_iter, drm_enc->base.id, SDE_HW_BLK_PINGPONG);
	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
@@ -2233,7 +2153,129 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
		else
			sde_enc->hw_dsc_pp[i] = NULL;
	}
}

static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc,
		struct drm_display_mode *adj_mode, bool pre_modeset)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	enum sde_intf_mode intf_mode;
	int ret;
	bool is_cmd_mode;

	if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE))
		is_cmd_mode = true;

	if (pre_modeset) {
		intf_mode = sde_encoder_get_intf_mode(drm_enc);
		if (msm_is_mode_seamless_dms(adj_mode) ||
				(msm_is_mode_seamless_dyn_clk(adj_mode) &&
				 is_cmd_mode)) {
			/* restore resource state before releasing them */
			ret = sde_encoder_resource_control(drm_enc,
					SDE_ENC_RC_EVENT_PRE_MODESET);
			if (ret) {
				SDE_ERROR_ENC(sde_enc,
					"sde resource control failed: %d\n",
					ret);
				return ret;
			}

			/*
			 * Disable dce before switching the mode and after pre-
			 * modeset to guarantee previous kickoff has finished.
			 */
			sde_encoder_dce_disable(sde_enc);
		} else if (msm_is_mode_seamless_poms(adj_mode)) {
			_sde_encoder_modeset_helper_locked(drm_enc,
					SDE_ENC_RC_EVENT_PRE_MODESET);
			sde_encoder_virt_mode_switch(drm_enc, intf_mode,
					adj_mode);
		}
	} else {
		if (msm_is_mode_seamless_dms(adj_mode) ||
				(msm_is_mode_seamless_dyn_clk(adj_mode) &&
				is_cmd_mode))
			sde_encoder_resource_control(&sde_enc->base,
					SDE_ENC_RC_EVENT_POST_MODESET);
		else if (msm_is_mode_seamless_poms(adj_mode))
			_sde_encoder_modeset_helper_locked(drm_enc,
					SDE_ENC_RC_EVENT_POST_MODESET);
	}

	return 0;
}

static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
				      struct drm_display_mode *mode,
				      struct drm_display_mode *adj_mode)
{
	struct sde_encoder_virt *sde_enc;
	struct sde_kms *sde_kms;
	struct drm_connector *conn;
	int i = 0, ret;

	if (!drm_enc) {
		SDE_ERROR("invalid encoder\n");
		return;
	}

	if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) {
		SDE_ERROR("power resource is not enabled\n");
		return;
	}

	sde_kms = sde_encoder_get_kms(drm_enc);
	if (!sde_kms)
		return;

	sde_enc = to_sde_encoder_virt(drm_enc);
	SDE_DEBUG_ENC(sde_enc, "\n");
	SDE_EVT32(DRMID(drm_enc));

	/*
	 * cache the crtc in sde_enc on enable for duration of use case
	 * for correctly servicing asynchronous irq events and timers
	 */
	if (!drm_enc->crtc) {
		SDE_ERROR("invalid crtc\n");
		return;
	}

	sde_enc->crtc = drm_enc->crtc;
	sde_crtc_set_qos_dirty(drm_enc->crtc);

	/* get and store the mode_info */
	conn = _sde_encoder_get_connector(sde_kms->dev, drm_enc);
	if (!conn) {
		SDE_ERROR_ENC(sde_enc, "failed to find attached connector\n");
		return;
	} else if (!conn->state) {
		SDE_ERROR_ENC(sde_enc, "invalid connector state\n");
		return;
	}

	sde_connector_state_get_mode_info(conn->state, &sde_enc->mode_info);
	sde_encoder_dce_set_bpp(sde_enc->mode_info, sde_enc->crtc);

	/* release resources before seamless mode change */
	ret = sde_encoder_virt_modeset_rc(drm_enc, adj_mode, true);
	if (ret)
		return;

	/* reserve dynamic resources now, indicating non test-only */
	ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state,
			conn->state, false);
	if (ret) {
		SDE_ERROR_ENC(sde_enc,
				"failed to reserve hw resources, %d\n", ret);
		return;
	}

	/* assign the reserved HW blocks to this encoder */
	_sde_encoder_virt_populate_hw_res(drm_enc);

	/* perform mode_set on phys_encs */
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

@@ -2251,14 +2293,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	}

	/* update resources after seamless mode change */
	if (msm_is_mode_seamless_dms(adj_mode) ||
			(msm_is_mode_seamless_dyn_clk(adj_mode) &&
			is_cmd_mode))
		sde_encoder_resource_control(&sde_enc->base,
						SDE_ENC_RC_EVENT_POST_MODESET);
	else if (msm_is_mode_seamless_poms(adj_mode))
		_sde_encoder_modeset_helper_locked(drm_enc,
						SDE_ENC_RC_EVENT_POST_MODESET);
	sde_encoder_virt_modeset_rc(drm_enc, adj_mode, false);
}

void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable)