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

Commit f5dce665 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'exynos-drm-next' of...

Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

This pull request includes,
    - Code refactoring on HDMI DDC and PHY.
    - Regression fixup on deadlock issue with G2D pm integration.
    - Fixup on page fault issue with wait_for_vblank mechianism specific to Exynos drm.
    - And some cleanups.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
  drm/exynos: g2d: simplify g2d_free_runqueue_node()
  drm/exynos: g2d: use autosuspend mode for PM runtime
  drm/exynos: g2d: wait for engine to finish
  drm/exynos: g2d: remove runqueue nodes in g2d_{close,remove}()
  drm/exynos: g2d: move PM management to runqueue worker
  Revert "drm/exynos: g2d: fix system and runtime pm integration"
  drm/exynos: use drm core to handle page-flip event
  drm/exynos: mark exynos_dp_crtc_clock_enable() static
  drm/exynos/fimd: add clock rate checking
  drm/exynos: fix pending update handling
  drm/exynos/vidi: use timer for vblanks instead of sleeping worker
  drm/exynos: g2d: beautify probing message
  drm/exynos: mixer: simplify loop in vp_win_reset()
  drm/exynos: mixer: convert booleans to flags in mixer context
  gpu: drm: exynos_hdmi: Remove duplicate initialization of regulator bulk consumer
  gpu: drm: exynos_hdmi: Move PHY logic into single function
  gpu: drm: exynos_hdmi: Move DDC logic into single function
parents 28a39654 c0462796
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -551,7 +551,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
{
	struct decon_context *ctx = dev_id;
	u32 val;
	int win;

	if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
		goto out;
@@ -560,16 +559,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
	val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;

	if (val) {
		for (win = ctx->first_win; win < WINDOWS_NR ; win++) {
			struct exynos_drm_plane *plane = &ctx->planes[win];

			if (!plane->pending_fb)
				continue;

			exynos_drm_crtc_finish_update(ctx->crtc, plane);
		}

		/* clear */
		writel(val, ctx->addr + DECON_VIDINTCON1);
		drm_crtc_handle_vblank(&ctx->crtc->base);
	}
+0 −9
Original line number Diff line number Diff line
@@ -603,7 +603,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
{
	struct decon_context *ctx = (struct decon_context *)dev_id;
	u32 val, clear_bit;
	int win;

	val = readl(ctx->regs + VIDINTCON1);

@@ -617,14 +616,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)

	if (!ctx->i80_if) {
		drm_crtc_handle_vblank(&ctx->crtc->base);
		for (win = 0 ; win < WINDOWS_NR ; win++) {
			struct exynos_drm_plane *plane = &ctx->planes[win];

			if (!plane->pending_fb)
				continue;

			exynos_drm_crtc_finish_update(ctx->crtc, plane);
		}

		/* set wait vsync event to zero and wake up queue. */
		if (atomic_read(&ctx->wait_vsync_event)) {
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ struct exynos_dp_device {
	struct analogix_dp_plat_data plat_data;
};

int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
static int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
				bool enable)
{
	struct exynos_dp_device *dp = to_dp(plat_data);
+21 −37
Original line number Diff line number Diff line
@@ -69,8 +69,6 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc,
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

	exynos_crtc->event = crtc->state->event;

	if (exynos_crtc->ops->atomic_begin)
		exynos_crtc->ops->atomic_begin(exynos_crtc);
}
@@ -79,9 +77,24 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
				     struct drm_crtc_state *old_crtc_state)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_pending_vblank_event *event;
	unsigned long flags;

	if (exynos_crtc->ops->atomic_flush)
		exynos_crtc->ops->atomic_flush(exynos_crtc);

	event = crtc->state->event;
	if (event) {
		crtc->state->event = NULL;

		spin_lock_irqsave(&crtc->dev->event_lock, flags);
		if (drm_crtc_vblank_get(crtc) == 0)
			drm_crtc_arm_vblank_event(crtc, event);
		else
			drm_crtc_send_vblank_event(crtc, event);
		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
	}

}

static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
@@ -134,8 +147,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
	exynos_crtc->ops = ops;
	exynos_crtc->ctx = ctx;

	init_waitqueue_head(&exynos_crtc->wait_update);

	crtc = &exynos_crtc->base;

	private->crtc[pipe] = crtc;
@@ -175,32 +186,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe)
		exynos_crtc->ops->disable_vblank(exynos_crtc);
}

void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc)
{
	wait_event_timeout(exynos_crtc->wait_update,
			   (atomic_read(&exynos_crtc->pending_update) == 0),
			   msecs_to_jiffies(50));
}

void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
				struct exynos_drm_plane *exynos_plane)
{
	struct drm_crtc *crtc = &exynos_crtc->base;
	unsigned long flags;

	exynos_plane->pending_fb = NULL;

	if (atomic_dec_and_test(&exynos_crtc->pending_update))
		wake_up(&exynos_crtc->wait_update);

	spin_lock_irqsave(&crtc->dev->event_lock, flags);
	if (exynos_crtc->event)
		drm_crtc_send_vblank_event(crtc, exynos_crtc->event);

	exynos_crtc->event = NULL;
	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
}

int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
				       enum exynos_drm_output_type out_type)
{
@@ -228,20 +213,19 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
					struct drm_file *file)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_pending_vblank_event *e;
	unsigned long flags;

	spin_lock_irqsave(&crtc->dev->event_lock, flags);

	e = exynos_crtc->event;
	if (e && e->base.file_priv == file) {
		exynos_crtc->event = NULL;
		atomic_dec(&exynos_crtc->pending_update);
	}
	e = crtc->state->event;
	if (e && e->base.file_priv == file)
		crtc->state->event = NULL;
	else
		e = NULL;

	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);

	if (e && e->base.file_priv == file)
	if (e)
		drm_event_cancel_free(crtc->dev, &e->base);
}
+1 −43
Original line number Diff line number Diff line
@@ -45,37 +45,11 @@ struct exynos_atomic_commit {
	u32			crtcs;
};

static void exynos_atomic_wait_for_commit(struct drm_atomic_state *state)
{
	struct drm_crtc_state *crtc_state;
	struct drm_crtc *crtc;
	int i, ret;

	for_each_crtc_in_state(state, crtc, crtc_state, i) {
		struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

		if (!crtc->state->enable)
			continue;

		ret = drm_crtc_vblank_get(crtc);
		if (ret)
			continue;

		exynos_drm_crtc_wait_pending_update(exynos_crtc);
		drm_crtc_vblank_put(crtc);
	}
}

static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
{
	struct drm_device *dev = commit->dev;
	struct exynos_drm_private *priv = dev->dev_private;
	struct drm_atomic_state *state = commit->state;
	struct drm_plane *plane;
	struct drm_crtc *crtc;
	struct drm_plane_state *plane_state;
	struct drm_crtc_state *crtc_state;
	int i;

	drm_atomic_helper_commit_modeset_disables(dev, state);

@@ -89,25 +63,9 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
	 * have the relevant clocks enabled to perform the update.
	 */

	for_each_crtc_in_state(state, crtc, crtc_state, i) {
		struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

		atomic_set(&exynos_crtc->pending_update, 0);
	}

	for_each_plane_in_state(state, plane, plane_state, i) {
		struct exynos_drm_crtc *exynos_crtc =
						to_exynos_crtc(plane->crtc);

		if (!plane->crtc)
			continue;

		atomic_inc(&exynos_crtc->pending_update);
	}

	drm_atomic_helper_commit_planes(dev, state, 0);

	exynos_atomic_wait_for_commit(state);
	drm_atomic_helper_wait_for_vblanks(dev, state);

	drm_atomic_helper_cleanup_planes(dev, state);

Loading