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

Commit 58871668 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: update vblank queue mechanism"

parents 8baaf062 69b6d362
Loading
Loading
Loading
Loading
+1 −9
Original line number Original line Diff line number Diff line
@@ -339,14 +339,6 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
	cur_work->crtc_id = crtc_id;
	cur_work->crtc_id = crtc_id;
	cur_work->enable = enable;
	cur_work->enable = enable;
	cur_work->priv = priv;
	cur_work->priv = priv;

	/* During modeset scenario, vblank request is queued to
	 * display thread to avoid enabling irq resulting in
	 * vblank refcount mismatch
	 */
	if (crtc->state && drm_atomic_crtc_needs_modeset(crtc->state))
		worker = &priv->disp_thread[crtc_id].worker;
	else
	worker = &priv->event_thread[crtc_id].worker;
	worker = &priv->event_thread[crtc_id].worker;


	kthread_queue_work(worker, &cur_work->work);
	kthread_queue_work(worker, &cur_work->work);
+3 −0
Original line number Original line Diff line number Diff line
@@ -4839,6 +4839,7 @@ int sde_crtc_vblank(struct drm_crtc *crtc, bool en)
	}
	}
	sde_crtc = to_sde_crtc(crtc);
	sde_crtc = to_sde_crtc(crtc);


	mutex_lock(&sde_crtc->vblank_modeset_ctrl_lock);
	mutex_lock(&sde_crtc->crtc_lock);
	mutex_lock(&sde_crtc->crtc_lock);
	SDE_EVT32(DRMID(&sde_crtc->base), en, sde_crtc->enabled);
	SDE_EVT32(DRMID(&sde_crtc->base), en, sde_crtc->enabled);
	ret = _sde_crtc_vblank_enable_no_lock(sde_crtc, en);
	ret = _sde_crtc_vblank_enable_no_lock(sde_crtc, en);
@@ -4847,6 +4848,7 @@ int sde_crtc_vblank(struct drm_crtc *crtc, bool en)
				sde_crtc->name, ret);
				sde_crtc->name, ret);


	mutex_unlock(&sde_crtc->crtc_lock);
	mutex_unlock(&sde_crtc->crtc_lock);
	mutex_unlock(&sde_crtc->vblank_modeset_ctrl_lock);


	return 0;
	return 0;
}
}
@@ -6132,6 +6134,7 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane)
	mutex_init(&sde_crtc->crtc_lock);
	mutex_init(&sde_crtc->crtc_lock);
	spin_lock_init(&sde_crtc->spin_lock);
	spin_lock_init(&sde_crtc->spin_lock);
	atomic_set(&sde_crtc->frame_pending, 0);
	atomic_set(&sde_crtc->frame_pending, 0);
	mutex_init(&sde_crtc->vblank_modeset_ctrl_lock);


	sde_crtc->enabled = false;
	sde_crtc->enabled = false;


+3 −0
Original line number Original line Diff line number Diff line
@@ -236,6 +236,8 @@ struct sde_crtc_misr_info {
 * @ad_dirty      : list containing ad properties that are dirty
 * @ad_dirty      : list containing ad properties that are dirty
 * @ad_active     : list containing ad properties that are active
 * @ad_active     : list containing ad properties that are active
 * @crtc_lock     : crtc lock around create, destroy and access.
 * @crtc_lock     : crtc lock around create, destroy and access.
 * @vblank_modeset_ctrl_lock     : lock used for controlling vblank
				during modeset
 * @frame_pending : Whether or not an update is pending
 * @frame_pending : Whether or not an update is pending
 * @frame_events  : static allocation of in-flight frame events
 * @frame_events  : static allocation of in-flight frame events
 * @frame_event_list : available frame event list
 * @frame_event_list : available frame event list
@@ -309,6 +311,7 @@ struct sde_crtc {


	struct mutex crtc_lock;
	struct mutex crtc_lock;
	struct mutex crtc_cp_lock;
	struct mutex crtc_cp_lock;
	struct mutex vblank_modeset_ctrl_lock;


	atomic_t frame_pending;
	atomic_t frame_pending;
	struct sde_crtc_frame_event frame_events[SDE_CRTC_FRAME_EVENT_SIZE];
	struct sde_crtc_frame_event frame_events[SDE_CRTC_FRAME_EVENT_SIZE];
+24 −18
Original line number Original line Diff line number Diff line
@@ -82,6 +82,11 @@
		((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE) || \
		((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE) || \
		((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))
		((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))


#define REQ_SEAMLESS_MODESET_LOCK(adj_mode, is_cmd_mode) \
		(msm_is_mode_seamless_dms(adj_mode) || \
		(msm_is_mode_seamless_dyn_clk(adj_mode) && \
		is_cmd_mode) || msm_is_mode_seamless_poms(adj_mode))

/**
/**
 * enum sde_enc_rc_events - events for resource control state machine
 * enum sde_enc_rc_events - events for resource control state machine
 * @SDE_ENC_RC_EVENT_KICKOFF:
 * @SDE_ENC_RC_EVENT_KICKOFF:
@@ -2878,9 +2883,12 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	enum sde_intf_mode intf_mode;
	enum sde_intf_mode intf_mode;
	bool is_cmd_mode = false;
	bool is_cmd_mode = false;
	int i = 0, ret;
	int i = 0, ret;
	struct sde_crtc *sde_crtc;
	bool modeset_lock = false;


	if (!drm_enc) {
	if (!drm_enc || !drm_enc->crtc) {
		SDE_ERROR("invalid encoder\n");
		SDE_ERROR("invalid params %d %d\n",
			!drm_enc, drm_enc ? !drm_enc->crtc : -1);
		return;
		return;
	}
	}


@@ -2901,25 +2909,16 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,


	SDE_EVT32(DRMID(drm_enc));
	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_enc->crtc = drm_enc->crtc;
	sde_crtc = to_sde_crtc(sde_enc->crtc);


	list_for_each_entry(conn_iter, connector_list, head)
	list_for_each_entry(conn_iter, connector_list, head)
		if (conn_iter->encoder == drm_enc)
		if (conn_iter->encoder == drm_enc)
			conn = conn_iter;
			conn = conn_iter;


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


@@ -2930,6 +2929,10 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,


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


	modeset_lock = REQ_SEAMLESS_MODESET_LOCK(adj_mode,
					is_cmd_mode);
	if (modeset_lock)
		mutex_lock(&sde_crtc->vblank_modeset_ctrl_lock);
	/* release resources before seamless mode change */
	/* release resources before seamless mode change */
	if (msm_is_mode_seamless_dms(adj_mode) ||
	if (msm_is_mode_seamless_dms(adj_mode) ||
			(msm_is_mode_seamless_dyn_clk(adj_mode) &&
			(msm_is_mode_seamless_dyn_clk(adj_mode) &&
@@ -2941,7 +2944,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
			SDE_ERROR_ENC(sde_enc,
			SDE_ERROR_ENC(sde_enc,
					"sde resource control failed: %d\n",
					"sde resource control failed: %d\n",
					ret);
					ret);
			return;
			goto exit;
		}
		}


		/*
		/*
@@ -2961,7 +2964,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	if (ret) {
	if (ret) {
		SDE_ERROR_ENC(sde_enc,
		SDE_ERROR_ENC(sde_enc,
				"failed to reserve hw resources, %d\n", ret);
				"failed to reserve hw resources, %d\n", ret);
		return;
		goto exit;
	}
	}


	sde_rm_init_hw_iter(&pp_iter, drm_enc->base.id, SDE_HW_BLK_PINGPONG);
	sde_rm_init_hw_iter(&pp_iter, drm_enc->base.id, SDE_HW_BLK_PINGPONG);
@@ -3017,7 +3020,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
			if (!sde_enc->hw_pp[i] && sde_enc->topology.num_intf) {
			if (!sde_enc->hw_pp[i] && sde_enc->topology.num_intf) {
				SDE_ERROR_ENC(sde_enc,
				SDE_ERROR_ENC(sde_enc,
				    "invalid pingpong block for the encoder\n");
				    "invalid pingpong block for the encoder\n");
				return;
				goto exit;
			}
			}
			phys->hw_pp = sde_enc->hw_pp[i];
			phys->hw_pp = sde_enc->hw_pp[i];
			phys->connector = conn->state->connector;
			phys->connector = conn->state->connector;
@@ -3035,6 +3038,9 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	else if (msm_is_mode_seamless_poms(adj_mode))
	else if (msm_is_mode_seamless_poms(adj_mode))
		_sde_encoder_modeset_helper_locked(drm_enc,
		_sde_encoder_modeset_helper_locked(drm_enc,
						SDE_ENC_RC_EVENT_POST_MODESET);
						SDE_ENC_RC_EVENT_POST_MODESET);
exit:
	if (modeset_lock)
		mutex_unlock(&sde_crtc->vblank_modeset_ctrl_lock);
}
}


void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable)
void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable)