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

Commit 00c1beab 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

Summary:
 - Support for pipeline clock between KMS drivers.
   . Exynos SoC is required to control clocks across KMS drivers
     according to Exynos SoC version. So this patch refactos
     some relevant codes and provides generic solution for it.
 - Add Exynos5433 SoC support to HDMI parts - HDMI and DECON-TV.
 - Add HW trigger mode support to CRTC drivers.
   . In case of using i80 Panel, some Exynos SoC supports HW trigger
     mode so this patch makes trigger mode - HW or SW trigger - to be
     set according to SoC version properly.
 - And some cleanups and regression fixups.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (39 commits)
  drm/exynos: clean up register definions for fimd and decon
  drm/exynos: decon: clean up interface type
  drm/exynos: fimd: add HW trigger support
  drm/exynos: clean up wait_for_vblank
  drm/exynos: mixer: use generic of_device_get_match_data helper
  drm/exynos: mixer: remove support for non-dt platforms
  drm/exynos: hdmi: use generic of_device_get_match_data helper
  drm/exynos: rotator: use generic of_device_get_match_data helper
  drm/exynos: fimd: use generic of_device_get_match_data helper
  drm/exynos: dsi: use generic of_device_get_match_data helper
  drm/exynos: exynos5433_decon: use generic of_device_get_match_data helper
  drm/exynos: convert clock_enable crtc callback to pipeline clock
  drm/exynos/mixer: enable HDMI-PHY before configuring MIXER
  drm/exynos/decon5433: enable HDMI-PHY before configuring DECON
  drm/exynos: add support for pipeline clock to the framework
  drm/exynos: add helper to get crtc from pipe
  drm/exynos/decon5433: do not protect window in plane disable
  drm/exynos/decon5433: reset decon on start
  drm/exynos/decon5433: fix DECON standalone update
  drm/exynos/hdmi: remove registry dump
  ...
parents acff058f b5bf0f1e
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -5,7 +5,8 @@ Exynos series of SoCs which transfers the image data from a video memory
buffer to an external LCD interface.

Required properties:
- compatible: value should be "samsung,exynos5433-decon";
- 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
@@ -16,7 +17,7 @@ Required properties:
- 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
	       property. Must contain "aclk_decon", "aclk_smmu_decon0x",
	       property. Must contain "pclk", "aclk_decon", "aclk_smmu_decon0x",
	       "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk",
	       "sclk_decon_eclk"
- ports: contains a port which is connected to mic node. address-cells and
+24 −3
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ Required properties:
	1) "samsung,exynos4210-hdmi"
	2) "samsung,exynos4212-hdmi"
	3) "samsung,exynos5420-hdmi"
	4) "samsung,exynos5433-hdmi"
- reg: physical base address of the hdmi and length of memory mapped
	region.
- interrupts: interrupt number to the cpu.
@@ -12,6 +13,11 @@ Required properties:
	a) phandle of the gpio controller node.
	b) pin number within the gpio controller.
	c) optional flags and pull up/down.
- ddc: phandle to the hdmi ddc node
- phy: phandle to the hdmi phy node
- samsung,syscon-phandle: phandle for system controller node for PMU.

Required properties for Exynos 4210, 4212, 5420 and 5433:
- clocks: list of clock IDs from SoC clock driver.
	a) hdmi: Gate of HDMI IP bus clock.
	b) sclk_hdmi: Gate of HDMI special clock.
@@ -25,9 +31,24 @@ Required properties:
		sclk_pixel.
- clock-names: aliases as per driver requirements for above clock IDs:
	"hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
- ddc: phandle to the hdmi ddc node
- phy: phandle to the hdmi phy node
- samsung,syscon-phandle: phandle for system controller node for PMU.

Required properties for Exynos 5433:
- clocks: list of clock specifiers according to common clock bindings.
	a) hdmi_pclk: Gate of HDMI IP APB bus.
	b) hdmi_i_pclk: Gate of HDMI-PHY IP APB bus.
	d) i_tmds_clk: Gate of HDMI TMDS clock.
	e) i_pixel_clk: Gate of HDMI pixel clock.
	f) i_spdif_clk: Gate of HDMI SPDIF clock.
	g) oscclk: Oscillator clock, used as parent of following *_user clocks
		in case HDMI-PHY is not operational.
	h) tmds_clko: TMDS clock generated by HDMI-PHY.
	i) tmds_clko_user: MUX used to switch between oscclk and tmds_clko,
		respectively if HDMI-PHY is off and operational.
	j) pixel_clko: Pixel clock generated by HDMI-PHY.
	k) pixel_clko_user: MUX used to switch between oscclk and pixel_clko,
		respectively if HDMI-PHY is off and operational.
- clock-names: aliases for above clock specfiers.
- samsung,sysreg: handle to syscon used to control the system registers.

Example:

+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ comment "Sub-drivers"

config DRM_EXYNOS_G2D
	bool "G2D"
	depends on !VIDEO_SAMSUNG_S5P_G2D
	depends on VIDEO_SAMSUNG_S5P_G2D=n
	select FRAME_VECTOR
	help
	  Choose this option if you want to use Exynos G2D for DRM.
+3 −3
Original line number Diff line number Diff line
@@ -2,10 +2,10 @@
# Makefile for the drm device driver.  This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.

exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
		exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \
		exynos_drm_plane.o
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
		exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o

exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON)	+= exynos5433_drm_decon.o
+44 −42
Original line number Diff line number Diff line
@@ -28,6 +28,10 @@
#define WINDOWS_NR	3
#define MIN_FB_WIDTH_FOR_16WORD_BURST	128

#define IFTYPE_I80	(1 << 0)
#define I80_HW_TRG	(1 << 1)
#define IFTYPE_HDMI	(1 << 2)

static const char * const decon_clks_name[] = {
	"pclk",
	"aclk_decon",
@@ -38,12 +42,6 @@ static const char * const decon_clks_name[] = {
	"sclk_decon_eclk",
};

enum decon_iftype {
	IFTYPE_RGB,
	IFTYPE_I80,
	IFTYPE_HDMI
};

enum decon_flag_bits {
	BIT_CLKS_ENABLED,
	BIT_IRQS_ENABLED,
@@ -61,7 +59,7 @@ struct decon_context {
	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
	int				pipe;
	unsigned long			flags;
	enum decon_iftype		out_type;
	unsigned long			out_type;
	int				first_win;
};

@@ -95,7 +93,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)

	if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
		val = VIDINTCON0_INTEN;
		if (ctx->out_type == IFTYPE_I80)
		if (ctx->out_type & IFTYPE_I80)
			val |= VIDINTCON0_FRAMEDONE;
		else
			val |= VIDINTCON0_INTFRMEN;
@@ -119,11 +117,11 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)

static void decon_setup_trigger(struct decon_context *ctx)
{
	u32 val = (ctx->out_type != IFTYPE_HDMI)
	u32 val = !(ctx->out_type & I80_HW_TRG)
		? TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
		  TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN
		: TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
		  TRIGCON_HWTRIGMASK_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB;
		  TRIGCON_HWTRIGMASK | TRIGCON_HWTRIGEN;
	writel(val, ctx->addr + DECON_TRIGCON);
}

@@ -136,7 +134,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	if (ctx->out_type == IFTYPE_HDMI) {
	if (ctx->out_type & IFTYPE_HDMI) {
		m->crtc_hsync_start = m->crtc_hdisplay + 10;
		m->crtc_hsync_end = m->crtc_htotal - 92;
		m->crtc_vsync_start = m->crtc_vdisplay + 1;
@@ -151,17 +149,20 @@ static void decon_commit(struct exynos_drm_crtc *crtc)

	/* lcd on and use command if */
	val = VIDOUT_LCD_ON;
	if (ctx->out_type == IFTYPE_I80)
	if (ctx->out_type & IFTYPE_I80) {
		val |= VIDOUT_COMMAND_IF;
	else
		decon_setup_trigger(ctx);
	} else {
		val |= VIDOUT_RGB_IF;
	}

	writel(val, ctx->addr + DECON_VIDOUTCON0);

	val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
		VIDTCON2_HOZVAL(m->hdisplay - 1);
	writel(val, ctx->addr + DECON_VIDTCON2);

	if (ctx->out_type != IFTYPE_I80) {
	if (!(ctx->out_type & IFTYPE_I80)) {
		val = VIDTCON00_VBPD_F(
				m->crtc_vtotal - m->crtc_vsync_end - 1) |
			VIDTCON00_VFPD_F(
@@ -183,10 +184,10 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
		writel(val, ctx->addr + DECON_VIDTCON11);
	}

	decon_setup_trigger(ctx);

	/* enable output and display signal */
	decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);

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

static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
@@ -300,7 +301,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
	val = dma_addr + pitch * state->src.h;
	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));

	if (ctx->out_type != IFTYPE_HDMI)
	if (!(ctx->out_type & IFTYPE_HDMI))
		val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
			| BIT_VAL(state->crtc.w * bpp, 13, 0);
	else
@@ -312,9 +313,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,

	/* window enable */
	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);

	/* standalone update */
	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}

static void decon_disable_plane(struct exynos_drm_crtc *crtc,
@@ -326,15 +324,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
	if (test_bit(BIT_SUSPENDED, &ctx->flags))
		return;

	decon_shadow_protect_win(ctx, win, true);

	/* window disable */
	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);

	decon_shadow_protect_win(ctx, win, false);

	/* standalone update */
	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}

static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
@@ -348,7 +338,10 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
	for (i = ctx->first_win; i < WINDOWS_NR; i++)
		decon_shadow_protect_win(ctx, i, false);

	if (ctx->out_type == IFTYPE_I80)
	/* standalone update */
	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);

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

@@ -374,7 +367,7 @@ static void decon_swreset(struct decon_context *ctx)

	WARN(tries == 0, "failed to software reset DECON\n");

	if (ctx->out_type != IFTYPE_HDMI)
	if (!(ctx->out_type & IFTYPE_HDMI))
		return;

	writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0);
@@ -383,6 +376,8 @@ static void decon_swreset(struct decon_context *ctx)
	writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
	writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
	       ctx->addr + DECON_CRCCTRL);

	if (ctx->out_type & IFTYPE_I80)
		decon_setup_trigger(ctx);
}

@@ -395,8 +390,12 @@ static void decon_enable(struct exynos_drm_crtc *crtc)

	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);
@@ -424,6 +423,8 @@ static void decon_disable(struct exynos_drm_crtc *crtc)

	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);
@@ -459,8 +460,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
		decon_shadow_protect_win(ctx, win, true);
		decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
		decon_shadow_protect_win(ctx, win, false);
		decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
	}

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

	/* TODO: wait for possible vsync */
	msleep(50);

@@ -509,7 +512,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
	}

	exynos_plane = &ctx->planes[ctx->first_win];
	out_type = (ctx->out_type == IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
	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,
@@ -617,11 +620,11 @@ static const struct dev_pm_ops exynos5433_decon_pm_ops = {
static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
	{
		.compatible = "samsung,exynos5433-decon",
		.data = (void *)IFTYPE_RGB
		.data = (void *)I80_HW_TRG
	},
	{
		.compatible = "samsung,exynos5433-decon-tv",
		.data = (void *)IFTYPE_HDMI
		.data = (void *)(I80_HW_TRG | IFTYPE_HDMI)
	},
	{},
};
@@ -629,7 +632,6 @@ MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);

static int exynos5433_decon_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id;
	struct device *dev = &pdev->dev;
	struct decon_context *ctx;
	struct resource *res;
@@ -642,14 +644,14 @@ static int exynos5433_decon_probe(struct platform_device *pdev)

	__set_bit(BIT_SUSPENDED, &ctx->flags);
	ctx->dev = dev;
	ctx->out_type = (unsigned long)of_device_get_match_data(dev);

	of_id = of_match_device(exynos5433_decon_driver_dt_match, &pdev->dev);
	ctx->out_type = (enum decon_iftype)of_id->data;

	if (ctx->out_type == IFTYPE_HDMI)
	if (ctx->out_type & IFTYPE_HDMI) {
		ctx->first_win = 1;
	else if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
		ctx->out_type = IFTYPE_I80;
	} else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
		ctx->out_type = IFTYPE_I80;
	}

	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
		struct clk *clk;
@@ -674,7 +676,7 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
			(ctx->out_type == IFTYPE_I80) ? "lcd_sys" : "vsync");
			(ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync");
	if (!res) {
		dev_err(dev, "cannot find IRQ resource\n");
		return -ENXIO;
Loading