All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] drm/exynos: TV path improvements
       [not found] <CGME20170929100545eucas1p24e82643e9ba934c6a0a1f437f4c0891a@eucas1p2.samsung.com>
@ 2017-09-29 10:05 ` Andrzej Hajda
       [not found]   ` <CGME20170929100546eucas1p2c06bf97d6961259c617b1e6d3a63f081@eucas1p2.samsung.com>
                     ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Hi all,

This patchset does two main things:
- removes mode limitation for Exynos542x chips, multiple modes were filtered
  out due to lack of HW version checking code,
- enables two modes on older chips, thanks to quirk found by Daniel Drake,
  and published by Tobias Jakobi [1][2].
Beside this it consolidates the code and performs multiple cleanups.

v2:
- addressed comments by Tobias,
- added Daniel's patch adding 1366x768Hz mode

[1]: http://www.spinics.net/lists/linux-samsung-soc/msg24617.html
[2]: https://www.spinics.net/lists/dri-devel/msg150906.html

Regards
Andrzej


Andrzej Hajda (10):
  drm/exynos/mixer: abstract out output mode setup code
  drm/exynos/mixer: move mode commit to enable callback
  drm/exynos/mixer: move resolution configuration to single function
  drm/exynos/mixer: fix mode validation code
  drm/exynos/mixer: remove mixer_resources sub-structure
  drm/exynos/hdmi: remove redundant mode field
  drm/exynos: add mode_fixup callback to exynos_drm_crtc_ops
  drm/exynos/mixer: pass actual mode on MIXER to encoder
  drm/exynos/hdmi: quirk for support mode timings conversion
  drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes

Daniel Drake (1):
  drm/exynos/hdmi: add 85.5MHz pixel clock for v14 HDMI PHY

 drivers/gpu/drm/exynos/exynos_drm_crtc.c |  15 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |   3 +
 drivers/gpu/drm/exynos/exynos_hdmi.c     |  58 ++--
 drivers/gpu/drm/exynos/exynos_mixer.c    | 458 +++++++++++++++----------------
 4 files changed, 278 insertions(+), 256 deletions(-)

-- 
2.14.1

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 01/11] drm/exynos/mixer: abstract out output mode setup code
       [not found]   ` <CGME20170929100546eucas1p2c06bf97d6961259c617b1e6d3a63f081@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Mode setup code is called from video plane update and mixer plane update.
Let's group it together in mixer_commit function like in case of other
Exynos CRTCs.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 002755415e00..499ebdca4fed 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -473,6 +473,22 @@ static void mixer_stop(struct mixer_context *ctx)
 		usleep_range(10000, 12000);
 }
 
+static void mixer_commit(struct mixer_context *ctx)
+{
+	struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode;
+
+	/* setup display size */
+	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
+		u32 val  = MXR_MXR_RES_HEIGHT(mode->vdisplay)
+			 | MXR_MXR_RES_WIDTH(mode->hdisplay);
+		mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION, val);
+	}
+
+	mixer_cfg_scan(ctx, mode->vdisplay);
+	mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
+	mixer_run(ctx);
+}
+
 static void vp_video_buffer(struct mixer_context *ctx,
 			    struct exynos_drm_plane *plane)
 {
@@ -553,11 +569,9 @@ static void vp_video_buffer(struct mixer_context *ctx,
 	vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
 	vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
 
-	mixer_cfg_scan(ctx, mode->vdisplay);
-	mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
 	mixer_cfg_layer(ctx, plane->index, priority, true);
 	mixer_cfg_vp_blend(ctx);
-	mixer_run(ctx);
+	mixer_commit(ctx);
 
 	spin_unlock_irqrestore(&res->reg_slock, flags);
 
@@ -638,14 +652,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 	mixer_reg_write(res, MXR_GRAPHIC_SPAN(win),
 			fb->pitches[0] / fb->format->cpp[0]);
 
-	/* setup display size */
-	if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
-		win == DEFAULT_WIN) {
-		val  = MXR_MXR_RES_HEIGHT(mode->vdisplay);
-		val |= MXR_MXR_RES_WIDTH(mode->hdisplay);
-		mixer_reg_write(res, MXR_RESOLUTION, val);
-	}
-
 	val  = MXR_GRP_WH_WIDTH(state->src.w);
 	val |= MXR_GRP_WH_HEIGHT(state->src.h);
 	val |= MXR_GRP_WH_H_SCALE(x_ratio);
@@ -660,18 +666,15 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 	/* set buffer address to mixer */
 	mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
 
-	mixer_cfg_scan(ctx, mode->vdisplay);
-	mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
 	mixer_cfg_layer(ctx, win, priority, true);
 	mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format));
+	mixer_commit(ctx);
 
 	/* layer update mandatory for mixer 16.0.33.0 */
 	if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
 		ctx->mxr_ver == MXR_VER_128_0_0_184)
 		mixer_layer_update(ctx);
 
-	mixer_run(ctx);
-
 	spin_unlock_irqrestore(&res->reg_slock, flags);
 
 	mixer_regs_dump(ctx);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 02/11] drm/exynos/mixer: move mode commit to enable callback
       [not found]   ` <CGME20170929100546eucas1p20f2a84d13ea64f5c3329e4e641730643@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Mode commit should not be called for every plane separately. It is enough
to call it once in enable callback. The change also requires that
the interlace check is moved to mixer_commit. It should be done in
the same patch to avoid regression.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 499ebdca4fed..ae89e53186ee 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -477,6 +477,11 @@ static void mixer_commit(struct mixer_context *ctx)
 {
 	struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode;
 
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
+	else
+		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
+
 	/* setup display size */
 	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
 		u32 val  = MXR_MXR_RES_HEIGHT(mode->vdisplay)
@@ -494,7 +499,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
 {
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
-	struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
 	struct mixer_resources *res = &ctx->mixer_res;
 	struct drm_framebuffer *fb = state->base.fb;
 	unsigned int priority = state->base.normalized_zpos + 1;
@@ -509,8 +513,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
 	luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0);
 	chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1);
 
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
-		__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
+	if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
 		if (is_tiled) {
 			luma_addr[1] = luma_addr[0] + 0x40;
 			chroma_addr[1] = chroma_addr[0] + 0x40;
@@ -519,7 +522,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
 			chroma_addr[1] = chroma_addr[0] + fb->pitches[0];
 		}
 	} else {
-		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
 		luma_addr[1] = 0;
 		chroma_addr[1] = 0;
 	}
@@ -571,7 +573,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
 
 	mixer_cfg_layer(ctx, plane->index, priority, true);
 	mixer_cfg_vp_blend(ctx);
-	mixer_commit(ctx);
 
 	spin_unlock_irqrestore(&res->reg_slock, flags);
 
@@ -591,7 +592,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 {
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
-	struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
 	struct mixer_resources *res = &ctx->mixer_res;
 	struct drm_framebuffer *fb = state->base.fb;
 	unsigned int priority = state->base.normalized_zpos + 1;
@@ -637,11 +637,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 		+ (state->src.x * fb->format->cpp[0])
 		+ (state->src.y * fb->pitches[0]);
 
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
-	else
-		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
-
 	spin_lock_irqsave(&res->reg_slock, flags);
 
 	/* setup format */
@@ -668,7 +663,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 
 	mixer_cfg_layer(ctx, win, priority, true);
 	mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format));
-	mixer_commit(ctx);
 
 	/* layer update mandatory for mixer 16.0.33.0 */
 	if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
@@ -1021,6 +1015,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
 	}
 	mixer_win_reset(ctx);
 
+	mixer_commit(ctx);
+
 	mixer_vsync_set_update(ctx, true);
 
 	set_bit(MXR_BIT_POWERED, &ctx->flags);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 03/11] drm/exynos/mixer: move resolution configuration to single function
       [not found]   ` <CGME20170929100546eucas1p2b1f4313dc1f769609b10b310c2185786@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Screen resolution configuration depends on HW version, let's put it into
single function to make it consistent and simplify the code.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index ae89e53186ee..a87f60bbf2c2 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -367,7 +367,7 @@ static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
 			VP_SHADOW_UPDATE_ENABLE : 0);
 }
 
-static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
+static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
 {
 	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val;
@@ -376,7 +376,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
 	val = test_bit(MXR_BIT_INTERLACE, &ctx->flags) ?
 		MXR_CFG_SCAN_INTERLACE : MXR_CFG_SCAN_PROGRESSIVE;
 
-	if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
+	/* setup display size */
+	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
+		mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION,
+			MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width));
+	} else {
 		/* choosing between proper HD and SD mode */
 		if (height <= 480)
 			val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
@@ -482,14 +486,7 @@ static void mixer_commit(struct mixer_context *ctx)
 	else
 		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
 
-	/* setup display size */
-	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
-		u32 val  = MXR_MXR_RES_HEIGHT(mode->vdisplay)
-			 | MXR_MXR_RES_WIDTH(mode->hdisplay);
-		mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION, val);
-	}
-
-	mixer_cfg_scan(ctx, mode->vdisplay);
+	mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay);
 	mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
 	mixer_run(ctx);
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 04/11] drm/exynos/mixer: fix mode validation code
       [not found]   ` <CGME20170929100547eucas1p2642f5da0380df27d991cf3b2b1e730b3@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Mode limitation checked in mixer driver affects only older HW.
Mixer in Exynos542x has no such limitations. While at it patch changes
validation callback to recently introduced mode_valid which is more
suitable for the check. Additionally little cleanup is performed.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index a87f60bbf2c2..fba120346189 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1040,26 +1040,24 @@ static void mixer_disable(struct exynos_drm_crtc *crtc)
 	clear_bit(MXR_BIT_POWERED, &ctx->flags);
 }
 
-/* Only valid for Mixer version 16.0.33.0 */
-static int mixer_atomic_check(struct exynos_drm_crtc *crtc,
-		       struct drm_crtc_state *state)
+static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
+		const struct drm_display_mode *mode)
 {
-	struct drm_display_mode *mode = &state->adjusted_mode;
-	u32 w, h;
+	struct mixer_context *ctx = crtc->ctx;
+	u32 w = mode->hdisplay, h = mode->vdisplay;
 
-	w = mode->hdisplay;
-	h = mode->vdisplay;
+	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n", w, h,
+		mode->vrefresh, !!(mode->flags & DRM_MODE_FLAG_INTERLACE));
 
-	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
-		mode->hdisplay, mode->vdisplay, mode->vrefresh,
-		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
+	if (ctx->mxr_ver == MXR_VER_128_0_0_184)
+		return MODE_OK;
 
 	if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
-		(w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
-		(w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
-		return 0;
+	    (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
+	    (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
+		return MODE_OK;
 
-	return -EINVAL;
+	return MODE_BAD;
 }
 
 static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
@@ -1071,7 +1069,7 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
 	.update_plane		= mixer_update_plane,
 	.disable_plane		= mixer_disable_plane,
 	.atomic_flush		= mixer_atomic_flush,
-	.atomic_check		= mixer_atomic_check,
+	.mode_valid		= mixer_mode_valid,
 };
 
 static const struct mixer_drv_data exynos5420_mxr_drv_data = {
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 05/11] drm/exynos/mixer: remove mixer_resources sub-structure
       [not found]   ` <CGME20170929100548eucas1p113a840591a4bf961272384516984957e@eucas1p1.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  2017-10-16 10:02       ` Inki Dae
  0 siblings, 1 reply; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

mixer_resources adds only unnecessary redirection, removing it makes the
code shorter and cleaner.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 323 ++++++++++++++++------------------
 1 file changed, 147 insertions(+), 176 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index fba120346189..2d8905ea0141 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -67,19 +67,6 @@
 #define MXR_FORMAT_ARGB4444	6
 #define MXR_FORMAT_ARGB8888	7
 
-struct mixer_resources {
-	int			irq;
-	void __iomem		*mixer_regs;
-	void __iomem		*vp_regs;
-	spinlock_t		reg_slock;
-	struct clk		*mixer;
-	struct clk		*vp;
-	struct clk		*hdmi;
-	struct clk		*sclk_mixer;
-	struct clk		*sclk_hdmi;
-	struct clk		*mout_mixer;
-};
-
 enum mixer_version_id {
 	MXR_VER_0_0_0_16,
 	MXR_VER_16_0_33_0,
@@ -117,7 +104,16 @@ struct mixer_context {
 	struct exynos_drm_plane	planes[MIXER_WIN_NR];
 	unsigned long		flags;
 
-	struct mixer_resources	mixer_res;
+	int			irq;
+	void __iomem		*mixer_regs;
+	void __iomem		*vp_regs;
+	spinlock_t		reg_slock;
+	struct clk		*mixer;
+	struct clk		*vp;
+	struct clk		*hdmi;
+	struct clk		*sclk_mixer;
+	struct clk		*sclk_hdmi;
+	struct clk		*mout_mixer;
 	enum mixer_version_id	mxr_ver;
 };
 
@@ -194,44 +190,44 @@ static inline bool is_alpha_format(unsigned int pixel_format)
 	}
 }
 
-static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
+static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id)
 {
-	return readl(res->vp_regs + reg_id);
+	return readl(ctx->vp_regs + reg_id);
 }
 
-static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
+static inline void vp_reg_write(struct mixer_context *ctx, u32 reg_id,
 				 u32 val)
 {
-	writel(val, res->vp_regs + reg_id);
+	writel(val, ctx->vp_regs + reg_id);
 }
 
-static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
+static inline void vp_reg_writemask(struct mixer_context *ctx, u32 reg_id,
 				 u32 val, u32 mask)
 {
-	u32 old = vp_reg_read(res, reg_id);
+	u32 old = vp_reg_read(ctx, reg_id);
 
 	val = (val & mask) | (old & ~mask);
-	writel(val, res->vp_regs + reg_id);
+	writel(val, ctx->vp_regs + reg_id);
 }
 
-static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
+static inline u32 mixer_reg_read(struct mixer_context *ctx, u32 reg_id)
 {
-	return readl(res->mixer_regs + reg_id);
+	return readl(ctx->mixer_regs + reg_id);
 }
 
-static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
+static inline void mixer_reg_write(struct mixer_context *ctx, u32 reg_id,
 				 u32 val)
 {
-	writel(val, res->mixer_regs + reg_id);
+	writel(val, ctx->mixer_regs + reg_id);
 }
 
-static inline void mixer_reg_writemask(struct mixer_resources *res,
+static inline void mixer_reg_writemask(struct mixer_context *ctx,
 				 u32 reg_id, u32 val, u32 mask)
 {
-	u32 old = mixer_reg_read(res, reg_id);
+	u32 old = mixer_reg_read(ctx, reg_id);
 
 	val = (val & mask) | (old & ~mask);
-	writel(val, res->mixer_regs + reg_id);
+	writel(val, ctx->mixer_regs + reg_id);
 }
 
 static void mixer_regs_dump(struct mixer_context *ctx)
@@ -239,7 +235,7 @@ static void mixer_regs_dump(struct mixer_context *ctx)
 #define DUMPREG(reg_id) \
 do { \
 	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
-		(u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
+		(u32)readl(ctx->mixer_regs + reg_id)); \
 } while (0)
 
 	DUMPREG(MXR_STATUS);
@@ -271,7 +267,7 @@ static void vp_regs_dump(struct mixer_context *ctx)
 #define DUMPREG(reg_id) \
 do { \
 	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
-		(u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
+		(u32) readl(ctx->vp_regs + reg_id)); \
 } while (0)
 
 	DUMPREG(VP_ENABLE);
@@ -301,7 +297,7 @@ do { \
 #undef DUMPREG
 }
 
-static inline void vp_filter_set(struct mixer_resources *res,
+static inline void vp_filter_set(struct mixer_context *ctx,
 		int reg_id, const u8 *data, unsigned int size)
 {
 	/* assure 4-byte align */
@@ -309,24 +305,23 @@ static inline void vp_filter_set(struct mixer_resources *res,
 	for (; size; size -= 4, reg_id += 4, data += 4) {
 		u32 val = (data[0] << 24) |  (data[1] << 16) |
 			(data[2] << 8) | data[3];
-		vp_reg_write(res, reg_id, val);
+		vp_reg_write(ctx, reg_id, val);
 	}
 }
 
-static void vp_default_filter(struct mixer_resources *res)
+static void vp_default_filter(struct mixer_context *ctx)
 {
-	vp_filter_set(res, VP_POLY8_Y0_LL,
+	vp_filter_set(ctx, VP_POLY8_Y0_LL,
 		filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
-	vp_filter_set(res, VP_POLY4_Y0_LL,
+	vp_filter_set(ctx, VP_POLY4_Y0_LL,
 		filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
-	vp_filter_set(res, VP_POLY4_C0_LL,
+	vp_filter_set(ctx, VP_POLY4_C0_LL,
 		filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
 }
 
 static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
 				bool alpha)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val;
 
 	val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
@@ -335,13 +330,12 @@ static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
 		val |= MXR_GRP_CFG_BLEND_PRE_MUL;
 		val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
 	}
-	mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
+	mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
 			    val, MXR_GRP_CFG_MISC_MASK);
 }
 
 static void mixer_cfg_vp_blend(struct mixer_context *ctx)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val;
 
 	/*
@@ -351,25 +345,22 @@ static void mixer_cfg_vp_blend(struct mixer_context *ctx)
 	 * support blending of the video layer through this.
 	 */
 	val = 0;
-	mixer_reg_write(res, MXR_VIDEO_CFG, val);
+	mixer_reg_write(ctx, MXR_VIDEO_CFG, val);
 }
 
 static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
-
 	/* block update on vsync */
-	mixer_reg_writemask(res, MXR_STATUS, enable ?
+	mixer_reg_writemask(ctx, MXR_STATUS, enable ?
 			MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
 
 	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
-		vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
+		vp_reg_write(ctx, VP_SHADOW_UPDATE, enable ?
 			VP_SHADOW_UPDATE_ENABLE : 0);
 }
 
 static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val;
 
 	/* choosing between interlace and progressive mode */
@@ -378,7 +369,7 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
 
 	/* setup display size */
 	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
-		mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION,
+		mixer_reg_write(ctx, MXR_RESOLUTION,
 			MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width));
 	} else {
 		/* choosing between proper HD and SD mode */
@@ -394,12 +385,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
 			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
 	}
 
-	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
+	mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK);
 }
 
 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val;
 
 	switch (height) {
@@ -412,45 +402,44 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
 	default:
 		val = MXR_CFG_RGB709_16_235;
 		/* Configure the BT.709 CSC matrix for full range RGB. */
-		mixer_reg_write(res, MXR_CM_COEFF_Y,
+		mixer_reg_write(ctx, MXR_CM_COEFF_Y,
 			MXR_CSC_CT( 0.184,  0.614,  0.063) |
 			MXR_CM_COEFF_RGB_FULL);
-		mixer_reg_write(res, MXR_CM_COEFF_CB,
+		mixer_reg_write(ctx, MXR_CM_COEFF_CB,
 			MXR_CSC_CT(-0.102, -0.338,  0.440));
-		mixer_reg_write(res, MXR_CM_COEFF_CR,
+		mixer_reg_write(ctx, MXR_CM_COEFF_CR,
 			MXR_CSC_CT( 0.440, -0.399, -0.040));
 		break;
 	}
 
-	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
+	mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
 }
 
 static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
 			    unsigned int priority, bool enable)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val = enable ? ~0 : 0;
 
 	switch (win) {
 	case 0:
-		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
-		mixer_reg_writemask(res, MXR_LAYER_CFG,
+		mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
+		mixer_reg_writemask(ctx, MXR_LAYER_CFG,
 				    MXR_LAYER_CFG_GRP0_VAL(priority),
 				    MXR_LAYER_CFG_GRP0_MASK);
 		break;
 	case 1:
-		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
-		mixer_reg_writemask(res, MXR_LAYER_CFG,
+		mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
+		mixer_reg_writemask(ctx, MXR_LAYER_CFG,
 				    MXR_LAYER_CFG_GRP1_VAL(priority),
 				    MXR_LAYER_CFG_GRP1_MASK);
 
 		break;
 	case VP_DEFAULT_WIN:
 		if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
-			vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
-			mixer_reg_writemask(res, MXR_CFG, val,
+			vp_reg_writemask(ctx, VP_ENABLE, val, VP_ENABLE_ON);
+			mixer_reg_writemask(ctx, MXR_CFG, val,
 				MXR_CFG_VP_ENABLE);
-			mixer_reg_writemask(res, MXR_LAYER_CFG,
+			mixer_reg_writemask(ctx, MXR_LAYER_CFG,
 					    MXR_LAYER_CFG_VP_VAL(priority),
 					    MXR_LAYER_CFG_VP_MASK);
 		}
@@ -460,19 +449,16 @@ static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
 
 static void mixer_run(struct mixer_context *ctx)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
-
-	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
+	mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
 }
 
 static void mixer_stop(struct mixer_context *ctx)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	int timeout = 20;
 
-	mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
+	mixer_reg_writemask(ctx, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
 
-	while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
+	while (!(mixer_reg_read(ctx, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
 			--timeout)
 		usleep_range(10000, 12000);
 }
@@ -496,7 +482,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
 {
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
-	struct mixer_resources *res = &ctx->mixer_res;
 	struct drm_framebuffer *fb = state->base.fb;
 	unsigned int priority = state->base.normalized_zpos + 1;
 	unsigned long flags;
@@ -523,55 +508,55 @@ static void vp_video_buffer(struct mixer_context *ctx,
 		chroma_addr[1] = 0;
 	}
 
-	spin_lock_irqsave(&res->reg_slock, flags);
+	spin_lock_irqsave(&ctx->reg_slock, flags);
 
 	/* interlace or progressive scan mode */
 	val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0);
-	vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
+	vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP);
 
 	/* setup format */
 	val = (is_nv21 ? VP_MODE_NV21 : VP_MODE_NV12);
 	val |= (is_tiled ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
-	vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
+	vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_FMT_MASK);
 
 	/* setting size of input image */
-	vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
+	vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
 		VP_IMG_VSIZE(fb->height));
 	/* chroma plane for NV12/NV21 is half the height of the luma plane */
-	vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
+	vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
 		VP_IMG_VSIZE(fb->height / 2));
 
-	vp_reg_write(res, VP_SRC_WIDTH, state->src.w);
-	vp_reg_write(res, VP_SRC_HEIGHT, state->src.h);
-	vp_reg_write(res, VP_SRC_H_POSITION,
+	vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w);
+	vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h);
+	vp_reg_write(ctx, VP_SRC_H_POSITION,
 			VP_SRC_H_POSITION_VAL(state->src.x));
-	vp_reg_write(res, VP_SRC_V_POSITION, state->src.y);
+	vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y);
 
-	vp_reg_write(res, VP_DST_WIDTH, state->crtc.w);
-	vp_reg_write(res, VP_DST_H_POSITION, state->crtc.x);
+	vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w);
+	vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x);
 	if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
-		vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h / 2);
-		vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y / 2);
+		vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2);
+		vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2);
 	} else {
-		vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h);
-		vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y);
+		vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h);
+		vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y);
 	}
 
-	vp_reg_write(res, VP_H_RATIO, state->h_ratio);
-	vp_reg_write(res, VP_V_RATIO, state->v_ratio);
+	vp_reg_write(ctx, VP_H_RATIO, state->h_ratio);
+	vp_reg_write(ctx, VP_V_RATIO, state->v_ratio);
 
-	vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
+	vp_reg_write(ctx, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
 
 	/* set buffer address to vp */
-	vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
-	vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
-	vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
-	vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
+	vp_reg_write(ctx, VP_TOP_Y_PTR, luma_addr[0]);
+	vp_reg_write(ctx, VP_BOT_Y_PTR, luma_addr[1]);
+	vp_reg_write(ctx, VP_TOP_C_PTR, chroma_addr[0]);
+	vp_reg_write(ctx, VP_BOT_C_PTR, chroma_addr[1]);
 
 	mixer_cfg_layer(ctx, plane->index, priority, true);
 	mixer_cfg_vp_blend(ctx);
 
-	spin_unlock_irqrestore(&res->reg_slock, flags);
+	spin_unlock_irqrestore(&ctx->reg_slock, flags);
 
 	mixer_regs_dump(ctx);
 	vp_regs_dump(ctx);
@@ -579,9 +564,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
 
 static void mixer_layer_update(struct mixer_context *ctx)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
-
-	mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
+	mixer_reg_writemask(ctx, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
 }
 
 static void mixer_graph_buffer(struct mixer_context *ctx,
@@ -589,7 +572,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 {
 	struct exynos_drm_plane_state *state =
 				to_exynos_plane_state(plane->base.state);
-	struct mixer_resources *res = &ctx->mixer_res;
 	struct drm_framebuffer *fb = state->base.fb;
 	unsigned int priority = state->base.normalized_zpos + 1;
 	unsigned long flags;
@@ -634,29 +616,29 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 		+ (state->src.x * fb->format->cpp[0])
 		+ (state->src.y * fb->pitches[0]);
 
-	spin_lock_irqsave(&res->reg_slock, flags);
+	spin_lock_irqsave(&ctx->reg_slock, flags);
 
 	/* setup format */
-	mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
+	mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
 		MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
 
 	/* setup geometry */
-	mixer_reg_write(res, MXR_GRAPHIC_SPAN(win),
+	mixer_reg_write(ctx, MXR_GRAPHIC_SPAN(win),
 			fb->pitches[0] / fb->format->cpp[0]);
 
 	val  = MXR_GRP_WH_WIDTH(state->src.w);
 	val |= MXR_GRP_WH_HEIGHT(state->src.h);
 	val |= MXR_GRP_WH_H_SCALE(x_ratio);
 	val |= MXR_GRP_WH_V_SCALE(y_ratio);
-	mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
+	mixer_reg_write(ctx, MXR_GRAPHIC_WH(win), val);
 
 	/* setup offsets in display image */
 	val  = MXR_GRP_DXY_DX(dst_x_offset);
 	val |= MXR_GRP_DXY_DY(dst_y_offset);
-	mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
+	mixer_reg_write(ctx, MXR_GRAPHIC_DXY(win), val);
 
 	/* set buffer address to mixer */
-	mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
+	mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr);
 
 	mixer_cfg_layer(ctx, win, priority, true);
 	mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format));
@@ -666,20 +648,19 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
 		ctx->mxr_ver == MXR_VER_128_0_0_184)
 		mixer_layer_update(ctx);
 
-	spin_unlock_irqrestore(&res->reg_slock, flags);
+	spin_unlock_irqrestore(&ctx->reg_slock, flags);
 
 	mixer_regs_dump(ctx);
 }
 
 static void vp_win_reset(struct mixer_context *ctx)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	unsigned int tries = 100;
 
-	vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
+	vp_reg_write(ctx, VP_SRESET, VP_SRESET_PROCESSING);
 	while (--tries) {
 		/* waiting until VP_SRESET_PROCESSING is 0 */
-		if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
+		if (~vp_reg_read(ctx, VP_SRESET) & VP_SRESET_PROCESSING)
 			break;
 		mdelay(10);
 	}
@@ -688,57 +669,55 @@ static void vp_win_reset(struct mixer_context *ctx)
 
 static void mixer_win_reset(struct mixer_context *ctx)
 {
-	struct mixer_resources *res = &ctx->mixer_res;
 	unsigned long flags;
 
-	spin_lock_irqsave(&res->reg_slock, flags);
+	spin_lock_irqsave(&ctx->reg_slock, flags);
 
-	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
+	mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
 
 	/* set output in RGB888 mode */
-	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
+	mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
 
 	/* 16 beat burst in DMA */
-	mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
+	mixer_reg_writemask(ctx, MXR_STATUS, MXR_STATUS_16_BURST,
 		MXR_STATUS_BURST_MASK);
 
 	/* reset default layer priority */
-	mixer_reg_write(res, MXR_LAYER_CFG, 0);
+	mixer_reg_write(ctx, MXR_LAYER_CFG, 0);
 
 	/* set all background colors to RGB (0,0,0) */
-	mixer_reg_write(res, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128));
-	mixer_reg_write(res, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128));
-	mixer_reg_write(res, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128));
+	mixer_reg_write(ctx, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128));
+	mixer_reg_write(ctx, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128));
+	mixer_reg_write(ctx, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128));
 
 	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
 		/* configuration of Video Processor Registers */
 		vp_win_reset(ctx);
-		vp_default_filter(res);
+		vp_default_filter(ctx);
 	}
 
 	/* disable all layers */
-	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
-	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
+	mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
+	mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
 	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
-		mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
+		mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
 
 	/* set all source image offsets to zero */
-	mixer_reg_write(res, MXR_GRAPHIC_SXY(0), 0);
-	mixer_reg_write(res, MXR_GRAPHIC_SXY(1), 0);
+	mixer_reg_write(ctx, MXR_GRAPHIC_SXY(0), 0);
+	mixer_reg_write(ctx, MXR_GRAPHIC_SXY(1), 0);
 
-	spin_unlock_irqrestore(&res->reg_slock, flags);
+	spin_unlock_irqrestore(&ctx->reg_slock, flags);
 }
 
 static irqreturn_t mixer_irq_handler(int irq, void *arg)
 {
 	struct mixer_context *ctx = arg;
-	struct mixer_resources *res = &ctx->mixer_res;
 	u32 val, base, shadow;
 
-	spin_lock(&res->reg_slock);
+	spin_lock(&ctx->reg_slock);
 
 	/* read interrupt status for handling and clearing flags for VSYNC */
-	val = mixer_reg_read(res, MXR_INT_STATUS);
+	val = mixer_reg_read(ctx, MXR_INT_STATUS);
 
 	/* handling VSYNC */
 	if (val & MXR_INT_STATUS_VSYNC) {
@@ -748,13 +727,13 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
 
 		/* interlace scan need to check shadow register */
 		if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
-			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
-			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
+			base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0));
+			shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0));
 			if (base != shadow)
 				goto out;
 
-			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
-			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
+			base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(1));
+			shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(1));
 			if (base != shadow)
 				goto out;
 		}
@@ -764,9 +743,9 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
 
 out:
 	/* clear interrupts */
-	mixer_reg_write(res, MXR_INT_STATUS, val);
+	mixer_reg_write(ctx, MXR_INT_STATUS, val);
 
-	spin_unlock(&res->reg_slock);
+	spin_unlock(&ctx->reg_slock);
 
 	return IRQ_HANDLED;
 }
@@ -774,26 +753,25 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
 static int mixer_resources_init(struct mixer_context *mixer_ctx)
 {
 	struct device *dev = &mixer_ctx->pdev->dev;
-	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
 	struct resource *res;
 	int ret;
 
-	spin_lock_init(&mixer_res->reg_slock);
+	spin_lock_init(&mixer_ctx->reg_slock);
 
-	mixer_res->mixer = devm_clk_get(dev, "mixer");
-	if (IS_ERR(mixer_res->mixer)) {
+	mixer_ctx->mixer = devm_clk_get(dev, "mixer");
+	if (IS_ERR(mixer_ctx->mixer)) {
 		dev_err(dev, "failed to get clock 'mixer'\n");
 		return -ENODEV;
 	}
 
-	mixer_res->hdmi = devm_clk_get(dev, "hdmi");
-	if (IS_ERR(mixer_res->hdmi)) {
+	mixer_ctx->hdmi = devm_clk_get(dev, "hdmi");
+	if (IS_ERR(mixer_ctx->hdmi)) {
 		dev_err(dev, "failed to get clock 'hdmi'\n");
-		return PTR_ERR(mixer_res->hdmi);
+		return PTR_ERR(mixer_ctx->hdmi);
 	}
 
-	mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
-	if (IS_ERR(mixer_res->sclk_hdmi)) {
+	mixer_ctx->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
+	if (IS_ERR(mixer_ctx->sclk_hdmi)) {
 		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
 		return -ENODEV;
 	}
@@ -803,9 +781,9 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
 		return -ENXIO;
 	}
 
-	mixer_res->mixer_regs = devm_ioremap(dev, res->start,
+	mixer_ctx->mixer_regs = devm_ioremap(dev, res->start,
 							resource_size(res));
-	if (mixer_res->mixer_regs == NULL) {
+	if (mixer_ctx->mixer_regs == NULL) {
 		dev_err(dev, "register mapping failed.\n");
 		return -ENXIO;
 	}
@@ -822,7 +800,7 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
 		dev_err(dev, "request interrupt failed.\n");
 		return ret;
 	}
-	mixer_res->irq = res->start;
+	mixer_ctx->irq = res->start;
 
 	return 0;
 }
@@ -830,30 +808,29 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
 static int vp_resources_init(struct mixer_context *mixer_ctx)
 {
 	struct device *dev = &mixer_ctx->pdev->dev;
-	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
 	struct resource *res;
 
-	mixer_res->vp = devm_clk_get(dev, "vp");
-	if (IS_ERR(mixer_res->vp)) {
+	mixer_ctx->vp = devm_clk_get(dev, "vp");
+	if (IS_ERR(mixer_ctx->vp)) {
 		dev_err(dev, "failed to get clock 'vp'\n");
 		return -ENODEV;
 	}
 
 	if (test_bit(MXR_BIT_HAS_SCLK, &mixer_ctx->flags)) {
-		mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
-		if (IS_ERR(mixer_res->sclk_mixer)) {
+		mixer_ctx->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
+		if (IS_ERR(mixer_ctx->sclk_mixer)) {
 			dev_err(dev, "failed to get clock 'sclk_mixer'\n");
 			return -ENODEV;
 		}
-		mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
-		if (IS_ERR(mixer_res->mout_mixer)) {
+		mixer_ctx->mout_mixer = devm_clk_get(dev, "mout_mixer");
+		if (IS_ERR(mixer_ctx->mout_mixer)) {
 			dev_err(dev, "failed to get clock 'mout_mixer'\n");
 			return -ENODEV;
 		}
 
-		if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
-			clk_set_parent(mixer_res->mout_mixer,
-				       mixer_res->sclk_hdmi);
+		if (mixer_ctx->sclk_hdmi && mixer_ctx->mout_mixer)
+			clk_set_parent(mixer_ctx->mout_mixer,
+				       mixer_ctx->sclk_hdmi);
 	}
 
 	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
@@ -862,9 +839,9 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
 		return -ENXIO;
 	}
 
-	mixer_res->vp_regs = devm_ioremap(dev, res->start,
+	mixer_ctx->vp_regs = devm_ioremap(dev, res->start,
 							resource_size(res));
-	if (mixer_res->vp_regs == NULL) {
+	if (mixer_ctx->vp_regs == NULL) {
 		dev_err(dev, "register mapping failed.\n");
 		return -ENXIO;
 	}
@@ -908,15 +885,14 @@ static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
 static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
 {
 	struct mixer_context *mixer_ctx = crtc->ctx;
-	struct mixer_resources *res = &mixer_ctx->mixer_res;
 
 	__set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
 	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
 		return 0;
 
 	/* enable vsync interrupt */
-	mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
-	mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
+	mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
+	mixer_reg_writemask(mixer_ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
 
 	return 0;
 }
@@ -924,7 +900,6 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
 static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
 {
 	struct mixer_context *mixer_ctx = crtc->ctx;
-	struct mixer_resources *res = &mixer_ctx->mixer_res;
 
 	__clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
 
@@ -932,8 +907,8 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
 		return;
 
 	/* disable vsync interrupt */
-	mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
-	mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
+	mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
+	mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
 }
 
 static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
@@ -966,7 +941,6 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
 				struct exynos_drm_plane *plane)
 {
 	struct mixer_context *mixer_ctx = crtc->ctx;
-	struct mixer_resources *res = &mixer_ctx->mixer_res;
 	unsigned long flags;
 
 	DRM_DEBUG_KMS("win: %d\n", plane->index);
@@ -974,9 +948,9 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
 	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
 		return;
 
-	spin_lock_irqsave(&res->reg_slock, flags);
+	spin_lock_irqsave(&mixer_ctx->reg_slock, flags);
 	mixer_cfg_layer(mixer_ctx, plane->index, 0, false);
-	spin_unlock_irqrestore(&res->reg_slock, flags);
+	spin_unlock_irqrestore(&mixer_ctx->reg_slock, flags);
 }
 
 static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
@@ -993,7 +967,6 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
 static void mixer_enable(struct exynos_drm_crtc *crtc)
 {
 	struct mixer_context *ctx = crtc->ctx;
-	struct mixer_resources *res = &ctx->mixer_res;
 
 	if (test_bit(MXR_BIT_POWERED, &ctx->flags))
 		return;
@@ -1004,11 +977,11 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
 
 	mixer_vsync_set_update(ctx, false);
 
-	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
+	mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
 
 	if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) {
-		mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
-		mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
+		mixer_reg_writemask(ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
+		mixer_reg_writemask(ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
 	}
 	mixer_win_reset(ctx);
 
@@ -1211,14 +1184,13 @@ static int mixer_remove(struct platform_device *pdev)
 static int __maybe_unused exynos_mixer_suspend(struct device *dev)
 {
 	struct mixer_context *ctx = dev_get_drvdata(dev);
-	struct mixer_resources *res = &ctx->mixer_res;
 
-	clk_disable_unprepare(res->hdmi);
-	clk_disable_unprepare(res->mixer);
+	clk_disable_unprepare(ctx->hdmi);
+	clk_disable_unprepare(ctx->mixer);
 	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
-		clk_disable_unprepare(res->vp);
+		clk_disable_unprepare(ctx->vp);
 		if (test_bit(MXR_BIT_HAS_SCLK, &ctx->flags))
-			clk_disable_unprepare(res->sclk_mixer);
+			clk_disable_unprepare(ctx->sclk_mixer);
 	}
 
 	return 0;
@@ -1227,28 +1199,27 @@ static int __maybe_unused exynos_mixer_suspend(struct device *dev)
 static int __maybe_unused exynos_mixer_resume(struct device *dev)
 {
 	struct mixer_context *ctx = dev_get_drvdata(dev);
-	struct mixer_resources *res = &ctx->mixer_res;
 	int ret;
 
-	ret = clk_prepare_enable(res->mixer);
+	ret = clk_prepare_enable(ctx->mixer);
 	if (ret < 0) {
 		DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret);
 		return ret;
 	}
-	ret = clk_prepare_enable(res->hdmi);
+	ret = clk_prepare_enable(ctx->hdmi);
 	if (ret < 0) {
 		DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
 		return ret;
 	}
 	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
-		ret = clk_prepare_enable(res->vp);
+		ret = clk_prepare_enable(ctx->vp);
 		if (ret < 0) {
 			DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
 				  ret);
 			return ret;
 		}
 		if (test_bit(MXR_BIT_HAS_SCLK, &ctx->flags)) {
-			ret = clk_prepare_enable(res->sclk_mixer);
+			ret = clk_prepare_enable(ctx->sclk_mixer);
 			if (ret < 0) {
 				DRM_ERROR("Failed to prepare_enable the " \
 					   "sclk_mixer clk [%d]\n",
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 06/11] drm/exynos/hdmi: remove redundant mode field
       [not found]   ` <CGME20170929100548eucas1p2cf6293ef0d013016afcafb4d6194e8be@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Display mode is preserved in CRTC state, there is no need to keep local
copy of it. Moreover since HDMI should configure registers according to
requested mode, use it instead of adjusted_mode, which should contain
mode produced by CRTC - functionally it does not change anything, but
subsequent patches will make the difference.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 34 +++++++++-------------------------
 1 file changed, 9 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 214fa5e51963..7225b6521148 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -119,7 +119,6 @@ struct hdmi_context {
 	bool				powered;
 	bool				dvi_mode;
 	struct delayed_work		hotplug_work;
-	struct drm_display_mode		current_mode;
 	struct cec_notifier		*notifier;
 	const struct hdmi_driver_data	*drv_data;
 
@@ -770,6 +769,7 @@ static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
 
 static void hdmi_reg_infoframes(struct hdmi_context *hdata)
 {
+	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 	union hdmi_infoframe frm;
 	u8 buf[25];
 	int ret;
@@ -783,8 +783,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata)
 		return;
 	}
 
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
-			&hdata->current_mode, false);
+	ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, m, false);
 	if (!ret)
 		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
 	if (ret > 0) {
@@ -794,8 +793,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata)
 		DRM_INFO("%s: invalid AVI infoframe (%d)\n", __func__, ret);
 	}
 
-	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi,
-			&hdata->current_mode);
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frm.vendor.hdmi, m);
 	if (!ret)
 		ret = hdmi_vendor_infoframe_pack(&frm.vendor.hdmi, buf,
 				sizeof(buf));
@@ -1088,9 +1086,10 @@ static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
 
 static void hdmi_start(struct hdmi_context *hdata, bool start)
 {
+	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 	u32 val = start ? HDMI_TG_EN : 0;
 
-	if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (m->flags & DRM_MODE_FLAG_INTERLACE)
 		val |= HDMI_FIELD_EN;
 
 	hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
@@ -1160,7 +1159,7 @@ static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
 
 static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
 {
-	struct drm_display_mode *m = &hdata->current_mode;
+	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 	unsigned int val;
 
 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
@@ -1239,7 +1238,7 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
 
 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
 {
-	struct drm_display_mode *m = &hdata->current_mode;
+	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 
 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
 	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
@@ -1372,10 +1371,11 @@ static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
 
 static void hdmiphy_conf_apply(struct hdmi_context *hdata)
 {
+	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
 	int ret;
 	const u8 *phy_conf;
 
-	ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
+	ret = hdmi_find_phy_conf(hdata, m->clock * 1000);
 	if (ret < 0) {
 		DRM_ERROR("failed to find hdmiphy conf\n");
 		return;
@@ -1407,21 +1407,6 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
 	hdmi_audio_control(hdata, true);
 }
 
-static void hdmi_mode_set(struct drm_encoder *encoder,
-			  struct drm_display_mode *mode,
-			  struct drm_display_mode *adjusted_mode)
-{
-	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
-	struct drm_display_mode *m = adjusted_mode;
-
-	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
-		m->hdisplay, m->vdisplay,
-		m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
-		"INTERLACED" : "PROGRESSIVE");
-
-	drm_mode_copy(&hdata->current_mode, m);
-}
-
 static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
 {
 	if (!hdata->sysreg)
@@ -1504,7 +1489,6 @@ static void hdmi_disable(struct drm_encoder *encoder)
 
 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
 	.mode_fixup	= hdmi_mode_fixup,
-	.mode_set	= hdmi_mode_set,
 	.enable		= hdmi_enable,
 	.disable	= hdmi_disable,
 };
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 07/11] drm/exynos: add mode_fixup callback to exynos_drm_crtc_ops
       [not found]   ` <CGME20170929100548eucas1p26c83f7cf1e82d4cd052e19d4d06cdbfa@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

crtc::mode_fixup callback is required by crtcs which internally use
a different mode than requested by user - case of Exynos Mixer.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c | 15 +++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |  3 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 6ce0821590df..dc01342e759a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -95,8 +95,23 @@ static enum drm_mode_status exynos_crtc_mode_valid(struct drm_crtc *crtc,
 	return MODE_OK;
 }
 
+static bool exynos_crtc_mode_fixup(struct drm_crtc *crtc,
+		const struct drm_display_mode *mode,
+		struct drm_display_mode *adjusted_mode)
+{
+	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+
+	if (exynos_crtc->ops->mode_fixup)
+		return exynos_crtc->ops->mode_fixup(exynos_crtc, mode,
+				adjusted_mode);
+
+	return true;
+}
+
+
 static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
 	.mode_valid	= exynos_crtc_mode_valid,
+	.mode_fixup	= exynos_crtc_mode_fixup,
 	.atomic_check	= exynos_crtc_atomic_check,
 	.atomic_begin	= exynos_crtc_atomic_begin,
 	.atomic_flush	= exynos_crtc_atomic_flush,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index cf131c2aa23e..e8bcc7223016 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -136,6 +136,9 @@ struct exynos_drm_crtc_ops {
 	u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc);
 	enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc,
 		const struct drm_display_mode *mode);
+	bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
+			   const struct drm_display_mode *mode,
+			   struct drm_display_mode *adjusted_mode);
 	int (*atomic_check)(struct exynos_drm_crtc *crtc,
 			    struct drm_crtc_state *state);
 	void (*atomic_begin)(struct exynos_drm_crtc *crtc);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 08/11] drm/exynos/mixer: pass actual mode on MIXER to encoder
       [not found]   ` <CGME20170929100549eucas1p2eddc8a5e6908a69c9c91be488906852f@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
720x480, 720x576, 1280x720, 1920x1080. Support for other modes can be
enabled by manipulating timings of HDMI. To allow it MIXER must pass
actual video mode to HDMI, the proper way to do it is to modify
adjusted_mode property in crtc::mode_fixup callback. Adding such callback
allows also to simplify mixer_cfg_scan code - choosing mode is performed
already in crtc::mode_fixup. mode_fixup is also better place to check
interlace flag.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 70 +++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 2d8905ea0141..8baa93f80106 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -115,6 +115,7 @@ struct mixer_context {
 	struct clk		*sclk_hdmi;
 	struct clk		*mout_mixer;
 	enum mixer_version_id	mxr_ver;
+	int			scan_value;
 };
 
 struct mixer_drv_data {
@@ -367,23 +368,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
 	val = test_bit(MXR_BIT_INTERLACE, &ctx->flags) ?
 		MXR_CFG_SCAN_INTERLACE : MXR_CFG_SCAN_PROGRESSIVE;
 
-	/* setup display size */
-	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
+	if (ctx->mxr_ver == MXR_VER_128_0_0_184)
 		mixer_reg_write(ctx, MXR_RESOLUTION,
 			MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width));
-	} else {
-		/* choosing between proper HD and SD mode */
-		if (height <= 480)
-			val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
-		else if (height <= 576)
-			val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
-		else if (height <= 720)
-			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
-		else if (height <= 1080)
-			val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
-		else
-			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
-	}
+	else
+		val |= ctx->scan_value;
 
 	mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK);
 }
@@ -467,11 +456,6 @@ static void mixer_commit(struct mixer_context *ctx)
 {
 	struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode;
 
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
-	else
-		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
-
 	mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay);
 	mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
 	mixer_run(ctx);
@@ -1033,6 +1017,51 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
 	return MODE_BAD;
 }
 
+static bool mixer_mode_fixup(struct exynos_drm_crtc *crtc,
+		   const struct drm_display_mode *mode,
+		   struct drm_display_mode *adjusted_mode)
+{
+	struct mixer_context *ctx = crtc->ctx;
+	int width = mode->hdisplay, height = mode->vdisplay, i;
+
+	struct {
+		int hdisplay, vdisplay, htotal, vtotal, scan_val;
+	} static const modes[] = {
+		{ 720, 480, 858, 525, MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD },
+		{ 720, 576, 864, 625, MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD },
+		{ 1280, 720, 1650, 750, MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD },
+		{ 1920, 1080, 2200, 1125, MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD }
+	};
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
+	else
+		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
+
+	if (ctx->mxr_ver == MXR_VER_128_0_0_184)
+		return true;
+
+	for (i = 0; i < ARRAY_SIZE(modes); ++i)
+		if (width <= modes[i].hdisplay && height <= modes[i].vdisplay) {
+			ctx->scan_value = modes[i].scan_val;
+			if (width < modes[i].hdisplay ||
+			    height < modes[i].vdisplay) {
+				adjusted_mode->hdisplay = modes[i].hdisplay;
+				adjusted_mode->hsync_start = modes[i].hdisplay;
+				adjusted_mode->hsync_end = modes[i].htotal;
+				adjusted_mode->htotal = modes[i].htotal;
+				adjusted_mode->vdisplay = modes[i].vdisplay;
+				adjusted_mode->vsync_start = modes[i].vdisplay;
+				adjusted_mode->vsync_end = modes[i].vtotal;
+				adjusted_mode->vtotal = modes[i].vtotal;
+			}
+
+			return true;
+		}
+
+	return false;
+}
+
 static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
 	.enable			= mixer_enable,
 	.disable		= mixer_disable,
@@ -1043,6 +1072,7 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
 	.disable_plane		= mixer_disable_plane,
 	.atomic_flush		= mixer_atomic_flush,
 	.mode_valid		= mixer_mode_valid,
+	.mode_fixup		= mixer_mode_fixup,
 };
 
 static const struct mixer_drv_data exynos5420_mxr_drv_data = {
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
       [not found]   ` <CGME20170929100549eucas1p2053fdf47957c11fa39d0e026267f088c@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  2017-10-17  7:38       ` Inki Dae
  0 siblings, 1 reply; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
720x480, 720x576, 1280x720, 1920x1080. Support for other modes
can be enabled by manipulating timings of HDMI. To do it
adjusted_mode should contain actual mode set on crtc.
With this patch it is possible to enable 1024x768 and 1280x1024
modes in MIXER.

Suggested-by: Daniel Drake <drake@endlessm.com>
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 7225b6521148..4b081f6cfdcb 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
 static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
 {
 	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
+	struct drm_display_mode *am = &hdata->encoder.crtc->state->adjusted_mode;
+	int hquirk = 0;
+
+	/*
+	 * In case video mode coming from CRTC differs from requested one HDMI
+	 * sometimes is able to almost properly perform conversion - only
+	 * first line is distorted.
+	 */
+	if ((m->vdisplay != am->vdisplay) &&
+	    (m->hdisplay == 1280 || m->hdisplay == 1024))
+		hquirk = 258;
 
 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
 	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
@@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
 	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
 
 	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
-	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
-	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
+	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - hquirk);
+	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
 	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
 	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
 		hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes
       [not found]   ` <CGME20170929100549eucas1p29a39ec9db45d6009f23b89fd2d6b77f9@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  2017-10-17  7:48       ` Inki Dae
  0 siblings, 1 reply; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	dri-devel, linux-samsung-soc, Tobias Jakobi, Daniel Drake

Since HDMI can handle these modes despite of MIXER limitations let's
enable them.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 8baa93f80106..85d33137cfd8 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1014,6 +1014,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
 	    (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
 		return MODE_OK;
 
+	if ((w == 1024 && h == 768) || (w == 1280 && h == 1024))
+		return MODE_OK;
+
 	return MODE_BAD;
 }
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 11/11] drm/exynos/hdmi: add 85.5MHz pixel clock for v14 HDMI PHY
       [not found]   ` <CGME20170929100550eucas1p28b5fbc7fd3fedeafc0632a6401158dbf@eucas1p2.samsung.com>
@ 2017-09-29 10:05     ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-09-29 10:05 UTC (permalink / raw)
  To: Inki Dae
  Cc: Daniel Drake, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
	Andrzej Hajda, dri-devel, linux-samsung-soc, Tobias Jakobi

From: Daniel Drake <drake@endlessm.com>

Configuration details from Samsung. This enables 1366x768@60Hz,
which also needs the 256px timing hack to work around a mixer
limitation.

Signed-off-by: Daniel Drake <drake@endlessm.com>
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
[a.hajda@samsung.com: rebased onto proposed patchset]
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_hdmi.c  | 11 ++++++++++-
 drivers/gpu/drm/exynos/exynos_mixer.c |  4 +++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 4b081f6cfdcb..ee45accb81c7 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -296,6 +296,15 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = {
 			0x54, 0x93, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
 		},
 	},
+	{
+		.pixel_clock = 85500000,
+		.conf = {
+			0x01, 0xd1, 0x24, 0x11, 0x40, 0x40, 0xd0, 0x08,
+			0x84, 0xa0, 0xd6, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+			0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+			0x54, 0x90, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
+		},
+	},
 	{
 		.pixel_clock = 106500000,
 		.conf = {
@@ -1248,7 +1257,7 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
 	 * first line is distorted.
 	 */
 	if ((m->vdisplay != am->vdisplay) &&
-	    (m->hdisplay == 1280 || m->hdisplay == 1024))
+	    (m->hdisplay == 1280 || m->hdisplay == 1024 || m->hdisplay == 1366))
 		hquirk = 258;
 
 	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 85d33137cfd8..59ab31eec1bb 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1014,7 +1014,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
 	    (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
 		return MODE_OK;
 
-	if ((w == 1024 && h == 768) || (w == 1280 && h == 1024))
+	if ((w == 1024 && h == 768) ||
+	    (w == 1366 && h == 768) ||
+	    (w == 1280 && h == 1024))
 		return MODE_OK;
 
 	return MODE_BAD;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 05/11] drm/exynos/mixer: remove mixer_resources sub-structure
  2017-09-29 10:05     ` [PATCH v2 05/11] drm/exynos/mixer: remove mixer_resources sub-structure Andrzej Hajda
@ 2017-10-16 10:02       ` Inki Dae
  0 siblings, 0 replies; 20+ messages in thread
From: Inki Dae @ 2017-10-16 10:02 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Bartlomiej Zolnierkiewicz, Marek Szyprowski, dri-devel,
	linux-samsung-soc, Tobias Jakobi, Daniel Drake



2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
> mixer_resources adds only unnecessary redirection, removing it makes the
> code shorter and cleaner.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 323 ++++++++++++++++------------------
>  1 file changed, 147 insertions(+), 176 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index fba120346189..2d8905ea0141 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -67,19 +67,6 @@
>  #define MXR_FORMAT_ARGB4444	6
>  #define MXR_FORMAT_ARGB8888	7
>  
> -struct mixer_resources {
> -	int			irq;
> -	void __iomem		*mixer_regs;
> -	void __iomem		*vp_regs;
> -	spinlock_t		reg_slock;
> -	struct clk		*mixer;
> -	struct clk		*vp;
> -	struct clk		*hdmi;
> -	struct clk		*sclk_mixer;
> -	struct clk		*sclk_hdmi;
> -	struct clk		*mout_mixer;
> -};
> -
>  enum mixer_version_id {
>  	MXR_VER_0_0_0_16,
>  	MXR_VER_16_0_33_0,
> @@ -117,7 +104,16 @@ struct mixer_context {
>  	struct exynos_drm_plane	planes[MIXER_WIN_NR];
>  	unsigned long		flags;
>  
> -	struct mixer_resources	mixer_res;
> +	int			irq;
> +	void __iomem		*mixer_regs;
> +	void __iomem		*vp_regs;
> +	spinlock_t		reg_slock;
> +	struct clk		*mixer;
> +	struct clk		*vp;
> +	struct clk		*hdmi;
> +	struct clk		*sclk_mixer;
> +	struct clk		*sclk_hdmi;
> +	struct clk		*mout_mixer;
>  	enum mixer_version_id	mxr_ver;
>  };
>  
> @@ -194,44 +190,44 @@ static inline bool is_alpha_format(unsigned int pixel_format)
>  	}
>  }
>  
> -static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
> +static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id)
>  {
> -	return readl(res->vp_regs + reg_id);
> +	return readl(ctx->vp_regs + reg_id);
>  }
>  
> -static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
> +static inline void vp_reg_write(struct mixer_context *ctx, u32 reg_id,
>  				 u32 val)
>  {
> -	writel(val, res->vp_regs + reg_id);
> +	writel(val, ctx->vp_regs + reg_id);
>  }
>  
> -static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
> +static inline void vp_reg_writemask(struct mixer_context *ctx, u32 reg_id,
>  				 u32 val, u32 mask)
>  {
> -	u32 old = vp_reg_read(res, reg_id);
> +	u32 old = vp_reg_read(ctx, reg_id);
>  
>  	val = (val & mask) | (old & ~mask);
> -	writel(val, res->vp_regs + reg_id);
> +	writel(val, ctx->vp_regs + reg_id);
>  }
>  
> -static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
> +static inline u32 mixer_reg_read(struct mixer_context *ctx, u32 reg_id)
>  {
> -	return readl(res->mixer_regs + reg_id);
> +	return readl(ctx->mixer_regs + reg_id);
>  }
>  
> -static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
> +static inline void mixer_reg_write(struct mixer_context *ctx, u32 reg_id,
>  				 u32 val)
>  {
> -	writel(val, res->mixer_regs + reg_id);
> +	writel(val, ctx->mixer_regs + reg_id);
>  }
>  
> -static inline void mixer_reg_writemask(struct mixer_resources *res,
> +static inline void mixer_reg_writemask(struct mixer_context *ctx,
>  				 u32 reg_id, u32 val, u32 mask)
>  {
> -	u32 old = mixer_reg_read(res, reg_id);
> +	u32 old = mixer_reg_read(ctx, reg_id);
>  
>  	val = (val & mask) | (old & ~mask);
> -	writel(val, res->mixer_regs + reg_id);
> +	writel(val, ctx->mixer_regs + reg_id);
>  }
>  
>  static void mixer_regs_dump(struct mixer_context *ctx)
> @@ -239,7 +235,7 @@ static void mixer_regs_dump(struct mixer_context *ctx)
>  #define DUMPREG(reg_id) \
>  do { \
>  	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
> -		(u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
> +		(u32)readl(ctx->mixer_regs + reg_id)); \
>  } while (0)
>  
>  	DUMPREG(MXR_STATUS);
> @@ -271,7 +267,7 @@ static void vp_regs_dump(struct mixer_context *ctx)
>  #define DUMPREG(reg_id) \
>  do { \
>  	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
> -		(u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
> +		(u32) readl(ctx->vp_regs + reg_id)); \
>  } while (0)
>  
>  	DUMPREG(VP_ENABLE);
> @@ -301,7 +297,7 @@ do { \
>  #undef DUMPREG
>  }
>  
> -static inline void vp_filter_set(struct mixer_resources *res,
> +static inline void vp_filter_set(struct mixer_context *ctx,
>  		int reg_id, const u8 *data, unsigned int size)
>  {
>  	/* assure 4-byte align */
> @@ -309,24 +305,23 @@ static inline void vp_filter_set(struct mixer_resources *res,
>  	for (; size; size -= 4, reg_id += 4, data += 4) {
>  		u32 val = (data[0] << 24) |  (data[1] << 16) |
>  			(data[2] << 8) | data[3];
> -		vp_reg_write(res, reg_id, val);
> +		vp_reg_write(ctx, reg_id, val);
>  	}
>  }
>  
> -static void vp_default_filter(struct mixer_resources *res)
> +static void vp_default_filter(struct mixer_context *ctx)
>  {
> -	vp_filter_set(res, VP_POLY8_Y0_LL,
> +	vp_filter_set(ctx, VP_POLY8_Y0_LL,
>  		filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
> -	vp_filter_set(res, VP_POLY4_Y0_LL,
> +	vp_filter_set(ctx, VP_POLY4_Y0_LL,
>  		filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
> -	vp_filter_set(res, VP_POLY4_C0_LL,
> +	vp_filter_set(ctx, VP_POLY4_C0_LL,
>  		filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
>  }
>  
>  static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
>  				bool alpha)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	u32 val;
>  
>  	val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
> @@ -335,13 +330,12 @@ static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
>  		val |= MXR_GRP_CFG_BLEND_PRE_MUL;
>  		val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
>  	}
> -	mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
> +	mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
>  			    val, MXR_GRP_CFG_MISC_MASK);
>  }
>  
>  static void mixer_cfg_vp_blend(struct mixer_context *ctx)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	u32 val;
>  
>  	/*
> @@ -351,25 +345,22 @@ static void mixer_cfg_vp_blend(struct mixer_context *ctx)
>  	 * support blending of the video layer through this.
>  	 */
>  	val = 0;
> -	mixer_reg_write(res, MXR_VIDEO_CFG, val);
> +	mixer_reg_write(ctx, MXR_VIDEO_CFG, val);
>  }
>  
>  static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
> -
>  	/* block update on vsync */
> -	mixer_reg_writemask(res, MXR_STATUS, enable ?
> +	mixer_reg_writemask(ctx, MXR_STATUS, enable ?
>  			MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
>  
>  	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
> -		vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
> +		vp_reg_write(ctx, VP_SHADOW_UPDATE, enable ?
>  			VP_SHADOW_UPDATE_ENABLE : 0);
>  }
>  
>  static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	u32 val;
>  
>  	/* choosing between interlace and progressive mode */
> @@ -378,7 +369,7 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
>  
>  	/* setup display size */
>  	if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
> -		mixer_reg_write(&ctx->mixer_res, MXR_RESOLUTION,
> +		mixer_reg_write(ctx, MXR_RESOLUTION,
>  			MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width));
>  	} else {
>  		/* choosing between proper HD and SD mode */
> @@ -394,12 +385,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
>  			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
>  	}
>  
> -	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
> +	mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK);
>  }
>  
>  static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	u32 val;
>  
>  	switch (height) {
> @@ -412,45 +402,44 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
>  	default:
>  		val = MXR_CFG_RGB709_16_235;
>  		/* Configure the BT.709 CSC matrix for full range RGB. */
> -		mixer_reg_write(res, MXR_CM_COEFF_Y,
> +		mixer_reg_write(ctx, MXR_CM_COEFF_Y,
>  			MXR_CSC_CT( 0.184,  0.614,  0.063) |
>  			MXR_CM_COEFF_RGB_FULL);
> -		mixer_reg_write(res, MXR_CM_COEFF_CB,
> +		mixer_reg_write(ctx, MXR_CM_COEFF_CB,
>  			MXR_CSC_CT(-0.102, -0.338,  0.440));
> -		mixer_reg_write(res, MXR_CM_COEFF_CR,
> +		mixer_reg_write(ctx, MXR_CM_COEFF_CR,
>  			MXR_CSC_CT( 0.440, -0.399, -0.040));
>  		break;
>  	}
>  
> -	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
> +	mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
>  }
>  
>  static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
>  			    unsigned int priority, bool enable)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	u32 val = enable ? ~0 : 0;
>  
>  	switch (win) {
>  	case 0:
> -		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
> -		mixer_reg_writemask(res, MXR_LAYER_CFG,
> +		mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
> +		mixer_reg_writemask(ctx, MXR_LAYER_CFG,
>  				    MXR_LAYER_CFG_GRP0_VAL(priority),
>  				    MXR_LAYER_CFG_GRP0_MASK);
>  		break;
>  	case 1:
> -		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
> -		mixer_reg_writemask(res, MXR_LAYER_CFG,
> +		mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
> +		mixer_reg_writemask(ctx, MXR_LAYER_CFG,
>  				    MXR_LAYER_CFG_GRP1_VAL(priority),
>  				    MXR_LAYER_CFG_GRP1_MASK);
>  
>  		break;
>  	case VP_DEFAULT_WIN:
>  		if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
> -			vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
> -			mixer_reg_writemask(res, MXR_CFG, val,
> +			vp_reg_writemask(ctx, VP_ENABLE, val, VP_ENABLE_ON);
> +			mixer_reg_writemask(ctx, MXR_CFG, val,
>  				MXR_CFG_VP_ENABLE);
> -			mixer_reg_writemask(res, MXR_LAYER_CFG,
> +			mixer_reg_writemask(ctx, MXR_LAYER_CFG,
>  					    MXR_LAYER_CFG_VP_VAL(priority),
>  					    MXR_LAYER_CFG_VP_MASK);
>  		}
> @@ -460,19 +449,16 @@ static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
>  
>  static void mixer_run(struct mixer_context *ctx)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
> -
> -	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
> +	mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
>  }
>  
>  static void mixer_stop(struct mixer_context *ctx)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	int timeout = 20;
>  
> -	mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
> +	mixer_reg_writemask(ctx, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
>  
> -	while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
> +	while (!(mixer_reg_read(ctx, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
>  			--timeout)
>  		usleep_range(10000, 12000);
>  }
> @@ -496,7 +482,6 @@ static void vp_video_buffer(struct mixer_context *ctx,
>  {
>  	struct exynos_drm_plane_state *state =
>  				to_exynos_plane_state(plane->base.state);
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	unsigned int priority = state->base.normalized_zpos + 1;
>  	unsigned long flags;
> @@ -523,55 +508,55 @@ static void vp_video_buffer(struct mixer_context *ctx,
>  		chroma_addr[1] = 0;
>  	}
>  
> -	spin_lock_irqsave(&res->reg_slock, flags);
> +	spin_lock_irqsave(&ctx->reg_slock, flags);
>  
>  	/* interlace or progressive scan mode */
>  	val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0);
> -	vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
> +	vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP);
>  
>  	/* setup format */
>  	val = (is_nv21 ? VP_MODE_NV21 : VP_MODE_NV12);
>  	val |= (is_tiled ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
> -	vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
> +	vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_FMT_MASK);
>  
>  	/* setting size of input image */
> -	vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
> +	vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
>  		VP_IMG_VSIZE(fb->height));
>  	/* chroma plane for NV12/NV21 is half the height of the luma plane */
> -	vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
> +	vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
>  		VP_IMG_VSIZE(fb->height / 2));
>  
> -	vp_reg_write(res, VP_SRC_WIDTH, state->src.w);
> -	vp_reg_write(res, VP_SRC_HEIGHT, state->src.h);
> -	vp_reg_write(res, VP_SRC_H_POSITION,
> +	vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w);
> +	vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h);
> +	vp_reg_write(ctx, VP_SRC_H_POSITION,
>  			VP_SRC_H_POSITION_VAL(state->src.x));
> -	vp_reg_write(res, VP_SRC_V_POSITION, state->src.y);
> +	vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y);
>  
> -	vp_reg_write(res, VP_DST_WIDTH, state->crtc.w);
> -	vp_reg_write(res, VP_DST_H_POSITION, state->crtc.x);
> +	vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w);
> +	vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x);
>  	if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
> -		vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h / 2);
> -		vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y / 2);
> +		vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2);
> +		vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2);
>  	} else {
> -		vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h);
> -		vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y);
> +		vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h);
> +		vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y);
>  	}
>  
> -	vp_reg_write(res, VP_H_RATIO, state->h_ratio);
> -	vp_reg_write(res, VP_V_RATIO, state->v_ratio);
> +	vp_reg_write(ctx, VP_H_RATIO, state->h_ratio);
> +	vp_reg_write(ctx, VP_V_RATIO, state->v_ratio);
>  
> -	vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
> +	vp_reg_write(ctx, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
>  
>  	/* set buffer address to vp */
> -	vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
> -	vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
> -	vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
> -	vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
> +	vp_reg_write(ctx, VP_TOP_Y_PTR, luma_addr[0]);
> +	vp_reg_write(ctx, VP_BOT_Y_PTR, luma_addr[1]);
> +	vp_reg_write(ctx, VP_TOP_C_PTR, chroma_addr[0]);
> +	vp_reg_write(ctx, VP_BOT_C_PTR, chroma_addr[1]);
>  
>  	mixer_cfg_layer(ctx, plane->index, priority, true);
>  	mixer_cfg_vp_blend(ctx);
>  
> -	spin_unlock_irqrestore(&res->reg_slock, flags);
> +	spin_unlock_irqrestore(&ctx->reg_slock, flags);
>  
>  	mixer_regs_dump(ctx);
>  	vp_regs_dump(ctx);
> @@ -579,9 +564,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
>  
>  static void mixer_layer_update(struct mixer_context *ctx)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
> -
> -	mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
> +	mixer_reg_writemask(ctx, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
>  }
>  
>  static void mixer_graph_buffer(struct mixer_context *ctx,
> @@ -589,7 +572,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
>  {
>  	struct exynos_drm_plane_state *state =
>  				to_exynos_plane_state(plane->base.state);
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	unsigned int priority = state->base.normalized_zpos + 1;
>  	unsigned long flags;
> @@ -634,29 +616,29 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
>  		+ (state->src.x * fb->format->cpp[0])
>  		+ (state->src.y * fb->pitches[0]);
>  
> -	spin_lock_irqsave(&res->reg_slock, flags);
> +	spin_lock_irqsave(&ctx->reg_slock, flags);
>  
>  	/* setup format */
> -	mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
> +	mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
>  		MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
>  
>  	/* setup geometry */
> -	mixer_reg_write(res, MXR_GRAPHIC_SPAN(win),
> +	mixer_reg_write(ctx, MXR_GRAPHIC_SPAN(win),
>  			fb->pitches[0] / fb->format->cpp[0]);
>  
>  	val  = MXR_GRP_WH_WIDTH(state->src.w);
>  	val |= MXR_GRP_WH_HEIGHT(state->src.h);
>  	val |= MXR_GRP_WH_H_SCALE(x_ratio);
>  	val |= MXR_GRP_WH_V_SCALE(y_ratio);
> -	mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
> +	mixer_reg_write(ctx, MXR_GRAPHIC_WH(win), val);
>  
>  	/* setup offsets in display image */
>  	val  = MXR_GRP_DXY_DX(dst_x_offset);
>  	val |= MXR_GRP_DXY_DY(dst_y_offset);
> -	mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
> +	mixer_reg_write(ctx, MXR_GRAPHIC_DXY(win), val);
>  
>  	/* set buffer address to mixer */
> -	mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
> +	mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr);
>  
>  	mixer_cfg_layer(ctx, win, priority, true);
>  	mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format));
> @@ -666,20 +648,19 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
>  		ctx->mxr_ver == MXR_VER_128_0_0_184)
>  		mixer_layer_update(ctx);
>  
> -	spin_unlock_irqrestore(&res->reg_slock, flags);
> +	spin_unlock_irqrestore(&ctx->reg_slock, flags);
>  
>  	mixer_regs_dump(ctx);
>  }
>  
>  static void vp_win_reset(struct mixer_context *ctx)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	unsigned int tries = 100;
>  
> -	vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
> +	vp_reg_write(ctx, VP_SRESET, VP_SRESET_PROCESSING);
>  	while (--tries) {
>  		/* waiting until VP_SRESET_PROCESSING is 0 */
> -		if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
> +		if (~vp_reg_read(ctx, VP_SRESET) & VP_SRESET_PROCESSING)
>  			break;
>  		mdelay(10);
>  	}
> @@ -688,57 +669,55 @@ static void vp_win_reset(struct mixer_context *ctx)
>  
>  static void mixer_win_reset(struct mixer_context *ctx)
>  {
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	unsigned long flags;
>  
> -	spin_lock_irqsave(&res->reg_slock, flags);
> +	spin_lock_irqsave(&ctx->reg_slock, flags);
>  
> -	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
> +	mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
>  
>  	/* set output in RGB888 mode */
> -	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
> +	mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
>  
>  	/* 16 beat burst in DMA */
> -	mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
> +	mixer_reg_writemask(ctx, MXR_STATUS, MXR_STATUS_16_BURST,
>  		MXR_STATUS_BURST_MASK);
>  
>  	/* reset default layer priority */
> -	mixer_reg_write(res, MXR_LAYER_CFG, 0);
> +	mixer_reg_write(ctx, MXR_LAYER_CFG, 0);
>  
>  	/* set all background colors to RGB (0,0,0) */
> -	mixer_reg_write(res, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128));
> -	mixer_reg_write(res, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128));
> -	mixer_reg_write(res, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128));
> +	mixer_reg_write(ctx, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128));
> +	mixer_reg_write(ctx, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128));
> +	mixer_reg_write(ctx, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128));
>  
>  	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
>  		/* configuration of Video Processor Registers */
>  		vp_win_reset(ctx);
> -		vp_default_filter(res);
> +		vp_default_filter(ctx);
>  	}
>  
>  	/* disable all layers */
> -	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
> -	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
> +	mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
> +	mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
>  	if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
> -		mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
> +		mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
>  
>  	/* set all source image offsets to zero */
> -	mixer_reg_write(res, MXR_GRAPHIC_SXY(0), 0);
> -	mixer_reg_write(res, MXR_GRAPHIC_SXY(1), 0);
> +	mixer_reg_write(ctx, MXR_GRAPHIC_SXY(0), 0);
> +	mixer_reg_write(ctx, MXR_GRAPHIC_SXY(1), 0);
>  
> -	spin_unlock_irqrestore(&res->reg_slock, flags);
> +	spin_unlock_irqrestore(&ctx->reg_slock, flags);
>  }
>  
>  static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  {
>  	struct mixer_context *ctx = arg;
> -	struct mixer_resources *res = &ctx->mixer_res;
>  	u32 val, base, shadow;
>  
> -	spin_lock(&res->reg_slock);
> +	spin_lock(&ctx->reg_slock);
>  
>  	/* read interrupt status for handling and clearing flags for VSYNC */
> -	val = mixer_reg_read(res, MXR_INT_STATUS);
> +	val = mixer_reg_read(ctx, MXR_INT_STATUS);
>  
>  	/* handling VSYNC */
>  	if (val & MXR_INT_STATUS_VSYNC) {
> @@ -748,13 +727,13 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  
>  		/* interlace scan need to check shadow register */
>  		if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
> -			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
> -			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
> +			base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0));
> +			shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0));
>  			if (base != shadow)
>  				goto out;
>  
> -			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
> -			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
> +			base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(1));
> +			shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(1));
>  			if (base != shadow)
>  				goto out;
>  		}
> @@ -764,9 +743,9 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  
>  out:
>  	/* clear interrupts */
> -	mixer_reg_write(res, MXR_INT_STATUS, val);
> +	mixer_reg_write(ctx, MXR_INT_STATUS, val);
>  
> -	spin_unlock(&res->reg_slock);
> +	spin_unlock(&ctx->reg_slock);
>  
>  	return IRQ_HANDLED;
>  }
> @@ -774,26 +753,25 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
>  static int mixer_resources_init(struct mixer_context *mixer_ctx)
>  {
>  	struct device *dev = &mixer_ctx->pdev->dev;
> -	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
>  	struct resource *res;
>  	int ret;
>  
> -	spin_lock_init(&mixer_res->reg_slock);
> +	spin_lock_init(&mixer_ctx->reg_slock);
>  
> -	mixer_res->mixer = devm_clk_get(dev, "mixer");
> -	if (IS_ERR(mixer_res->mixer)) {
> +	mixer_ctx->mixer = devm_clk_get(dev, "mixer");
> +	if (IS_ERR(mixer_ctx->mixer)) {
>  		dev_err(dev, "failed to get clock 'mixer'\n");
>  		return -ENODEV;
>  	}
>  
> -	mixer_res->hdmi = devm_clk_get(dev, "hdmi");
> -	if (IS_ERR(mixer_res->hdmi)) {
> +	mixer_ctx->hdmi = devm_clk_get(dev, "hdmi");
> +	if (IS_ERR(mixer_ctx->hdmi)) {
>  		dev_err(dev, "failed to get clock 'hdmi'\n");
> -		return PTR_ERR(mixer_res->hdmi);
> +		return PTR_ERR(mixer_ctx->hdmi);
>  	}
>  
> -	mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
> -	if (IS_ERR(mixer_res->sclk_hdmi)) {
> +	mixer_ctx->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
> +	if (IS_ERR(mixer_ctx->sclk_hdmi)) {
>  		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
>  		return -ENODEV;
>  	}
> @@ -803,9 +781,9 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
>  		return -ENXIO;
>  	}
>  
> -	mixer_res->mixer_regs = devm_ioremap(dev, res->start,
> +	mixer_ctx->mixer_regs = devm_ioremap(dev, res->start,
>  							resource_size(res));
> -	if (mixer_res->mixer_regs == NULL) {
> +	if (mixer_ctx->mixer_regs == NULL) {
>  		dev_err(dev, "register mapping failed.\n");
>  		return -ENXIO;
>  	}
> @@ -822,7 +800,7 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
>  		dev_err(dev, "request interrupt failed.\n");
>  		return ret;
>  	}
> -	mixer_res->irq = res->start;
> +	mixer_ctx->irq = res->start;
>  
>  	return 0;
>  }
> @@ -830,30 +808,29 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
>  static int vp_resources_init(struct mixer_context *mixer_ctx)
>  {
>  	struct device *dev = &mixer_ctx->pdev->dev;
> -	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
>  	struct resource *res;
>  
> -	mixer_res->vp = devm_clk_get(dev, "vp");
> -	if (IS_ERR(mixer_res->vp)) {
> +	mixer_ctx->vp = devm_clk_get(dev, "vp");
> +	if (IS_ERR(mixer_ctx->vp)) {
>  		dev_err(dev, "failed to get clock 'vp'\n");
>  		return -ENODEV;
>  	}
>  
>  	if (test_bit(MXR_BIT_HAS_SCLK, &mixer_ctx->flags)) {
> -		mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
> -		if (IS_ERR(mixer_res->sclk_mixer)) {
> +		mixer_ctx->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
> +		if (IS_ERR(mixer_ctx->sclk_mixer)) {
>  			dev_err(dev, "failed to get clock 'sclk_mixer'\n");
>  			return -ENODEV;
>  		}
> -		mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
> -		if (IS_ERR(mixer_res->mout_mixer)) {
> +		mixer_ctx->mout_mixer = devm_clk_get(dev, "mout_mixer");
> +		if (IS_ERR(mixer_ctx->mout_mixer)) {
>  			dev_err(dev, "failed to get clock 'mout_mixer'\n");
>  			return -ENODEV;
>  		}
>  
> -		if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
> -			clk_set_parent(mixer_res->mout_mixer,
> -				       mixer_res->sclk_hdmi);
> +		if (mixer_ctx->sclk_hdmi && mixer_ctx->mout_mixer)
> +			clk_set_parent(mixer_ctx->mout_mixer,
> +				       mixer_ctx->sclk_hdmi);
>  	}
>  
>  	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
> @@ -862,9 +839,9 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
>  		return -ENXIO;
>  	}
>  
> -	mixer_res->vp_regs = devm_ioremap(dev, res->start,
> +	mixer_ctx->vp_regs = devm_ioremap(dev, res->start,
>  							resource_size(res));
> -	if (mixer_res->vp_regs == NULL) {
> +	if (mixer_ctx->vp_regs == NULL) {
>  		dev_err(dev, "register mapping failed.\n");
>  		return -ENXIO;
>  	}
> @@ -908,15 +885,14 @@ static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
>  static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
>  {
>  	struct mixer_context *mixer_ctx = crtc->ctx;
> -	struct mixer_resources *res = &mixer_ctx->mixer_res;
>  
>  	__set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
>  	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
>  		return 0;
>  
>  	/* enable vsync interrupt */
> -	mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
> -	mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
> +	mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
> +	mixer_reg_writemask(mixer_ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
>  
>  	return 0;
>  }
> @@ -924,7 +900,6 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
>  static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
>  {
>  	struct mixer_context *mixer_ctx = crtc->ctx;
> -	struct mixer_resources *res = &mixer_ctx->mixer_res;
>  
>  	__clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
>  
> @@ -932,8 +907,8 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
>  		return;
>  
>  	/* disable vsync interrupt */
> -	mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
> -	mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
> +	mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
> +	mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
>  }
>  
>  static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
> @@ -966,7 +941,6 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
>  				struct exynos_drm_plane *plane)
>  {
>  	struct mixer_context *mixer_ctx = crtc->ctx;
> -	struct mixer_resources *res = &mixer_ctx->mixer_res;
>  	unsigned long flags;
>  
>  	DRM_DEBUG_KMS("win: %d\n", plane->index);
> @@ -974,9 +948,9 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
>  	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
>  		return;
>  
> -	spin_lock_irqsave(&res->reg_slock, flags);
> +	spin_lock_irqsave(&mixer_ctx->reg_slock, flags);
>  	mixer_cfg_layer(mixer_ctx, plane->index, 0, false);
> -	spin_unlock_irqrestore(&res->reg_slock, flags);
> +	spin_unlock_irqrestore(&mixer_ctx->reg_slock, flags);
>  }
>  
>  static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
> @@ -993,7 +967,6 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
>  static void mixer_enable(struct exynos_drm_crtc *crtc)
>  {
>  	struct mixer_context *ctx = crtc->ctx;
> -	struct mixer_resources *res = &ctx->mixer_res;
>  
>  	if (test_bit(MXR_BIT_POWERED, &ctx->flags))
>  		return;
> @@ -1004,11 +977,11 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
>  
>  	mixer_vsync_set_update(ctx, false);
>  
> -	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
> +	mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
>  
>  	if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) {
> -		mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
> -		mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
> +		mixer_reg_writemask(ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);

WARNING: line over 80 characters
#851: FILE: drivers/gpu/drm/exynos/exynos_mixer.c:983:
+		mixer_reg_writemask(ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);

I will fix it.

Thanks,
Inki Dae

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
  2017-09-29 10:05     ` [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion Andrzej Hajda
@ 2017-10-17  7:38       ` Inki Dae
  2017-10-17  8:04         ` Andrzej Hajda
  0 siblings, 1 reply; 20+ messages in thread
From: Inki Dae @ 2017-10-17  7:38 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Bartlomiej Zolnierkiewicz, Marek Szyprowski, dri-devel,
	linux-samsung-soc, Tobias Jakobi, Daniel Drake



2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
> MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
> 720x480, 720x576, 1280x720, 1920x1080. Support for other modes
> can be enabled by manipulating timings of HDMI. To do it
> adjusted_mode should contain actual mode set on crtc.
> With this patch it is possible to enable 1024x768 and 1280x1024
> modes in MIXER.
> 
> Suggested-by: Daniel Drake <drake@endlessm.com>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
> ---
>  drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index 7225b6521148..4b081f6cfdcb 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
>  static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>  {
>  	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
> +	struct drm_display_mode *am = &hdata->encoder.crtc->state->adjusted_mode;
> +	int hquirk = 0;
> +
> +	/*
> +	 * In case video mode coming from CRTC differs from requested one HDMI
> +	 * sometimes is able to almost properly perform conversion - only
> +	 * first line is distorted.
> +	 */
> +	if ((m->vdisplay != am->vdisplay) &&
> +	    (m->hdisplay == 1280 || m->hdisplay == 1024))
> +		hquirk = 258;

Andrzej,

The distorted value couldn't be described logically? Just I wonder why the difference happens.

Thanks,
Inki Dae

>  
>  	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
>  	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
> @@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>  	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
>  
>  	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - hquirk);
> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
>  	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
>  	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
>  		hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes
  2017-09-29 10:05     ` [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes Andrzej Hajda
@ 2017-10-17  7:48       ` Inki Dae
  2017-10-17  8:09         ` Andrzej Hajda
  0 siblings, 1 reply; 20+ messages in thread
From: Inki Dae @ 2017-10-17  7:48 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Bartlomiej Zolnierkiewicz, Marek Szyprowski, dri-devel,
	linux-samsung-soc, Tobias Jakobi, Daniel Drake



2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
> Since HDMI can handle these modes despite of MIXER limitations let's
> enable them.
> 
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index 8baa93f80106..85d33137cfd8 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -1014,6 +1014,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
>  	    (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
>  		return MODE_OK;
>  
> +	if ((w == 1024 && h == 768) || (w == 1280 && h == 1024))
> +		return MODE_OK;

mixer_mode_valid function is common to all Exynos SoC managed by Exynos DRM driver.
So is it valid for all of them?

Thanks,
Inki Dae



> +
>  	return MODE_BAD;
>  }
>  
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
  2017-10-17  7:38       ` Inki Dae
@ 2017-10-17  8:04         ` Andrzej Hajda
  2017-10-18  2:31           ` Inki Dae
  0 siblings, 1 reply; 20+ messages in thread
From: Andrzej Hajda @ 2017-10-17  8:04 UTC (permalink / raw)
  To: Inki Dae
  Cc: linux-samsung-soc, Bartlomiej Zolnierkiewicz, dri-devel,
	Daniel Drake, Tobias Jakobi, Marek Szyprowski

On 17.10.2017 09:38, Inki Dae wrote:
>
> 2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
>> MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
>> 720x480, 720x576, 1280x720, 1920x1080. Support for other modes
>> can be enabled by manipulating timings of HDMI. To do it
>> adjusted_mode should contain actual mode set on crtc.
>> With this patch it is possible to enable 1024x768 and 1280x1024
>> modes in MIXER.
>>
>> Suggested-by: Daniel Drake <drake@endlessm.com>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
>> ---
>>  drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +++++++++++++--
>>  1 file changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> index 7225b6521148..4b081f6cfdcb 100644
>> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>> @@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
>>  static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>>  {
>>  	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
>> +	struct drm_display_mode *am = &hdata->encoder.crtc->state->adjusted_mode;
>> +	int hquirk = 0;
>> +
>> +	/*
>> +	 * In case video mode coming from CRTC differs from requested one HDMI
>> +	 * sometimes is able to almost properly perform conversion - only
>> +	 * first line is distorted.
>> +	 */
>> +	if ((m->vdisplay != am->vdisplay) &&
>> +	    (m->hdisplay == 1280 || m->hdisplay == 1024))
>> +		hquirk = 258;
> Andrzej,
>
> The distorted value couldn't be described logically? Just I wonder why the difference happens.

Without low level documentation of the IP one could only guess what
happens there.
In case of 1024x768 one can reason as follows:
- mixer sends image in format 1280x720, so it sends 1280 - 1024 = 256
pixels too much, so if we trim it in HDMI by 256 it should display it
correctly,
- but another quirk few lines later suppress 2 pixels from
hsync_(start,end), so to balance it we should add these pixels here, so
finally we have 256 + 2 = 258.

This explanation seems quite reasonable, except it does not work for
1280x1024 mode.

Regards
Andrzej

>
> Thanks,
> Inki Dae
>
>>  
>>  	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
>>  	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
>> @@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>>  	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
>>  
>>  	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
>> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
>> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
>> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - hquirk);
>> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
>>  	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
>>  	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
>>  		hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
>>
>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes
  2017-10-17  7:48       ` Inki Dae
@ 2017-10-17  8:09         ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-10-17  8:09 UTC (permalink / raw)
  To: Inki Dae
  Cc: linux-samsung-soc, Bartlomiej Zolnierkiewicz, dri-devel,
	Daniel Drake, Tobias Jakobi, Marek Szyprowski

On 17.10.2017 09:48, Inki Dae wrote:
>
> 2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
>> Since HDMI can handle these modes despite of MIXER limitations let's
>> enable them.
>>
>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
>> ---
>>  drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
>> index 8baa93f80106..85d33137cfd8 100644
>> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
>> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
>> @@ -1014,6 +1014,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
>>  	    (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
>>  		return MODE_OK;
>>  
>> +	if ((w == 1024 && h == 768) || (w == 1280 && h == 1024))
>> +		return MODE_OK;
> mixer_mode_valid function is common to all Exynos SoC managed by Exynos DRM driver.
> So is it valid for all of them?

It is valid for all SoCs having mixer, it was tested on Odroid
U3(Exynos4412) and XU3 (Exynos5422).

Regards
Andrzej

>
> Thanks,
> Inki Dae
>
>
>
>> +
>>  	return MODE_BAD;
>>  }
>>  
>>
>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
  2017-10-17  8:04         ` Andrzej Hajda
@ 2017-10-18  2:31           ` Inki Dae
  2017-10-18  9:36             ` Andrzej Hajda
  0 siblings, 1 reply; 20+ messages in thread
From: Inki Dae @ 2017-10-18  2:31 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: linux-samsung-soc, Bartlomiej Zolnierkiewicz, dri-devel,
	Daniel Drake, Tobias Jakobi, Marek Szyprowski



2017년 10월 17일 17:04에 Andrzej Hajda 이(가) 쓴 글:
> On 17.10.2017 09:38, Inki Dae wrote:
>>
>> 2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
>>> MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
>>> 720x480, 720x576, 1280x720, 1920x1080. Support for other modes
>>> can be enabled by manipulating timings of HDMI. To do it
>>> adjusted_mode should contain actual mode set on crtc.
>>> With this patch it is possible to enable 1024x768 and 1280x1024
>>> modes in MIXER.
>>>
>>> Suggested-by: Daniel Drake <drake@endlessm.com>
>>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>>> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
>>> ---
>>>  drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +++++++++++++--
>>>  1 file changed, 13 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
>>> index 7225b6521148..4b081f6cfdcb 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>>> @@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
>>>  static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>>>  {
>>>  	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
>>> +	struct drm_display_mode *am = &hdata->encoder.crtc->state->adjusted_mode;
>>> +	int hquirk = 0;
>>> +
>>> +	/*
>>> +	 * In case video mode coming from CRTC differs from requested one HDMI
>>> +	 * sometimes is able to almost properly perform conversion - only
>>> +	 * first line is distorted.
>>> +	 */
>>> +	if ((m->vdisplay != am->vdisplay) &&
>>> +	    (m->hdisplay == 1280 || m->hdisplay == 1024))
>>> +		hquirk = 258;
>> Andrzej,
>>
>> The distorted value couldn't be described logically? Just I wonder why the difference happens.
> 
> Without low level documentation of the IP one could only guess what
> happens there.
> In case of 1024x768 one can reason as follows:
> - mixer sends image in format 1280x720, so it sends 1280 - 1024 = 256
> pixels too much, so if we trim it in HDMI by 256 it should display it
> correctly,
> - but another quirk few lines later suppress 2 pixels from
> hsync_(start,end), so to balance it we should add these pixels here, so
> finally we have 256 + 2 = 258.
> 
> This explanation seems quite reasonable, except it does not work for
> 1280x1024 mode.

We aren't sure 100% but above comment would be helpful to other developers. So could you leave the comment?

Thanks,
Inki Dae

> 
> Regards
> Andrzej
> 
>>
>> Thanks,
>> Inki Dae
>>
>>>  
>>>  	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
>>>  	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
>>> @@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>>>  	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
>>>  
>>>  	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
>>> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
>>> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
>>> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - hquirk);
>>> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
>>>  	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
>>>  	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
>>>  		hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
>>>
>>
> 
> 
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion
  2017-10-18  2:31           ` Inki Dae
@ 2017-10-18  9:36             ` Andrzej Hajda
  0 siblings, 0 replies; 20+ messages in thread
From: Andrzej Hajda @ 2017-10-18  9:36 UTC (permalink / raw)
  To: Inki Dae
  Cc: linux-samsung-soc, Bartlomiej Zolnierkiewicz, dri-devel,
	Daniel Drake, Tobias Jakobi, Marek Szyprowski

On 18.10.2017 04:31, Inki Dae wrote:
>
> 2017년 10월 17일 17:04에 Andrzej Hajda 이(가) 쓴 글:
>> On 17.10.2017 09:38, Inki Dae wrote:
>>> 2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
>>>> MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
>>>> 720x480, 720x576, 1280x720, 1920x1080. Support for other modes
>>>> can be enabled by manipulating timings of HDMI. To do it
>>>> adjusted_mode should contain actual mode set on crtc.
>>>> With this patch it is possible to enable 1024x768 and 1280x1024
>>>> modes in MIXER.
>>>>
>>>> Suggested-by: Daniel Drake <drake@endlessm.com>
>>>> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
>>>> Reviewed-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
>>>> ---
>>>>  drivers/gpu/drm/exynos/exynos_hdmi.c | 15 +++++++++++++--
>>>>  1 file changed, 13 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
>>>> index 7225b6521148..4b081f6cfdcb 100644
>>>> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
>>>> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
>>>> @@ -1239,6 +1239,17 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
>>>>  static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>>>>  {
>>>>  	struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
>>>> +	struct drm_display_mode *am = &hdata->encoder.crtc->state->adjusted_mode;
>>>> +	int hquirk = 0;
>>>> +
>>>> +	/*
>>>> +	 * In case video mode coming from CRTC differs from requested one HDMI
>>>> +	 * sometimes is able to almost properly perform conversion - only
>>>> +	 * first line is distorted.
>>>> +	 */
>>>> +	if ((m->vdisplay != am->vdisplay) &&
>>>> +	    (m->hdisplay == 1280 || m->hdisplay == 1024))
>>>> +		hquirk = 258;
>>> Andrzej,
>>>
>>> The distorted value couldn't be described logically? Just I wonder why the difference happens.
>> Without low level documentation of the IP one could only guess what
>> happens there.
>> In case of 1024x768 one can reason as follows:
>> - mixer sends image in format 1280x720, so it sends 1280 - 1024 = 256
>> pixels too much, so if we trim it in HDMI by 256 it should display it
>> correctly,
>> - but another quirk few lines later suppress 2 pixels from
>> hsync_(start,end), so to balance it we should add these pixels here, so
>> finally we have 256 + 2 = 258.
>>
>> This explanation seems quite reasonable, except it does not work for
>> 1280x1024 mode.
> We aren't sure 100% but above comment would be helpful to other developers. So could you leave the comment?

I have made a mistake, in case of requested 1024x768 mode mixer sends
image in 1920x1080 format.
So the whole reasoning does not make sense.

Regards
Andrzej

>
> Thanks,
> Inki Dae
>
>> Regards
>> Andrzej
>>
>>> Thanks,
>>> Inki Dae
>>>
>>>>  
>>>>  	hdmi_reg_writev(hdata, HDMI_H_BLANK_0, 2, m->htotal - m->hdisplay);
>>>>  	hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
>>>> @@ -1332,8 +1343,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
>>>>  	hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
>>>>  
>>>>  	hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
>>>> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
>>>> -	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
>>>> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay - hquirk);
>>>> +	hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay + hquirk);
>>>>  	hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
>>>>  	if (hdata->drv_data == &exynos5433_hdmi_driver_data)
>>>>  		hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
>>>>
>>
>>
>

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 00/11] drm/exynos: TV path improvements
  2017-09-29 10:05 ` [PATCH v2 00/11] drm/exynos: TV path improvements Andrzej Hajda
                     ` (10 preceding siblings ...)
       [not found]   ` <CGME20170929100550eucas1p28b5fbc7fd3fedeafc0632a6401158dbf@eucas1p2.samsung.com>
@ 2017-10-23  1:37   ` Inki Dae
  11 siblings, 0 replies; 20+ messages in thread
From: Inki Dae @ 2017-10-23  1:37 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Bartlomiej Zolnierkiewicz, Marek Szyprowski, dri-devel,
	linux-samsung-soc, Tobias Jakobi, Daniel Drake

Hi Andrzej,

Merged. And regarding below patch 9, I will try to contact HW guy to ask for why the difference happens.
[PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion

Thanks,
Inki Dae

2017년 09월 29일 19:05에 Andrzej Hajda 이(가) 쓴 글:
> Hi all,
> 
> This patchset does two main things:
> - removes mode limitation for Exynos542x chips, multiple modes were filtered
>   out due to lack of HW version checking code,
> - enables two modes on older chips, thanks to quirk found by Daniel Drake,
>   and published by Tobias Jakobi [1][2].
> Beside this it consolidates the code and performs multiple cleanups.
> 
> v2:
> - addressed comments by Tobias,
> - added Daniel's patch adding 1366x768Hz mode
> 
> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg24617.html
> [2]: https://www.spinics.net/lists/dri-devel/msg150906.html
> 
> Regards
> Andrzej
> 
> 
> Andrzej Hajda (10):
>   drm/exynos/mixer: abstract out output mode setup code
>   drm/exynos/mixer: move mode commit to enable callback
>   drm/exynos/mixer: move resolution configuration to single function
>   drm/exynos/mixer: fix mode validation code
>   drm/exynos/mixer: remove mixer_resources sub-structure
>   drm/exynos/hdmi: remove redundant mode field
>   drm/exynos: add mode_fixup callback to exynos_drm_crtc_ops
>   drm/exynos/mixer: pass actual mode on MIXER to encoder
>   drm/exynos/hdmi: quirk for support mode timings conversion
>   drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes
> 
> Daniel Drake (1):
>   drm/exynos/hdmi: add 85.5MHz pixel clock for v14 HDMI PHY
> 
>  drivers/gpu/drm/exynos/exynos_drm_crtc.c |  15 +
>  drivers/gpu/drm/exynos/exynos_drm_drv.h  |   3 +
>  drivers/gpu/drm/exynos/exynos_hdmi.c     |  58 ++--
>  drivers/gpu/drm/exynos/exynos_mixer.c    | 458 +++++++++++++++----------------
>  4 files changed, 278 insertions(+), 256 deletions(-)
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-10-23  1:37 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20170929100545eucas1p24e82643e9ba934c6a0a1f437f4c0891a@eucas1p2.samsung.com>
2017-09-29 10:05 ` [PATCH v2 00/11] drm/exynos: TV path improvements Andrzej Hajda
     [not found]   ` <CGME20170929100546eucas1p2c06bf97d6961259c617b1e6d3a63f081@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 01/11] drm/exynos/mixer: abstract out output mode setup code Andrzej Hajda
     [not found]   ` <CGME20170929100546eucas1p20f2a84d13ea64f5c3329e4e641730643@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 02/11] drm/exynos/mixer: move mode commit to enable callback Andrzej Hajda
     [not found]   ` <CGME20170929100546eucas1p2b1f4313dc1f769609b10b310c2185786@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 03/11] drm/exynos/mixer: move resolution configuration to single function Andrzej Hajda
     [not found]   ` <CGME20170929100547eucas1p2642f5da0380df27d991cf3b2b1e730b3@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 04/11] drm/exynos/mixer: fix mode validation code Andrzej Hajda
     [not found]   ` <CGME20170929100548eucas1p113a840591a4bf961272384516984957e@eucas1p1.samsung.com>
2017-09-29 10:05     ` [PATCH v2 05/11] drm/exynos/mixer: remove mixer_resources sub-structure Andrzej Hajda
2017-10-16 10:02       ` Inki Dae
     [not found]   ` <CGME20170929100548eucas1p2cf6293ef0d013016afcafb4d6194e8be@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 06/11] drm/exynos/hdmi: remove redundant mode field Andrzej Hajda
     [not found]   ` <CGME20170929100548eucas1p26c83f7cf1e82d4cd052e19d4d06cdbfa@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 07/11] drm/exynos: add mode_fixup callback to exynos_drm_crtc_ops Andrzej Hajda
     [not found]   ` <CGME20170929100549eucas1p2eddc8a5e6908a69c9c91be488906852f@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 08/11] drm/exynos/mixer: pass actual mode on MIXER to encoder Andrzej Hajda
     [not found]   ` <CGME20170929100549eucas1p2053fdf47957c11fa39d0e026267f088c@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 09/11] drm/exynos/hdmi: quirk for support mode timings conversion Andrzej Hajda
2017-10-17  7:38       ` Inki Dae
2017-10-17  8:04         ` Andrzej Hajda
2017-10-18  2:31           ` Inki Dae
2017-10-18  9:36             ` Andrzej Hajda
     [not found]   ` <CGME20170929100549eucas1p29a39ec9db45d6009f23b89fd2d6b77f9@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 10/11] drm/exynos/mixer: enable support for 1024x768 and 1280x1024 modes Andrzej Hajda
2017-10-17  7:48       ` Inki Dae
2017-10-17  8:09         ` Andrzej Hajda
     [not found]   ` <CGME20170929100550eucas1p28b5fbc7fd3fedeafc0632a6401158dbf@eucas1p2.samsung.com>
2017-09-29 10:05     ` [PATCH v2 11/11] drm/exynos/hdmi: add 85.5MHz pixel clock for v14 HDMI PHY Andrzej Hajda
2017-10-23  1:37   ` [PATCH v2 00/11] drm/exynos: TV path improvements Inki Dae

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.