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

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

Merge tag 'exynos-drm-next-for-v4.13' of...

Merge tag 'exynos-drm-next-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

Summary:
- Rework vblank handling
  . This patch series adds frame counter callback and removes
    unnecessary pipe relevnt fields and simplifies event handling.
- clean up and fix up sw-trigger relevant code
  . This patch series moves TE relevant code from Panel and HDMI
    to DECON driver to fix a race between interrupt handlers and
    DECON disable, and to fix timeout issue at wait-for-vblank.
  . It removes unnecessary flags and check code specific to Exynos driver.

* tag 'exynos-drm-next-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (27 commits)
  drm/exynos/decon5433: remove useless check
  drm/exynos/decon5433: kill BIT_SUSPENDED flag
  drm/exynos/decon5433: kill BIT_WIN_UPDATED flag
  drm/exynos/decon5433: kill BIT_CLKS_ENABLED flag
  drm/exynos/decon5433: kill BIT_IRQS_ENABLED flag
  drm/exynos/decon5433: move TE handling to DECON
  dt-bindings: exynos5433-decon: add TE interrupt binding
  dt-bindings: exynos5433-decon: fix interrupts bindings
  drm/exynos/decon5433: always do sw-trigger when vblanks enabled
  drm/exynos: mixer: document YCbCr magic numbers
  drm/exynos: mixer: simplify mixer_cfg_rgb_fmt()
  drm/exynos/dsi: fix bridge_node DT parsing
  drm/exynos/hdmi: fix pipeline disable order
  drm/exynos/decon5433: simplify shadow protect code
  drm/exynos/decon5433: kill BIT_IRQS_ENABLED
  drm/exynos/decon5433: kill DECON_UPDATE workaround
  drm/exynos: kill mode_set_nofb callback
  drm/exynos: kill pipe field from drivers contexts
  drm/exynos: set plane possible_crtcs in exynos_plane_init
  drm/exynos: kill exynos_drm_private::pipe
  ...
parents 55f5b0bf ce42cf4b
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -8,12 +8,13 @@ Required properties:
- compatible: value should be one of:
	"samsung,exynos5433-decon", "samsung,exynos5433-decon-tv";
- reg: physical base address and length of the DECON registers set.
- interrupts: should contain a list of all DECON IP block interrupts in the
	      order: VSYNC, LCD_SYSTEM. The interrupt specifier format
	      depends on the interrupt controller used.
- interrupt-names: should contain the interrupt names: "vsync", "lcd_sys"
		   in the same order as they were listed in the interrupts
		   property.
- interrupt-names: should contain the interrupt names depending on mode of work:
		video mode: "vsync",
		command mode: "lcd_sys",
		command mode with software trigger: "lcd_sys", "te".
- interrupts or interrupts-extended: list of interrupt specifiers corresponding
		to names privided in interrupt-names, as described in
		interrupt-controller/interrupts.txt
- clocks: must include clock specifiers corresponding to entries in the
	  clock-names property.
- clock-names: list of clock names sorted in the same order as the clocks
+95 −123
Original line number Diff line number Diff line
@@ -47,14 +47,6 @@ static const char * const decon_clks_name[] = {
	"sclk_decon_eclk",
};

enum decon_flag_bits {
	BIT_CLKS_ENABLED,
	BIT_IRQS_ENABLED,
	BIT_WIN_UPDATED,
	BIT_SUSPENDED,
	BIT_REQUEST_UPDATE
};

struct decon_context {
	struct device			*dev;
	struct drm_device		*drm_dev;
@@ -64,8 +56,8 @@ struct decon_context {
	void __iomem			*addr;
	struct regmap			*sysreg;
	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
	int				pipe;
	unsigned long			flags;
	unsigned int			irq;
	unsigned int			te_irq;
	unsigned long			out_type;
	int				first_win;
	spinlock_t			vblank_lock;
@@ -97,10 +89,6 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
	struct decon_context *ctx = crtc->ctx;
	u32 val;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return -EPERM;

	if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
	val = VIDINTCON0_INTEN;
	if (ctx->out_type & IFTYPE_I80)
		val |= VIDINTCON0_FRAMEDONE;
@@ -108,7 +96,10 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
		val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;

	writel(val, ctx->addr + DECON_VIDINTCON0);
	}

	enable_irq(ctx->irq);
	if (!(ctx->out_type & I80_HW_TRG))
		enable_irq(ctx->te_irq);

	return 0;
}
@@ -117,10 +108,10 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;
	if (!(ctx->out_type & I80_HW_TRG))
		disable_irq_nosync(ctx->te_irq);
	disable_irq_nosync(ctx->irq);

	if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
	writel(0, ctx->addr + DECON_VIDINTCON0);
}

@@ -166,6 +157,13 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
	return frm;
}

static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;

	return decon_get_frame_count(ctx, false);
}

static void decon_setup_trigger(struct decon_context *ctx)
{
	if (!(ctx->out_type & (IFTYPE_I80 | I80_HW_TRG)))
@@ -193,9 +191,6 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
	bool interlaced = false;
	u32 val;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	if (ctx->out_type & IFTYPE_HDMI) {
		m->crtc_hsync_start = m->crtc_hdisplay + 10;
		m->crtc_hsync_end = m->crtc_htotal - 92;
@@ -309,23 +304,17 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
	writel(val, ctx->addr + DECON_WINCONx(win));
}

static void decon_shadow_protect_win(struct decon_context *ctx, int win,
					bool protect)
static void decon_shadow_protect(struct decon_context *ctx, bool protect)
{
	decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_Wx_PROTECT(win),
	decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_PROTECT_MASK,
		       protect ? ~0 : 0);
}

static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;
	int i;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	for (i = ctx->first_win; i < WINDOWS_NR; i++)
		decon_shadow_protect_win(ctx, i, true);
	decon_shadow_protect(ctx, true);
}

#define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
@@ -345,9 +334,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
	dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
	u32 val;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) {
		val = COORDINATE_X(state->crtc.x) |
			COORDINATE_Y(state->crtc.y / 2);
@@ -390,7 +376,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,

	/* window enable */
	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
	set_bit(BIT_REQUEST_UPDATE, &ctx->flags);
}

static void decon_disable_plane(struct exynos_drm_crtc *crtc,
@@ -399,33 +384,20 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
	struct decon_context *ctx = crtc->ctx;
	unsigned int win = plane->index;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
	set_bit(BIT_REQUEST_UPDATE, &ctx->flags);
}

static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;
	unsigned long flags;
	int i;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	spin_lock_irqsave(&ctx->vblank_lock, flags);

	for (i = ctx->first_win; i < WINDOWS_NR; i++)
		decon_shadow_protect_win(ctx, i, false);
	decon_shadow_protect(ctx, false);

	if (test_and_clear_bit(BIT_REQUEST_UPDATE, &ctx->flags))
	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);

	if (ctx->out_type & IFTYPE_I80)
		set_bit(BIT_WIN_UPDATED, &ctx->flags);

	ctx->frame_id = decon_get_frame_count(ctx, true);

	exynos_crtc_handle_event(crtc);
@@ -473,21 +445,12 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
{
	struct decon_context *ctx = crtc->ctx;

	if (!test_and_clear_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	pm_runtime_get_sync(ctx->dev);

	exynos_drm_pipe_clk_enable(crtc, true);

	set_bit(BIT_CLKS_ENABLED, &ctx->flags);

	decon_swreset(ctx);

	/* if vblank was enabled status, enable it again. */
	if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
		decon_enable_vblank(ctx->crtc);

	decon_commit(ctx->crtc);
}

@@ -496,8 +459,9 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
	struct decon_context *ctx = crtc->ctx;
	int i;

	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;
	if (!(ctx->out_type & I80_HW_TRG))
		synchronize_irq(ctx->te_irq);
	synchronize_irq(ctx->irq);

	/*
	 * We need to make sure that all windows are disabled before we
@@ -509,25 +473,18 @@ static void decon_disable(struct exynos_drm_crtc *crtc)

	decon_swreset(ctx);

	clear_bit(BIT_CLKS_ENABLED, &ctx->flags);

	exynos_drm_pipe_clk_enable(crtc, false);

	pm_runtime_put_sync(ctx->dev);

	set_bit(BIT_SUSPENDED, &ctx->flags);
}

static void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
static irqreturn_t decon_te_irq_handler(int irq, void *dev_id)
{
	struct decon_context *ctx = crtc->ctx;

	if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags) ||
	    (ctx->out_type & I80_HW_TRG))
		return;
	struct decon_context *ctx = dev_id;

	if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags))
	decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);

	return IRQ_HANDLED;
}

static void decon_clear_channels(struct exynos_drm_crtc *crtc)
@@ -543,11 +500,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
			goto err;
	}

	for (win = 0; win < WINDOWS_NR; win++) {
		decon_shadow_protect_win(ctx, win, true);
	decon_shadow_protect(ctx, true);
	for (win = 0; win < WINDOWS_NR; win++)
		decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
		decon_shadow_protect_win(ctx, win, false);
	}
	decon_shadow_protect(ctx, false);

	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);

@@ -564,25 +520,24 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
	.disable		= decon_disable,
	.enable_vblank		= decon_enable_vblank,
	.disable_vblank		= decon_disable_vblank,
	.get_vblank_counter	= decon_get_vblank_counter,
	.atomic_begin		= decon_atomic_begin,
	.update_plane		= decon_update_plane,
	.disable_plane		= decon_disable_plane,
	.atomic_flush		= decon_atomic_flush,
	.te_handler		= decon_te_irq_handler,
};

static int decon_bind(struct device *dev, struct device *master, void *data)
{
	struct decon_context *ctx = dev_get_drvdata(dev);
	struct drm_device *drm_dev = data;
	struct exynos_drm_private *priv = drm_dev->dev_private;
	struct exynos_drm_plane *exynos_plane;
	enum exynos_drm_output_type out_type;
	unsigned int win;
	int ret;

	ctx->drm_dev = drm_dev;
	ctx->pipe = priv->pipe++;
	drm_dev->max_vblank_count = 0xffffffff;

	for (win = ctx->first_win; win < WINDOWS_NR; win++) {
		int tmp = (win == ctx->first_win) ? 0 : win;
@@ -593,7 +548,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
		ctx->configs[win].type = decon_win_types[tmp];

		ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
					1 << ctx->pipe, &ctx->configs[win]);
					&ctx->configs[win]);
		if (ret)
			return ret;
	}
@@ -602,23 +557,13 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
	out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
						  : EXYNOS_DISPLAY_TYPE_LCD;
	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
					ctx->pipe, out_type,
					&decon_crtc_ops, ctx);
	if (IS_ERR(ctx->crtc)) {
		ret = PTR_ERR(ctx->crtc);
		goto err;
	}
			out_type, &decon_crtc_ops, ctx);
	if (IS_ERR(ctx->crtc))
		return PTR_ERR(ctx->crtc);

	decon_clear_channels(ctx->crtc);

	ret = drm_iommu_attach_device(drm_dev, dev);
	if (ret)
		goto err;

	return ret;
err:
	priv->pipe--;
	return ret;
	return drm_iommu_attach_device(drm_dev, dev);
}

static void decon_unbind(struct device *dev, struct device *master, void *data)
@@ -659,9 +604,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
	struct decon_context *ctx = dev_id;
	u32 val;

	if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
		goto out;

	val = readl(ctx->addr + DECON_VIDINTCON1);
	val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;

@@ -677,7 +619,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
		decon_handle_vblank(ctx);
	}

out:
	return IRQ_HANDLED;
}

@@ -732,6 +673,31 @@ static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);

static int decon_conf_irq(struct decon_context *ctx, const char *name,
		irq_handler_t handler, unsigned long int flags, bool required)
{
	struct platform_device *pdev = to_platform_device(ctx->dev);
	int ret, irq = platform_get_irq_byname(pdev, name);

	if (irq < 0) {
		if (irq == -EPROBE_DEFER)
			return irq;
		if (required)
			dev_err(ctx->dev, "cannot get %s IRQ\n", name);
		else
			irq = 0;
		return irq;
	}
	irq_set_status_flags(irq, IRQ_NOAUTOEN);
	ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx);
	if (ret < 0) {
		dev_err(ctx->dev, "IRQ %s request failed\n", name);
		return ret;
	}

	return irq;
}

static int exynos5433_decon_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -744,7 +710,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
	if (!ctx)
		return -ENOMEM;

	__set_bit(BIT_SUSPENDED, &ctx->flags);
	ctx->dev = dev;
	ctx->out_type = (unsigned long)of_device_get_match_data(dev);
	spin_lock_init(&ctx->vblank_lock);
@@ -755,15 +720,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
		ctx->out_type |= IFTYPE_I80;
	}

	if (ctx->out_type & I80_HW_TRG) {
		ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
							"samsung,disp-sysreg");
		if (IS_ERR(ctx->sysreg)) {
			dev_err(dev, "failed to get system register\n");
			return PTR_ERR(ctx->sysreg);
		}
	}

	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
		struct clk *clk;

@@ -786,18 +742,34 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
		return PTR_ERR(ctx->addr);
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
			(ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync");
	if (!res) {
		dev_err(dev, "cannot find IRQ resource\n");
		return -ENXIO;
	}
	if (ctx->out_type & IFTYPE_I80) {
		ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0, true);
		if (ret < 0)
			return ret;
		ctx->irq = ret;

	ret = devm_request_irq(dev, res->start, decon_irq_handler, 0,
			       "drm_decon", ctx);
	if (ret < 0) {
		dev_err(dev, "lcd_sys irq request failed\n");
		ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
				     IRQF_TRIGGER_RISING, false);
		if (ret < 0)
			return ret;
		if (ret) {
			ctx->te_irq = ret;
			ctx->out_type &= ~I80_HW_TRG;
		}
	} else {
		ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0, true);
		if (ret < 0)
			return ret;
		ctx->irq = ret;
	}

	if (ctx->out_type & I80_HW_TRG) {
		ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
							"samsung,disp-sysreg");
		if (IS_ERR(ctx->sysreg)) {
			dev_err(dev, "failed to get system register\n");
			return PTR_ERR(ctx->sysreg);
		}
	}

	platform_set_drvdata(pdev, ctx);
+4 −15
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@ struct decon_context {
	unsigned long			irq_flags;
	bool				i80_if;
	bool				suspended;
	int				pipe;
	wait_queue_head_t		wait_vsync_queue;
	atomic_t			wait_vsync_event;

@@ -130,19 +129,11 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
static int decon_ctx_initialize(struct decon_context *ctx,
			struct drm_device *drm_dev)
{
	struct exynos_drm_private *priv = drm_dev->dev_private;
	int ret;

	ctx->drm_dev = drm_dev;
	ctx->pipe = priv->pipe++;

	decon_clear_channels(ctx->crtc);

	ret = drm_iommu_attach_device(drm_dev, ctx->dev);
	if (ret)
		priv->pipe--;

	return ret;
	return drm_iommu_attach_device(drm_dev, ctx->dev);
}

static void decon_ctx_remove(struct decon_context *ctx)
@@ -590,7 +581,6 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
static const struct exynos_drm_crtc_ops decon_crtc_ops = {
	.enable = decon_enable,
	.disable = decon_disable,
	.commit = decon_commit,
	.enable_vblank = decon_enable_vblank,
	.disable_vblank = decon_disable_vblank,
	.atomic_begin = decon_atomic_begin,
@@ -612,7 +602,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
		writel(clear_bit, ctx->regs + VIDINTCON1);

	/* check the crtc is detached already from encoder */
	if (ctx->pipe < 0 || !ctx->drm_dev)
	if (!ctx->drm_dev)
		goto out;

	if (!ctx->i80_if) {
@@ -649,15 +639,14 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
		ctx->configs[i].type = decon_win_types[i];

		ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
					1 << ctx->pipe, &ctx->configs[i]);
					&ctx->configs[i]);
		if (ret)
			return ret;
	}

	exynos_plane = &ctx->planes[DEFAULT_WIN];
	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
					   ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD,
					   &decon_crtc_ops, ctx);
			EXYNOS_DISPLAY_TYPE_LCD, &decon_crtc_ops, ctx);
	if (IS_ERR(ctx->crtc)) {
		decon_ctx_remove(ctx);
		return PTR_ERR(ctx->crtc);
+22 −28
Original line number Diff line number Diff line
@@ -49,15 +49,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
	}
}

static void
exynos_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

	if (exynos_crtc->ops->commit)
		exynos_crtc->ops->commit(exynos_crtc);
}

static int exynos_crtc_atomic_check(struct drm_crtc *crtc,
				     struct drm_crtc_state *state)
{
@@ -93,7 +84,6 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
	.enable		= exynos_drm_crtc_enable,
	.disable	= exynos_drm_crtc_disable,
	.mode_set_nofb	= exynos_drm_crtc_mode_set_nofb,
	.atomic_check	= exynos_crtc_atomic_check,
	.atomic_begin	= exynos_crtc_atomic_begin,
	.atomic_flush	= exynos_crtc_atomic_flush,
@@ -105,18 +95,17 @@ void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
	struct drm_pending_vblank_event *event = crtc->state->event;
	unsigned long flags;

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

	WARN_ON(drm_crtc_vblank_get(crtc) != 0);

	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 void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -143,6 +132,16 @@ static void exynos_drm_crtc_disable_vblank(struct drm_crtc *crtc)
		exynos_crtc->ops->disable_vblank(exynos_crtc);
}

static u32 exynos_drm_crtc_get_vblank_counter(struct drm_crtc *crtc)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

	if (exynos_crtc->ops->get_vblank_counter)
		return exynos_crtc->ops->get_vblank_counter(exynos_crtc);

	return 0;
}

static const struct drm_crtc_funcs exynos_crtc_funcs = {
	.set_config	= drm_atomic_helper_set_config,
	.page_flip	= drm_atomic_helper_page_flip,
@@ -152,11 +151,11 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = {
	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
	.enable_vblank = exynos_drm_crtc_enable_vblank,
	.disable_vblank = exynos_drm_crtc_disable_vblank,
	.get_vblank_counter = exynos_drm_crtc_get_vblank_counter,
};

struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
					struct drm_plane *plane,
					int pipe,
					enum exynos_drm_output_type type,
					const struct exynos_drm_crtc_ops *ops,
					void *ctx)
@@ -169,7 +168,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
	if (!exynos_crtc)
		return ERR_PTR(-ENOMEM);

	exynos_crtc->pipe = pipe;
	exynos_crtc->type = type;
	exynos_crtc->ops = ops;
	exynos_crtc->ctx = ctx;
@@ -196,13 +194,9 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
{
	struct drm_crtc *crtc;

	list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
		struct exynos_drm_crtc *exynos_crtc;

		exynos_crtc = to_exynos_crtc(crtc);
		if (exynos_crtc->type == out_type)
			return exynos_crtc->pipe;
	}
	drm_for_each_crtc(crtc, drm_dev)
		if (to_exynos_crtc(crtc)->type == out_type)
			return drm_crtc_index(crtc);

	return -EPERM;
}
+0 −1
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@

struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
					struct drm_plane *plane,
					int pipe,
					enum exynos_drm_output_type type,
					const struct exynos_drm_crtc_ops *ops,
					void *context);
Loading