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

Commit f0acff6b 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: move vblank to event thread"

parents 9a28bf83 10ea2bdd
Loading
Loading
Loading
Loading
+43 −8
Original line number Diff line number Diff line
@@ -304,7 +304,8 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
	list_add_tail(&vbl_ev->node, &vbl_ctrl->event_list);
	spin_unlock_irqrestore(&vbl_ctrl->lock, flags);

	kthread_queue_work(&priv->disp_thread[crtc_id].worker, &vbl_ctrl->work);
	kthread_queue_work(&priv->event_thread[crtc_id].worker,
			&vbl_ctrl->work);

	return 0;
}
@@ -330,13 +331,19 @@ static int msm_drm_uninit(struct device *dev)
		kfree(vbl_ev);
	}

	/* clean up display commit worker threads */
	/* clean up display commit/event worker threads */
	for (i = 0; i < priv->num_crtcs; i++) {
		if (priv->disp_thread[i].thread) {
			kthread_flush_worker(&priv->disp_thread[i].worker);
			kthread_stop(priv->disp_thread[i].thread);
			priv->disp_thread[i].thread = NULL;
		}

		if (priv->event_thread[i].thread) {
			kthread_flush_worker(&priv->event_thread[i].worker);
			kthread_stop(priv->event_thread[i].thread);
			priv->event_thread[i].thread = NULL;
		}
	}

	msm_gem_shrinker_cleanup(ddev);
@@ -637,23 +644,51 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
	ddev->mode_config.funcs = &mode_config_funcs;

	for (i = 0; i < priv->num_crtcs; i++) {

		/* initialize display thread */
		priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
		kthread_init_worker(&priv->disp_thread[i].worker);
		priv->disp_thread[i].dev = ddev;
		priv->disp_thread[i].thread =
			kthread_run(kthread_worker_fn,
				&priv->disp_thread[i].worker,
				"crtc_commit:%d",
				priv->disp_thread[i].crtc_id);
				"crtc_commit:%d", priv->disp_thread[i].crtc_id);

		if (IS_ERR(priv->disp_thread[i].thread)) {
			dev_err(dev, "failed to create kthread\n");
			dev_err(dev, "failed to create crtc_commit kthread\n");
			priv->disp_thread[i].thread = NULL;
		}

		/* initialize event thread */
		priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
		kthread_init_worker(&priv->event_thread[i].worker);
		priv->event_thread[i].dev = ddev;
		priv->event_thread[i].thread =
			kthread_run(kthread_worker_fn,
				&priv->event_thread[i].worker,
				"crtc_event:%d", priv->event_thread[i].crtc_id);

		if (IS_ERR(priv->event_thread[i].thread)) {
			dev_err(dev, "failed to create crtc_event kthread\n");
			priv->event_thread[i].thread = NULL;
		}

		if ((!priv->disp_thread[i].thread) ||
				!priv->event_thread[i].thread) {
			/* clean up previously created threads if any */
			for (i -= 1; i >= 0; i--) {
				kthread_stop(priv->disp_thread[i].thread);
			for ( ; i >= 0; i--) {
				if (priv->disp_thread[i].thread) {
					kthread_stop(
						priv->disp_thread[i].thread);
					priv->disp_thread[i].thread = NULL;
				}

				if (priv->event_thread[i].thread) {
					kthread_stop(
						priv->event_thread[i].thread);
					priv->event_thread[i].thread = NULL;
				}
			}
			goto fail;
		}
	}
+4 −3
Original line number Diff line number Diff line
@@ -471,8 +471,8 @@ struct msm_drm_event {
	u8 data[];
};

/* Commit thread specific structure */
struct msm_drm_commit {
/* Commit/Event thread specific structure */
struct msm_drm_thread {
	struct drm_device *dev;
	struct task_struct *thread;
	unsigned int crtc_id;
@@ -536,7 +536,8 @@ struct msm_drm_private {
	unsigned int num_crtcs;
	struct drm_crtc *crtcs[MAX_CRTCS];

	struct msm_drm_commit disp_thread[MAX_CRTCS];
	struct msm_drm_thread disp_thread[MAX_CRTCS];
	struct msm_drm_thread event_thread[MAX_CRTCS];

	unsigned int num_encoders;
	struct drm_encoder *encoders[MAX_ENCODERS];
+12 −24
Original line number Diff line number Diff line
@@ -494,12 +494,6 @@ static void _sde_crtc_deinit_events(struct sde_crtc *sde_crtc)
{
	if (!sde_crtc)
		return;

	if (sde_crtc->event_thread) {
		kthread_flush_worker(&sde_crtc->event_worker);
		kthread_stop(sde_crtc->event_thread);
		sde_crtc->event_thread = NULL;
	}
}

static void sde_crtc_destroy(struct drm_crtc *crtc)
@@ -1616,7 +1610,7 @@ static void sde_crtc_frame_event_cb(void *data, u32 event)
	struct msm_drm_private *priv;
	struct sde_crtc_frame_event *fevent;
	unsigned long flags;
	int pipe_id;
	u32 crtc_id;

	if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
		SDE_ERROR("invalid parameters\n");
@@ -1624,7 +1618,7 @@ static void sde_crtc_frame_event_cb(void *data, u32 event)
	}
	sde_crtc = to_sde_crtc(crtc);
	priv = crtc->dev->dev_private;
	pipe_id = drm_crtc_index(crtc);
	crtc_id = drm_crtc_index(crtc);

	SDE_DEBUG("crtc%d\n", crtc->base.id);
	SDE_EVT32_VERBOSE(DRMID(crtc), event);
@@ -1646,7 +1640,7 @@ static void sde_crtc_frame_event_cb(void *data, u32 event)
	fevent->event = event;
	fevent->crtc = crtc;
	fevent->ts = ktime_get();
	kthread_queue_work(&sde_crtc->event_worker, &fevent->work);
	kthread_queue_work(&priv->event_thread[crtc_id].worker, &fevent->work);
}

void sde_crtc_complete_commit(struct drm_crtc *crtc,
@@ -3687,14 +3681,18 @@ int sde_crtc_event_queue(struct drm_crtc *crtc,
{
	unsigned long irq_flags;
	struct sde_crtc *sde_crtc;
	struct msm_drm_private *priv;
	struct sde_crtc_event *event = NULL;
	u32 crtc_id;

	if (!crtc || !func)
	if (!crtc || !crtc->dev || !crtc->dev->dev_private || !func) {
		SDE_ERROR("invalid parameters\n");
		return -EINVAL;
	}
	sde_crtc = to_sde_crtc(crtc);
	priv = crtc->dev->dev_private;
	crtc_id = drm_crtc_index(crtc);

	if (!sde_crtc->event_thread)
		return -EINVAL;
	/*
	 * Obtain an event struct from the private cache. This event
	 * queue may be called from ISR contexts, so use a private
@@ -3718,7 +3716,8 @@ int sde_crtc_event_queue(struct drm_crtc *crtc,

	/* queue new event request */
	kthread_init_work(&event->kt_work, _sde_crtc_event_cb);
	kthread_queue_work(&sde_crtc->event_worker, &event->kt_work);
	kthread_queue_work(&priv->event_thread[crtc_id].worker,
			&event->kt_work);

	return 0;
}
@@ -3739,17 +3738,6 @@ static int _sde_crtc_init_events(struct sde_crtc *sde_crtc)
		list_add_tail(&sde_crtc->event_cache[i].list,
				&sde_crtc->event_free_list);

	kthread_init_worker(&sde_crtc->event_worker);
	sde_crtc->event_thread = kthread_run(kthread_worker_fn,
			&sde_crtc->event_worker, "crtc_event:%d",
			sde_crtc->base.base.id);

	if (IS_ERR_OR_NULL(sde_crtc->event_thread)) {
		SDE_ERROR("failed to create event thread\n");
		rc = PTR_ERR(sde_crtc->event_thread);
		sde_crtc->event_thread = NULL;
	}

	return rc;
}

+0 −2
Original line number Diff line number Diff line
@@ -190,8 +190,6 @@ struct sde_crtc {
	struct completion frame_done_comp;

	/* for handling internal event thread */
	struct task_struct *event_thread;
	struct kthread_worker event_worker;
	struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];
	struct list_head event_free_list;
	spinlock_t event_lock;