All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder
@ 2015-08-05 23:24 Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 01/11] drm/exynos: split display's .dpms() into .enable() and .disable() Gustavo Padovan
                   ` (9 more replies)
  0 siblings, 10 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Hi,

This patchset is another important step in the exynos clean up, it removes
two exynos internal structs in favor of wider use of struct drm_encoder.

Structs exynos_drm_display and exynos_drm_encoder were doing exactly what
struct drm_encoder does so remove them makes the code cleaner, easier
to understand and less error prone.

Please review,

       Gustavo

---
v2:  - check ret value of hdmi_create_connector()
     - set dp->dpms_mode after enable/disable	

Gustavo Padovan (11):
  drm/exynos: split display's .dpms() into .enable() and .disable()
  drm/exynos: remove wrappers for phy_power_{on,off}
  drm/exynos: remove unused .remove() and .check_mode() ops from display
  drm/exynos: simplify calculation of possible CRTCs
  drm/exynos: remove struct exynos_drm_display
  drm/exynos: remove extra call to hdmi_commit()
  drm/exynos: remove extra call to exynos_dp_commit()
  drm/exynos: remove exynos_encoder's .commit() op
  drm/exynos: remove exynos_drm_create_enc_conn()
  drm/exynos: fold encoder setup into exynos_drm_load()
  drm/exynos: remove struct exynos_drm_encoder layer

 drivers/gpu/drm/exynos/Makefile             |   7 +-
 drivers/gpu/drm/exynos/exynos7_drm_decon.c  |  16 +--
 drivers/gpu/drm/exynos/exynos_dp_core.c     | 119 ++++++++++---------
 drivers/gpu/drm/exynos/exynos_dp_core.h     |   3 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c    |  36 ------
 drivers/gpu/drm/exynos/exynos_drm_crtc.c    |   3 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.h    |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     |  96 ++++++++-------
 drivers/gpu/drm/exynos/exynos_drm_drv.c     |  13 ++-
 drivers/gpu/drm/exynos/exynos_drm_drv.h     |  65 ++---------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     | 130 ++++++++++-----------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 174 ----------------------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.h |  23 ----
 drivers/gpu/drm/exynos/exynos_drm_fimd.c    |  17 ++-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c    |  90 ++++++++------
 drivers/gpu/drm/exynos/exynos_hdmi.c        | 160 ++++++++++++-------------
 16 files changed, 355 insertions(+), 599 deletions(-)
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.h

-- 
2.1.0

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

* [PATCH v2 01/11] drm/exynos: split display's .dpms() into .enable() and .disable()
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-11  0:37   ` [PATCH " Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 02/11] drm/exynos: remove wrappers for phy_power_{on,off} Gustavo Padovan
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

The DRM Core doesn't have a dpms() operation anymore, everything
now is enable() or disable().

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
v2: set dp->dpms_mode after enable/disable
---
 drivers/gpu/drm/exynos/exynos_dp_core.c     | 34 ++++-----------
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     | 36 ++++------------
 drivers/gpu/drm/exynos/exynos_drm_drv.h     |  6 ++-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     | 44 ++++++-------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c |  8 ++--
 drivers/gpu/drm/exynos/exynos_hdmi.c        | 65 ++++++++++-------------------
 6 files changed, 62 insertions(+), 131 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..b3bf210 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1066,8 +1066,9 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 		phy_power_off(dp->phy);
 }
 
-static void exynos_dp_poweron(struct exynos_dp_device *dp)
+static void exynos_dp_enable(struct exynos_drm_display *display)
 {
+	struct exynos_dp_device *dp = display_to_dp(display);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode == DRM_MODE_DPMS_ON)
@@ -1090,8 +1091,9 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp)
 	exynos_dp_commit(&dp->display);
 }
 
-static void exynos_dp_poweroff(struct exynos_dp_device *dp)
+static void exynos_dp_disable(struct exynos_drm_display *display)
 {
+	struct exynos_dp_device *dp = display_to_dp(display);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode != DRM_MODE_DPMS_ON)
@@ -1118,28 +1120,10 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
 	}
 }
 
-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct exynos_dp_device *dp = display_to_dp(display);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		exynos_dp_poweron(dp);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		exynos_dp_poweroff(dp);
-		break;
-	default:
-		break;
-	}
-	dp->dpms_mode = mode;
-}
-
 static struct exynos_drm_display_ops exynos_dp_display_ops = {
 	.create_connector = exynos_dp_create_connector,
-	.dpms = exynos_dp_dpms,
+	.enable = exynos_dp_enable,
+	.disable = exynos_dp_disable,
 	.commit = exynos_dp_commit,
 };
 
@@ -1319,7 +1303,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_disable(&dp->display);
 }
 
 static const struct component_ops exynos_dp_ops = {
@@ -1377,7 +1361,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_disable(&dp->display);
 	return 0;
 }
 
@@ -1385,7 +1369,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
+	exynos_dp_enable(&dp->display);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 7cb6595..e042670 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -32,7 +32,6 @@ struct exynos_dpi {
 	struct drm_encoder *encoder;
 
 	struct videomode *vm;
-	int dpms_mode;
 };
 
 #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
@@ -133,46 +132,30 @@ static int exynos_dpi_create_connector(struct exynos_drm_display *display,
 	return 0;
 }
 
-static void exynos_dpi_poweron(struct exynos_dpi *ctx)
+static void exynos_dpi_enable(struct exynos_drm_display *display)
 {
+	struct exynos_dpi *ctx = display_to_dpi(display);
+
 	if (ctx->panel) {
 		drm_panel_prepare(ctx->panel);
 		drm_panel_enable(ctx->panel);
 	}
 }
 
-static void exynos_dpi_poweroff(struct exynos_dpi *ctx)
+static void exynos_dpi_disable(struct exynos_drm_display *display)
 {
+	struct exynos_dpi *ctx = display_to_dpi(display);
+
 	if (ctx->panel) {
 		drm_panel_disable(ctx->panel);
 		drm_panel_unprepare(ctx->panel);
 	}
 }
 
-static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct exynos_dpi *ctx = display_to_dpi(display);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		if (ctx->dpms_mode != DRM_MODE_DPMS_ON)
-				exynos_dpi_poweron(ctx);
-			break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		if (ctx->dpms_mode == DRM_MODE_DPMS_ON)
-			exynos_dpi_poweroff(ctx);
-		break;
-	default:
-		break;
-	}
-	ctx->dpms_mode = mode;
-}
-
 static struct exynos_drm_display_ops exynos_dpi_display_ops = {
 	.create_connector = exynos_dpi_create_connector,
-	.dpms = exynos_dpi_dpms
+	.enable = exynos_dpi_enable,
+	.disable = exynos_dpi_disable,
 };
 
 /* of_* functions will be removed after merge of of_graph patches */
@@ -311,7 +294,6 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
 	ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD;
 	ctx->display.ops = &exynos_dpi_display_ops;
 	ctx->dev = dev;
-	ctx->dpms_mode = DRM_MODE_DPMS_OFF;
 
 	ret = exynos_dpi_parse_dt(ctx);
 	if (ret < 0) {
@@ -332,7 +314,7 @@ int exynos_dpi_remove(struct exynos_drm_display *display)
 {
 	struct exynos_dpi *ctx = display_to_dpi(display);
 
-	exynos_dpi_dpms(&ctx->display, DRM_MODE_DPMS_OFF);
+	exynos_dpi_disable(&ctx->display);
 
 	if (ctx->panel)
 		drm_panel_detach(ctx->panel);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 9f23db4..5c55606 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -86,7 +86,8 @@ struct exynos_drm_plane {
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *	      would be called by encoder->mode_set().
  * @check_mode: check if mode is valid or not.
- * @dpms: display device on or off.
+ * @enable: display device on.
+ * @disable: display device off.
  * @commit: apply changes to hw
  */
 struct exynos_drm_display;
@@ -102,7 +103,8 @@ struct exynos_drm_display_ops {
 				struct drm_display_mode *mode);
 	int (*check_mode)(struct exynos_drm_display *display,
 				struct drm_display_mode *mode);
-	void (*dpms)(struct exynos_drm_display *display, int mode);
+	void (*enable)(struct exynos_drm_display *display);
+	void (*disable)(struct exynos_drm_display *display);
 	void (*commit)(struct exynos_drm_display *display);
 };
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0e58b36..281b97d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1518,16 +1518,17 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
 		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
 }
 
-static int exynos_dsi_enable(struct exynos_dsi *dsi)
+static void exynos_dsi_enable(struct exynos_drm_display *display)
 {
+	struct exynos_dsi *dsi = display_to_dsi(display);
 	int ret;
 
 	if (dsi->state & DSIM_STATE_ENABLED)
-		return 0;
+		return;
 
 	ret = exynos_dsi_poweron(dsi);
 	if (ret < 0)
-		return ret;
+		return;
 
 	dsi->state |= DSIM_STATE_ENABLED;
 
@@ -1535,7 +1536,7 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
 	if (ret < 0) {
 		dsi->state &= ~DSIM_STATE_ENABLED;
 		exynos_dsi_poweroff(dsi);
-		return ret;
+		return;
 	}
 
 	exynos_dsi_set_display_mode(dsi);
@@ -1547,16 +1548,16 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
 		exynos_dsi_set_display_enable(dsi, false);
 		drm_panel_unprepare(dsi->panel);
 		exynos_dsi_poweroff(dsi);
-		return ret;
+		return;
 	}
 
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
-
-	return 0;
 }
 
-static void exynos_dsi_disable(struct exynos_dsi *dsi)
+static void exynos_dsi_disable(struct exynos_drm_display *display)
 {
+	struct exynos_dsi *dsi = display_to_dsi(display);
+
 	if (!(dsi->state & DSIM_STATE_ENABLED))
 		return;
 
@@ -1571,26 +1572,6 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi)
 	exynos_dsi_poweroff(dsi);
 }
 
-static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct exynos_dsi *dsi = display_to_dsi(display);
-
-	if (dsi->panel) {
-		switch (mode) {
-		case DRM_MODE_DPMS_ON:
-			exynos_dsi_enable(dsi);
-			break;
-		case DRM_MODE_DPMS_STANDBY:
-		case DRM_MODE_DPMS_SUSPEND:
-		case DRM_MODE_DPMS_OFF:
-			exynos_dsi_disable(dsi);
-			break;
-		default:
-			break;
-		}
-	}
-}
-
 static enum drm_connector_status
 exynos_dsi_detect(struct drm_connector *connector, bool force)
 {
@@ -1604,7 +1585,7 @@ exynos_dsi_detect(struct drm_connector *connector, bool force)
 		struct exynos_drm_display *display;
 
 		display = platform_get_drvdata(to_platform_device(dsi->dev));
-		exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF);
+		exynos_dsi_disable(display);
 		drm_panel_detach(dsi->panel);
 		dsi->panel = NULL;
 	}
@@ -1698,7 +1679,8 @@ static void exynos_dsi_mode_set(struct exynos_drm_display *display,
 static struct exynos_drm_display_ops exynos_dsi_display_ops = {
 	.create_connector = exynos_dsi_create_connector,
 	.mode_set = exynos_dsi_mode_set,
-	.dpms = exynos_dsi_dpms
+	.enable = exynos_dsi_enable,
+	.disable = exynos_dsi_disable,
 };
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1849,7 +1831,7 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
 	struct exynos_drm_display *display = dev_get_drvdata(dev);
 	struct exynos_dsi *dsi = display_to_dsi(display);
 
-	exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF);
+	exynos_dsi_disable(display);
 
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 7b89fd5..0aa4a58 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -70,8 +70,8 @@ static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
 	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->dpms)
-		display->ops->dpms(display, DRM_MODE_DPMS_ON);
+	if (display->ops->enable)
+		display->ops->enable(display);
 
 	if (display->ops->commit)
 		display->ops->commit(display);
@@ -82,8 +82,8 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
 	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->dpms)
-		display->ops->dpms(display, DRM_MODE_DPMS_OFF);
+	if (display->ops->disable)
+		display->ops->disable(display);
 }
 
 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 448f534..9b9396a 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1723,8 +1723,9 @@ static void hdmi_commit(struct exynos_drm_display *display)
 	hdmi_conf_apply(hdata);
 }
 
-static void hdmi_poweron(struct hdmi_context *hdata)
+static void hdmi_enable(struct exynos_drm_display *display)
 {
+	struct hdmi_context *hdata = display_to_hdmi(display);
 	struct hdmi_resources *res = &hdata->res;
 
 	if (hdata->powered)
@@ -1745,16 +1746,33 @@ static void hdmi_poweron(struct hdmi_context *hdata)
 	clk_prepare_enable(res->sclk_hdmi);
 
 	hdmiphy_poweron(hdata);
-	hdmi_commit(&hdata->display);
+	hdmi_commit(display);
 }
 
-static void hdmi_poweroff(struct hdmi_context *hdata)
+static void hdmi_disable(struct exynos_drm_display *display)
 {
+	struct hdmi_context *hdata = display_to_hdmi(display);
 	struct hdmi_resources *res = &hdata->res;
+	struct drm_crtc *crtc = hdata->encoder->crtc;
+	const struct drm_crtc_helper_funcs *funcs = NULL;
 
 	if (!hdata->powered)
 		return;
 
+	/*
+	 * The SFRs of VP and Mixer are updated by Vertical Sync of
+	 * Timing generator which is a part of HDMI so the sequence
+	 * to disable TV Subsystem should be as following,
+	 *	VP -> Mixer -> HDMI
+	 *
+	 * Below codes will try to disable Mixer and VP(if used)
+	 * prior to disabling HDMI.
+	 */
+	if (crtc)
+		funcs = crtc->helper_private;
+	if (funcs && funcs->disable)
+		(*funcs->disable)(crtc);
+
 	/* HDMI System Disable */
 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
 
@@ -1776,49 +1794,12 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
 	hdata->powered = false;
 }
 
-static void hdmi_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct hdmi_context *hdata = display_to_hdmi(display);
-	struct drm_encoder *encoder = hdata->encoder;
-	struct drm_crtc *crtc = encoder->crtc;
-	const struct drm_crtc_helper_funcs *funcs = NULL;
-
-	DRM_DEBUG_KMS("mode %d\n", mode);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		hdmi_poweron(hdata);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		/*
-		 * The SFRs of VP and Mixer are updated by Vertical Sync of
-		 * Timing generator which is a part of HDMI so the sequence
-		 * to disable TV Subsystem should be as following,
-		 *	VP -> Mixer -> HDMI
-		 *
-		 * Below codes will try to disable Mixer and VP(if used)
-		 * prior to disabling HDMI.
-		 */
-		if (crtc)
-			funcs = crtc->helper_private;
-		if (funcs && funcs->disable)
-			(*funcs->disable)(crtc);
-
-		hdmi_poweroff(hdata);
-		break;
-	default:
-		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
-		break;
-	}
-}
-
 static struct exynos_drm_display_ops hdmi_display_ops = {
 	.create_connector = hdmi_create_connector,
 	.mode_fixup	= hdmi_mode_fixup,
 	.mode_set	= hdmi_mode_set,
-	.dpms		= hdmi_dpms,
+	.enable		= hdmi_enable,
+	.disable	= hdmi_disable,
 	.commit		= hdmi_commit,
 };
 
-- 
2.1.0

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

* [PATCH v2 02/11] drm/exynos: remove wrappers for phy_power_{on,off}
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 01/11] drm/exynos: split display's .dpms() into .enable() and .disable() Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 03/11] drm/exynos: remove unused .remove() and .check_mode() ops from display Gustavo Padovan
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

phy_power_on() and phy_power_off() already checks for NULL pointer.
This patch removes the wrappers exynos_dp_phy_init() and
exynos_dp_phy_exit() since the only think they were doing was a check for
NULL phy.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_dp_core.c | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index b3bf210..54f91e7 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1054,18 +1054,6 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
 	return ret;
 }
 
-static void exynos_dp_phy_init(struct exynos_dp_device *dp)
-{
-	if (dp->phy)
-		phy_power_on(dp->phy);
-}
-
-static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
-{
-	if (dp->phy)
-		phy_power_off(dp->phy);
-}
-
 static void exynos_dp_enable(struct exynos_drm_display *display)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
@@ -1085,7 +1073,7 @@ static void exynos_dp_enable(struct exynos_drm_display *display)
 		crtc->ops->clock_enable(dp_to_crtc(dp), true);
 
 	clk_prepare_enable(dp->clock);
-	exynos_dp_phy_init(dp);
+	phy_power_on(dp->phy);
 	exynos_dp_init_dp(dp);
 	enable_irq(dp->irq);
 	exynos_dp_commit(&dp->display);
@@ -1108,7 +1096,7 @@ static void exynos_dp_disable(struct exynos_drm_display *display)
 
 	disable_irq(dp->irq);
 	flush_work(&dp->hotplug_work);
-	exynos_dp_phy_exit(dp);
+	phy_power_off(dp->phy);
 	clk_disable_unprepare(dp->clock);
 
 	if (crtc->ops->clock_enable)
@@ -1281,7 +1269,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 
 	INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug);
 
-	exynos_dp_phy_init(dp);
+	phy_power_on(dp->phy);
 
 	exynos_dp_init_dp(dp);
 
-- 
2.1.0

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

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

* [PATCH v2 03/11] drm/exynos: remove unused .remove() and .check_mode() ops from display
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 01/11] drm/exynos: split display's .dpms() into .enable() and .disable() Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 02/11] drm/exynos: remove wrappers for phy_power_{on,off} Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 04/11] drm/exynos: simplify calculation of possible CRTCs Gustavo Padovan
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

These two display_ops are not used anywhere, remove them.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 5c55606..47ea400 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -81,11 +81,9 @@ struct exynos_drm_plane {
  *	- this structure is common to analog tv, digital tv and lcd panel.
  *
  * @create_connector: initialize and register a new connector
- * @remove: cleans up the display for removal
  * @mode_fixup: fix mode data comparing to hw specific display mode.
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *	      would be called by encoder->mode_set().
- * @check_mode: check if mode is valid or not.
  * @enable: display device on.
  * @disable: display device off.
  * @commit: apply changes to hw
@@ -94,15 +92,12 @@ struct exynos_drm_display;
 struct exynos_drm_display_ops {
 	int (*create_connector)(struct exynos_drm_display *display,
 				struct drm_encoder *encoder);
-	void (*remove)(struct exynos_drm_display *display);
 	void (*mode_fixup)(struct exynos_drm_display *display,
 				struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode);
 	void (*mode_set)(struct exynos_drm_display *display,
 				struct drm_display_mode *mode);
-	int (*check_mode)(struct exynos_drm_display *display,
-				struct drm_display_mode *mode);
 	void (*enable)(struct exynos_drm_display *display);
 	void (*disable)(struct exynos_drm_display *display);
 	void (*commit)(struct exynos_drm_display *display);
-- 
2.1.0

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

* [PATCH v2 04/11] drm/exynos: simplify calculation of possible CRTCs
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (2 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 03/11] drm/exynos: remove unused .remove() and .check_mode() ops from display Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 05/11] drm/exynos: remove struct exynos_drm_display Gustavo Padovan
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

All CRTCs can only be LCD, HDMI or VIDI, so basically all CRTCs will be a
possible CRTCs. This patch removes an extra function with switch that was
only checking if the CRTC type was one of those three above.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 29 +++++------------------------
 1 file changed, 5 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 0aa4a58..7ba3a2d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -105,36 +105,17 @@ static struct drm_encoder_funcs exynos_encoder_funcs = {
 	.destroy = exynos_drm_encoder_destroy,
 };
 
-static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
+void exynos_drm_encoder_setup(struct drm_device *dev)
 {
-	struct drm_encoder *clone;
-	struct drm_device *dev = encoder->dev;
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct exynos_drm_display *display = exynos_encoder->display;
+	struct drm_encoder *encoder;
 	unsigned int clone_mask = 0;
 	int cnt = 0;
 
-	list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
-		switch (display->type) {
-		case EXYNOS_DISPLAY_TYPE_LCD:
-		case EXYNOS_DISPLAY_TYPE_HDMI:
-		case EXYNOS_DISPLAY_TYPE_VIDI:
-			clone_mask |= (1 << (cnt++));
-			break;
-		default:
-			continue;
-		}
-	}
-
-	return clone_mask;
-}
-
-void exynos_drm_encoder_setup(struct drm_device *dev)
-{
-	struct drm_encoder *encoder;
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+		clone_mask |= (1 << (cnt++));
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		encoder->possible_clones = exynos_drm_encoder_clones(encoder);
+		encoder->possible_clones = clone_mask;
 }
 
 struct drm_encoder *
-- 
2.1.0

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

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

* [PATCH v2 05/11] drm/exynos: remove struct exynos_drm_display
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (3 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 04/11] drm/exynos: simplify calculation of possible CRTCs Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 06/11] drm/exynos: remove extra call to hdmi_commit() Gustavo Padovan
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

This struct was just representing encoder information, it was a member of
struct exynos_drm_encoder, so any code trying to access encoder data would
have to go through the encoder struct, get the display struct and then get
the data it want.

During this patchset we also realized that the only data
exynos_drm_encoder needs to store is the drm_encoder parent and the
exynos_drm_encoder_ops.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c  | 17 ++++---
 drivers/gpu/drm/exynos/exynos_dp_core.c     | 46 +++++++++---------
 drivers/gpu/drm/exynos/exynos_dp_core.h     |  3 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c    | 23 ++++-----
 drivers/gpu/drm/exynos/exynos_drm_crtc.c    |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_crtc.h    |  2 +-
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     | 41 ++++++++--------
 drivers/gpu/drm/exynos/exynos_drm_drv.h     | 47 ++++++++----------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     | 58 +++++++++++-----------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 75 ++++++++---------------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.h |  6 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c    | 18 +++----
 drivers/gpu/drm/exynos/exynos_drm_vidi.c    | 43 +++++------------
 drivers/gpu/drm/exynos/exynos_hdmi.c        | 48 +++++++++---------
 14 files changed, 177 insertions(+), 252 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index cfd0b5e..1b89e94 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -61,7 +61,7 @@ struct decon_context {
 	atomic_t			wait_vsync_event;
 
 	struct exynos_drm_panel_info panel;
-	struct exynos_drm_display *display;
+	struct exynos_drm_encoder *encoder;
 };
 
 static const struct of_device_id decon_driver_dt_match[] = {
@@ -681,8 +681,9 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 	}
 
-	if (ctx->display)
-		exynos_drm_create_enc_conn(drm_dev, ctx->display);
+	if (ctx->encoder)
+		exynos_drm_create_enc_conn(drm_dev, ctx->encoder,
+					   EXYNOS_DISPLAY_TYPE_LCD);
 
 	return 0;
 
@@ -695,8 +696,8 @@ static void decon_unbind(struct device *dev, struct device *master,
 
 	decon_disable(ctx->crtc);
 
-	if (ctx->display)
-		exynos_dpi_remove(ctx->display);
+	if (ctx->encoder)
+		exynos_dpi_remove(ctx->encoder);
 
 	decon_ctx_remove(ctx);
 }
@@ -781,9 +782,9 @@ static int decon_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ctx);
 
-	ctx->display = exynos_dpi_probe(dev);
-	if (IS_ERR(ctx->display)) {
-		ret = PTR_ERR(ctx->display);
+	ctx->encoder = exynos_dpi_probe(dev);
+	if (IS_ERR(ctx->encoder)) {
+		ret = PTR_ERR(ctx->encoder);
 		goto err_iounmap;
 	}
 
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 54f91e7..002a233 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -38,13 +38,13 @@
 
 static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
 {
-	return to_exynos_crtc(dp->encoder->crtc);
+	return to_exynos_crtc(dp->encoder.base.crtc);
 }
 
-static inline struct exynos_dp_device *
-display_to_dp(struct exynos_drm_display *d)
+static inline struct exynos_dp_device *encoder_to_dp(
+						struct exynos_drm_encoder *e)
 {
-	return container_of(d, struct exynos_dp_device, display);
+	return container_of(e, struct exynos_dp_device, encoder);
 }
 
 struct bridge_init {
@@ -891,9 +891,9 @@ static void exynos_dp_hotplug(struct work_struct *work)
 		drm_helper_hpd_irq_event(dp->drm_dev);
 }
 
-static void exynos_dp_commit(struct exynos_drm_display *display)
+static void exynos_dp_commit(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dp_device *dp = display_to_dp(display);
+	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	int ret;
 
 	/* Keep the panel disabled while we configure video */
@@ -994,7 +994,7 @@ static struct drm_encoder *exynos_dp_best_encoder(
 {
 	struct exynos_dp_device *dp = ctx_from_connector(connector);
 
-	return dp->encoder;
+	return &dp->encoder.base;
 }
 
 static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
@@ -1019,15 +1019,13 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 	return 0;
 }
 
-static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				struct drm_encoder *encoder)
+static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
 {
-	struct exynos_dp_device *dp = display_to_dp(display);
+	struct exynos_dp_device *dp = encoder_to_dp(exynos_encoder);
+	struct drm_encoder *encoder = &exynos_encoder->base;
 	struct drm_connector *connector = &dp->connector;
 	int ret;
 
-	dp->encoder = encoder;
-
 	/* Pre-empt DP connector creation if there's a bridge */
 	if (dp->bridge) {
 		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
@@ -1054,9 +1052,9 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
 	return ret;
 }
 
-static void exynos_dp_enable(struct exynos_drm_display *display)
+static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dp_device *dp = display_to_dp(display);
+	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode == DRM_MODE_DPMS_ON)
@@ -1076,12 +1074,12 @@ static void exynos_dp_enable(struct exynos_drm_display *display)
 	phy_power_on(dp->phy);
 	exynos_dp_init_dp(dp);
 	enable_irq(dp->irq);
-	exynos_dp_commit(&dp->display);
+	exynos_dp_commit(&dp->encoder);
 }
 
-static void exynos_dp_disable(struct exynos_drm_display *display)
+static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dp_device *dp = display_to_dp(display);
+	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode != DRM_MODE_DPMS_ON)
@@ -1108,7 +1106,7 @@ static void exynos_dp_disable(struct exynos_drm_display *display)
 	}
 }
 
-static struct exynos_drm_display_ops exynos_dp_display_ops = {
+static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
 	.create_connector = exynos_dp_create_connector,
 	.enable = exynos_dp_enable,
 	.disable = exynos_dp_disable,
@@ -1283,7 +1281,8 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 
 	dp->drm_dev = drm_dev;
 
-	return exynos_drm_create_enc_conn(drm_dev, &dp->display);
+	return exynos_drm_create_enc_conn(drm_dev, &dp->encoder,
+					  EXYNOS_DISPLAY_TYPE_LCD);
 }
 
 static void exynos_dp_unbind(struct device *dev, struct device *master,
@@ -1291,7 +1290,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_disable(&dp->display);
+	exynos_dp_disable(&dp->encoder);
 }
 
 static const struct component_ops exynos_dp_ops = {
@@ -1310,8 +1309,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (!dp)
 		return -ENOMEM;
 
-	dp->display.type = EXYNOS_DISPLAY_TYPE_LCD;
-	dp->display.ops = &exynos_dp_display_ops;
+	dp->encoder.ops = &exynos_dp_encoder_ops;
 	platform_set_drvdata(pdev, dp);
 
 	panel_node = of_parse_phandle(dev->of_node, "panel", 0);
@@ -1349,7 +1347,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_disable(&dp->display);
+	exynos_dp_disable(&dp->encoder);
 	return 0;
 }
 
@@ -1357,7 +1355,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_enable(&dp->display);
+	exynos_dp_enable(&dp->encoder);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a4e7996..f8cc202 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -147,11 +147,10 @@ struct link_train {
 };
 
 struct exynos_dp_device {
-	struct exynos_drm_display display;
+	struct exynos_drm_encoder encoder;
 	struct device		*dev;
 	struct drm_device	*drm_dev;
 	struct drm_connector	connector;
-	struct drm_encoder	*encoder;
 	struct drm_panel	*panel;
 	struct drm_bridge	*bridge;
 	struct clk		*clock;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 4c9f972..e386452 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -21,38 +21,33 @@
 static LIST_HEAD(exynos_drm_subdrv_list);
 
 int exynos_drm_create_enc_conn(struct drm_device *dev,
-					struct exynos_drm_display *display)
+			       struct exynos_drm_encoder *exynos_encoder,
+			       enum exynos_drm_output_type type)
 {
-	struct drm_encoder *encoder;
 	int ret;
 	unsigned long possible_crtcs = 0;
 
-	ret = exynos_drm_crtc_get_pipe_from_type(dev, display->type);
+	ret = exynos_drm_crtc_get_pipe_from_type(dev, type);
 	if (ret < 0)
 		return ret;
 
 	possible_crtcs |= 1 << ret;
 
 	/* create and initialize a encoder for this sub driver. */
-	encoder = exynos_drm_encoder_create(dev, display, possible_crtcs);
-	if (!encoder) {
+	ret = exynos_drm_encoder_create(dev, exynos_encoder, possible_crtcs);
+	if (ret) {
 		DRM_ERROR("failed to create encoder\n");
-		return -EFAULT;
+		return ret;
 	}
 
-	display->encoder = encoder;
-
-	ret = display->ops->create_connector(display, encoder);
+	ret = exynos_encoder->ops->create_connector(exynos_encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		goto err_destroy_encoder;
+		drm_encoder_cleanup(&exynos_encoder->base);
+		return ret;
 	}
 
 	return 0;
-
-err_destroy_encoder:
-	encoder->funcs->destroy(encoder);
-	return ret;
 }
 
 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 9bc2353..2715c2a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -235,7 +235,7 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
 }
 
 int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
-					unsigned int out_type)
+				       enum exynos_drm_output_type out_type)
 {
 	struct drm_crtc *crtc;
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index d01d49a..9e7027d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -30,7 +30,7 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
 
 /* This function gets pipe value to crtc device matched with out_type. */
 int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
-					unsigned int out_type);
+				       enum exynos_drm_output_type out_type);
 
 /*
  * This function calls the crtc device(manager)'s te_handler() callback
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index e042670..60a3161 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -23,22 +23,21 @@
 #include "exynos_drm_drv.h"
 
 struct exynos_dpi {
-	struct exynos_drm_display display;
+	struct exynos_drm_encoder encoder;
 	struct device *dev;
 	struct device_node *panel_node;
 
 	struct drm_panel *panel;
 	struct drm_connector connector;
-	struct drm_encoder *encoder;
 
 	struct videomode *vm;
 };
 
 #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
 
-static inline struct exynos_dpi *display_to_dpi(struct exynos_drm_display *d)
+static inline struct exynos_dpi *encoder_to_dpi(struct exynos_drm_encoder *e)
 {
-	return container_of(d, struct exynos_dpi, display);
+	return container_of(e, struct exynos_dpi, encoder);
 }
 
 static enum drm_connector_status
@@ -98,7 +97,7 @@ exynos_dpi_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dpi *ctx = connector_to_dpi(connector);
 
-	return ctx->encoder;
+	return &ctx->encoder.base;
 }
 
 static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
@@ -106,15 +105,14 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
 	.best_encoder = exynos_dpi_best_encoder,
 };
 
-static int exynos_dpi_create_connector(struct exynos_drm_display *display,
-				       struct drm_encoder *encoder)
+static int exynos_dpi_create_connector(
+				struct exynos_drm_encoder *exynos_encoder)
 {
-	struct exynos_dpi *ctx = display_to_dpi(display);
+	struct exynos_dpi *ctx = encoder_to_dpi(exynos_encoder);
+	struct drm_encoder *encoder = &exynos_encoder->base;
 	struct drm_connector *connector = &ctx->connector;
 	int ret;
 
-	ctx->encoder = encoder;
-
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
 	ret = drm_connector_init(encoder->dev, connector,
@@ -132,9 +130,9 @@ static int exynos_dpi_create_connector(struct exynos_drm_display *display,
 	return 0;
 }
 
-static void exynos_dpi_enable(struct exynos_drm_display *display)
+static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dpi *ctx = display_to_dpi(display);
+	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
 	if (ctx->panel) {
 		drm_panel_prepare(ctx->panel);
@@ -142,9 +140,9 @@ static void exynos_dpi_enable(struct exynos_drm_display *display)
 	}
 }
 
-static void exynos_dpi_disable(struct exynos_drm_display *display)
+static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dpi *ctx = display_to_dpi(display);
+	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
 	if (ctx->panel) {
 		drm_panel_disable(ctx->panel);
@@ -152,7 +150,7 @@ static void exynos_dpi_disable(struct exynos_drm_display *display)
 	}
 }
 
-static struct exynos_drm_display_ops exynos_dpi_display_ops = {
+static struct exynos_drm_encoder_ops exynos_dpi_encoder_ops = {
 	.create_connector = exynos_dpi_create_connector,
 	.enable = exynos_dpi_enable,
 	.disable = exynos_dpi_disable,
@@ -282,7 +280,7 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
 	return 0;
 }
 
-struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
+struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
 {
 	struct exynos_dpi *ctx;
 	int ret;
@@ -291,8 +289,7 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
 	if (!ctx)
 		return ERR_PTR(-ENOMEM);
 
-	ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD;
-	ctx->display.ops = &exynos_dpi_display_ops;
+	ctx->encoder.ops = &exynos_dpi_encoder_ops;
 	ctx->dev = dev;
 
 	ret = exynos_dpi_parse_dt(ctx);
@@ -307,14 +304,14 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
 			return ERR_PTR(-EPROBE_DEFER);
 	}
 
-	return &ctx->display;
+	return &ctx->encoder;
 }
 
-int exynos_dpi_remove(struct exynos_drm_display *display)
+int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dpi *ctx = display_to_dpi(display);
+	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
-	exynos_dpi_disable(&ctx->display);
+	exynos_dpi_disable(&ctx->encoder);
 
 	if (ctx->panel)
 		drm_panel_detach(ctx->panel);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 47ea400..4931193 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -22,6 +22,7 @@
 #define MAX_PLANE	5
 #define MAX_FB_BUFFER	4
 
+#define to_exynos_encoder(x)	container_of(x, struct exynos_drm_encoder, base)
 #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
 #define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)
 
@@ -77,7 +78,7 @@ struct exynos_drm_plane {
 };
 
 /*
- * Exynos DRM Display Structure.
+ * Exynos DRM Encoder Structure.
  *	- this structure is common to analog tv, digital tv and lcd panel.
  *
  * @create_connector: initialize and register a new connector
@@ -88,37 +89,30 @@ struct exynos_drm_plane {
  * @disable: display device off.
  * @commit: apply changes to hw
  */
-struct exynos_drm_display;
-struct exynos_drm_display_ops {
-	int (*create_connector)(struct exynos_drm_display *display,
-				struct drm_encoder *encoder);
-	void (*mode_fixup)(struct exynos_drm_display *display,
+struct exynos_drm_encoder;
+struct exynos_drm_encoder_ops {
+	int (*create_connector)(struct exynos_drm_encoder *encoder);
+	void (*mode_fixup)(struct exynos_drm_encoder *encoder,
 				struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode);
-	void (*mode_set)(struct exynos_drm_display *display,
+	void (*mode_set)(struct exynos_drm_encoder *encoder,
 				struct drm_display_mode *mode);
-	void (*enable)(struct exynos_drm_display *display);
-	void (*disable)(struct exynos_drm_display *display);
-	void (*commit)(struct exynos_drm_display *display);
+	void (*enable)(struct exynos_drm_encoder *encoder);
+	void (*disable)(struct exynos_drm_encoder *encoder);
+	void (*commit)(struct exynos_drm_encoder *encoder);
 };
 
 /*
- * Exynos drm display structure, maps 1:1 with an encoder/connector
+ * exynos specific encoder structure.
  *
- * @list: the list entry for this manager
+ * @drm_encoder: encoder object.
  * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
- * @encoder: encoder object this display maps to
- * @connector: connector object this display maps to
  * @ops: pointer to callbacks for exynos drm specific functionality
- * @ctx: A pointer to the display's implementation specific context
  */
-struct exynos_drm_display {
-	struct list_head list;
-	enum exynos_drm_output_type type;
-	struct drm_encoder *encoder;
-	struct drm_connector *connector;
-	struct exynos_drm_display_ops *ops;
+struct exynos_drm_encoder {
+	struct drm_encoder		base;
+	struct exynos_drm_encoder_ops	*ops;
 };
 
 /*
@@ -265,12 +259,12 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
 
 #ifdef CONFIG_DRM_EXYNOS_DPI
-struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
-int exynos_dpi_remove(struct exynos_drm_display *display);
+struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev);
+int exynos_dpi_remove(struct exynos_drm_encoder *encoder);
 #else
-static inline struct exynos_drm_display *
+static inline struct exynos_drm_encoder *
 exynos_dpi_probe(struct device *dev) { return NULL; }
-static inline int exynos_dpi_remove(struct exynos_drm_display *display)
+static inline int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
 {
 	return 0;
 }
@@ -278,7 +272,8 @@ static inline int exynos_dpi_remove(struct exynos_drm_display *display)
 
 /* This function creates a encoder and a connector, and initializes them. */
 int exynos_drm_create_enc_conn(struct drm_device *dev,
-				struct exynos_drm_display *display);
+			       struct exynos_drm_encoder *encoder,
+			       enum exynos_drm_output_type type);
 
 extern struct platform_driver fimd_driver;
 extern struct platform_driver exynos5433_decon_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 281b97d..fef3a61 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -259,7 +259,7 @@ struct exynos_dsi_driver_data {
 };
 
 struct exynos_dsi {
-	struct exynos_drm_display display;
+	struct exynos_drm_encoder encoder;
 	struct mipi_dsi_host dsi_host;
 	struct drm_connector connector;
 	struct device_node *panel_node;
@@ -295,9 +295,9 @@ struct exynos_dsi {
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
-static inline struct exynos_dsi *display_to_dsi(struct exynos_drm_display *d)
+static inline struct exynos_dsi *encoder_to_dsi(struct exynos_drm_encoder *e)
 {
-	return container_of(d, struct exynos_dsi, display);
+	return container_of(e, struct exynos_dsi, encoder);
 }
 
 enum reg_idx {
@@ -1272,7 +1272,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
 {
 	struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
-	struct drm_encoder *encoder = dsi->display.encoder;
+	struct drm_encoder *encoder = &dsi->encoder.base;
 
 	if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
 		exynos_drm_crtc_te_handler(encoder->crtc);
@@ -1518,9 +1518,9 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
 		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
 }
 
-static void exynos_dsi_enable(struct exynos_drm_display *display)
+static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dsi *dsi = display_to_dsi(display);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	int ret;
 
 	if (dsi->state & DSIM_STATE_ENABLED)
@@ -1554,9 +1554,9 @@ static void exynos_dsi_enable(struct exynos_drm_display *display)
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 }
 
-static void exynos_dsi_disable(struct exynos_drm_display *display)
+static void exynos_dsi_disable(struct exynos_drm_encoder *encoder)
 {
-	struct exynos_dsi *dsi = display_to_dsi(display);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 
 	if (!(dsi->state & DSIM_STATE_ENABLED))
 		return;
@@ -1582,10 +1582,10 @@ exynos_dsi_detect(struct drm_connector *connector, bool force)
 		if (dsi->panel)
 			drm_panel_attach(dsi->panel, &dsi->connector);
 	} else if (!dsi->panel_node) {
-		struct exynos_drm_display *display;
+		struct exynos_drm_encoder *encoder;
 
-		display = platform_get_drvdata(to_platform_device(dsi->dev));
-		exynos_dsi_disable(display);
+		encoder = platform_get_drvdata(to_platform_device(dsi->dev));
+		exynos_dsi_disable(encoder);
 		drm_panel_detach(dsi->panel);
 		dsi->panel = NULL;
 	}
@@ -1628,7 +1628,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dsi *dsi = connector_to_dsi(connector);
 
-	return dsi->display.encoder;
+	return &dsi->encoder.base;
 }
 
 static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
@@ -1636,10 +1636,11 @@ static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
 	.best_encoder = exynos_dsi_best_encoder,
 };
 
-static int exynos_dsi_create_connector(struct exynos_drm_display *display,
-				       struct drm_encoder *encoder)
+static int exynos_dsi_create_connector(
+				struct exynos_drm_encoder *exynos_encoder)
 {
-	struct exynos_dsi *dsi = display_to_dsi(display);
+	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
+	struct drm_encoder *encoder = &exynos_encoder->base;
 	struct drm_connector *connector = &dsi->connector;
 	int ret;
 
@@ -1660,10 +1661,10 @@ static int exynos_dsi_create_connector(struct exynos_drm_display *display,
 	return 0;
 }
 
-static void exynos_dsi_mode_set(struct exynos_drm_display *display,
+static void exynos_dsi_mode_set(struct exynos_drm_encoder *encoder,
 			 struct drm_display_mode *mode)
 {
-	struct exynos_dsi *dsi = display_to_dsi(display);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct videomode *vm = &dsi->vm;
 
 	vm->hactive = mode->hdisplay;
@@ -1676,7 +1677,7 @@ static void exynos_dsi_mode_set(struct exynos_drm_display *display,
 	vm->hsync_len = mode->hsync_end - mode->hsync_start;
 }
 
-static struct exynos_drm_display_ops exynos_dsi_display_ops = {
+static struct exynos_drm_encoder_ops exynos_dsi_encoder_ops = {
 	.create_connector = exynos_dsi_create_connector,
 	.mode_set = exynos_dsi_mode_set,
 	.enable = exynos_dsi_enable,
@@ -1803,22 +1804,22 @@ end:
 static int exynos_dsi_bind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_display *display = dev_get_drvdata(dev);
-	struct exynos_dsi *dsi = display_to_dsi(display);
+	struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct drm_device *drm_dev = data;
 	struct drm_bridge *bridge;
 	int ret;
 
-	ret = exynos_drm_create_enc_conn(drm_dev, display);
+	ret = exynos_drm_create_enc_conn(drm_dev, encoder,
+					 EXYNOS_DISPLAY_TYPE_LCD);
 	if (ret) {
 		DRM_ERROR("Encoder create [%d] failed with %d\n",
-			  display->type, ret);
+			  EXYNOS_DISPLAY_TYPE_LCD, ret);
 		return ret;
 	}
 
 	bridge = of_drm_find_bridge(dsi->bridge_node);
 	if (bridge) {
-		display->encoder->bridge = bridge;
 		drm_bridge_attach(drm_dev, bridge);
 	}
 
@@ -1828,10 +1829,10 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 static void exynos_dsi_unbind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_display *display = dev_get_drvdata(dev);
-	struct exynos_dsi *dsi = display_to_dsi(display);
+	struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 
-	exynos_dsi_disable(display);
+	exynos_dsi_disable(encoder);
 
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
@@ -1852,8 +1853,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD;
-	dsi->display.ops = &exynos_dsi_display_ops;
+	dsi->encoder.ops = &exynos_dsi_encoder_ops;
 
 	/* To be checked as invalid one */
 	dsi->te_gpio = -ENOENT;
@@ -1930,7 +1930,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	platform_set_drvdata(pdev, &dsi->display);
+	platform_set_drvdata(pdev, &dsi->encoder);
 
 	return component_add(dev, &exynos_dsi_component_ops);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 7ba3a2d..b9a1c93 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -18,20 +18,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_encoder.h"
 
-#define to_exynos_encoder(x)	container_of(x, struct exynos_drm_encoder,\
-				drm_encoder)
-
-/*
- * exynos specific encoder structure.
- *
- * @drm_encoder: encoder object.
- * @display: the display structure that maps to this encoder
- */
-struct exynos_drm_encoder {
-	struct drm_encoder		drm_encoder;
-	struct exynos_drm_display	*display;
-};
-
 static bool
 exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
 			       const struct drm_display_mode *mode,
@@ -39,16 +25,16 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
 {
 	struct drm_device *dev = encoder->dev;
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct exynos_drm_display *display = exynos_encoder->display;
 	struct drm_connector *connector;
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		if (connector->encoder != encoder)
 			continue;
 
-		if (display->ops->mode_fixup)
-			display->ops->mode_fixup(display, connector, mode,
-					adjusted_mode);
+		if (exynos_encoder->ops->mode_fixup)
+			exynos_encoder->ops->mode_fixup(exynos_encoder,
+							connector, mode,
+							adjusted_mode);
 	}
 
 	return true;
@@ -59,31 +45,28 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
 					 struct drm_display_mode *adjusted_mode)
 {
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->mode_set)
-		display->ops->mode_set(display, adjusted_mode);
+	if (exynos_encoder->ops->mode_set)
+		exynos_encoder->ops->mode_set(exynos_encoder, adjusted_mode);
 }
 
 static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
 {
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->enable)
-		display->ops->enable(display);
+	if (exynos_encoder->ops->enable)
+		exynos_encoder->ops->enable(exynos_encoder);
 
-	if (display->ops->commit)
-		display->ops->commit(display);
+	if (exynos_encoder->ops->commit)
+		exynos_encoder->ops->commit(exynos_encoder);
 }
 
 static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
 {
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->disable)
-		display->ops->disable(display);
+	if (exynos_encoder->ops->disable)
+		exynos_encoder->ops->disable(exynos_encoder);
 }
 
 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
@@ -93,16 +76,8 @@ static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
 	.disable	= exynos_drm_encoder_disable,
 };
 
-static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	drm_encoder_cleanup(encoder);
-	kfree(exynos_encoder);
-}
-
 static struct drm_encoder_funcs exynos_encoder_funcs = {
-	.destroy = exynos_drm_encoder_destroy,
+	.destroy = drm_encoder_cleanup,
 };
 
 void exynos_drm_encoder_setup(struct drm_device *dev)
@@ -118,23 +93,16 @@ void exynos_drm_encoder_setup(struct drm_device *dev)
 		encoder->possible_clones = clone_mask;
 }
 
-struct drm_encoder *
-exynos_drm_encoder_create(struct drm_device *dev,
-			   struct exynos_drm_display *display,
-			   unsigned long possible_crtcs)
+int exynos_drm_encoder_create(struct drm_device *dev,
+			      struct exynos_drm_encoder *exynos_encoder,
+			      unsigned long possible_crtcs)
 {
 	struct drm_encoder *encoder;
-	struct exynos_drm_encoder *exynos_encoder;
 
 	if (!possible_crtcs)
-		return NULL;
-
-	exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
-	if (!exynos_encoder)
-		return NULL;
+		return -EINVAL;
 
-	exynos_encoder->display = display;
-	encoder = &exynos_encoder->drm_encoder;
+	encoder = &exynos_encoder->base;
 	encoder->possible_crtcs = possible_crtcs;
 
 	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
@@ -146,10 +114,5 @@ exynos_drm_encoder_create(struct drm_device *dev,
 
 	DRM_DEBUG_KMS("encoder has been created\n");
 
-	return encoder;
-}
-
-struct exynos_drm_display *exynos_drm_get_display(struct drm_encoder *encoder)
-{
-	return to_exynos_encoder(encoder)->display;
+	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
index 26305d8..005f583 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
@@ -15,9 +15,7 @@
 #define _EXYNOS_DRM_ENCODER_H_
 
 void exynos_drm_encoder_setup(struct drm_device *dev);
-struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
-			struct exynos_drm_display *mgr,
-			unsigned long possible_crtcs);
-struct exynos_drm_display *exynos_drm_get_display(struct drm_encoder *encoder);
+int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
+			      *encoder, unsigned long possible_crtcs);
 
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 88dea9d..9edd11d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -169,7 +169,7 @@ struct fimd_context {
 
 	struct exynos_drm_panel_info panel;
 	struct fimd_driver_data *driver_data;
-	struct exynos_drm_display *display;
+	struct exynos_drm_encoder *encoder;
 };
 
 static const struct of_device_id fimd_driver_dt_match[] = {
@@ -945,8 +945,9 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 	if (IS_ERR(ctx->crtc))
 		return PTR_ERR(ctx->crtc);
 
-	if (ctx->display)
-		exynos_drm_create_enc_conn(drm_dev, ctx->display);
+	if (ctx->encoder)
+		exynos_drm_create_enc_conn(drm_dev, ctx->encoder,
+					   EXYNOS_DISPLAY_TYPE_LCD);
 
 	if (is_drm_iommu_supported(drm_dev))
 		fimd_clear_channels(ctx->crtc);
@@ -967,8 +968,8 @@ static void fimd_unbind(struct device *dev, struct device *master,
 
 	drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
 
-	if (ctx->display)
-		exynos_dpi_remove(ctx->display);
+	if (ctx->encoder)
+		exynos_dpi_remove(ctx->encoder);
 }
 
 static const struct component_ops fimd_component_ops = {
@@ -1075,10 +1076,9 @@ static int fimd_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ctx);
 
-	ctx->display = exynos_dpi_probe(dev);
-	if (IS_ERR(ctx->display)) {
-		return PTR_ERR(ctx->display);
-	}
+	ctx->encoder = exynos_dpi_probe(dev);
+	if (IS_ERR(ctx->encoder))
+		return PTR_ERR(ctx->encoder);
 
 	pm_runtime_enable(dev);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index ade59ee..d7f9501 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -35,11 +35,10 @@
 					connector)
 
 struct vidi_context {
-	struct exynos_drm_display	display;
+	struct exynos_drm_encoder	encoder;
 	struct platform_device		*pdev;
 	struct drm_device		*drm_dev;
 	struct exynos_drm_crtc		*crtc;
-	struct drm_encoder		*encoder;
 	struct drm_connector		connector;
 	struct exynos_drm_plane		planes[WINDOWS_NR];
 	struct edid			*raw_edid;
@@ -55,9 +54,9 @@ struct vidi_context {
 	int				pipe;
 };
 
-static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
+static inline struct vidi_context *encoder_to_vidi(struct exynos_drm_encoder *e)
 {
-	return container_of(d, struct vidi_context, display);
+	return container_of(e, struct vidi_context, encoder);
 }
 
 static const char fake_edid_info[] = {
@@ -254,9 +253,7 @@ static DEVICE_ATTR(connection, 0644, vidi_show_connection,
 int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
 				struct drm_file *file_priv)
 {
-	struct vidi_context *ctx = NULL;
-	struct drm_encoder *encoder;
-	struct exynos_drm_display *display;
+	struct vidi_context *ctx = dev_get_drvdata(drm_dev->dev);
 	struct drm_exynos_vidi_connection *vidi = data;
 
 	if (!vidi) {
@@ -269,21 +266,6 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
 		return -EINVAL;
 	}
 
-	list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list,
-								head) {
-		display = exynos_drm_get_display(encoder);
-
-		if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
-			ctx = display_to_vidi(display);
-			break;
-		}
-	}
-
-	if (!ctx) {
-		DRM_DEBUG_KMS("not found virtual device type encoder.\n");
-		return -EINVAL;
-	}
-
 	if (ctx->connected == vidi->connection) {
 		DRM_DEBUG_KMS("same connection request.\n");
 		return -EINVAL;
@@ -376,7 +358,7 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
 {
 	struct vidi_context *ctx = ctx_from_connector(connector);
 
-	return ctx->encoder;
+	return &ctx->encoder.base;
 }
 
 static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
@@ -384,14 +366,13 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
 	.best_encoder = vidi_best_encoder,
 };
 
-static int vidi_create_connector(struct exynos_drm_display *display,
-				struct drm_encoder *encoder)
+static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 {
-	struct vidi_context *ctx = display_to_vidi(display);
+	struct vidi_context *ctx = encoder_to_vidi(exynos_encoder);
+	struct drm_encoder *encoder = &exynos_encoder->base;
 	struct drm_connector *connector = &ctx->connector;
 	int ret;
 
-	ctx->encoder = encoder;
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
 	ret = drm_connector_init(ctx->drm_dev, connector,
@@ -409,7 +390,7 @@ static int vidi_create_connector(struct exynos_drm_display *display,
 }
 
 
-static struct exynos_drm_display_ops vidi_display_ops = {
+static struct exynos_drm_encoder_ops vidi_encoder_ops = {
 	.create_connector = vidi_create_connector,
 };
 
@@ -442,7 +423,8 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 	}
 
-	ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
+	ret = exynos_drm_create_enc_conn(drm_dev, &ctx->encoder,
+					 EXYNOS_DISPLAY_TYPE_VIDI);
 	if (ret) {
 		ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
 		return ret;
@@ -470,8 +452,7 @@ static int vidi_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
-	ctx->display.ops = &vidi_display_ops;
+	ctx->encoder.ops = &vidi_encoder_ops;
 	ctx->default_win = 0;
 	ctx->pdev = pdev;
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9b9396a..1aed7ea 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -87,11 +87,11 @@ struct hdmi_resources {
 };
 
 struct hdmi_context {
-	struct exynos_drm_display	display;
+	struct exynos_drm_encoder	encoder;
 	struct device			*dev;
 	struct drm_device		*drm_dev;
 	struct drm_connector		connector;
-	struct drm_encoder		*encoder;
+	bool				hpd;
 	bool				powered;
 	bool				dvi_mode;
 
@@ -115,9 +115,9 @@ struct hdmi_context {
 	struct regmap			*pmureg;
 };
 
-static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d)
+static inline struct hdmi_context *encoder_to_hdmi(struct exynos_drm_encoder *e)
 {
-	return container_of(d, struct hdmi_context, display);
+	return container_of(e, struct hdmi_context, encoder);
 }
 
 struct hdmiphy_config {
@@ -1031,7 +1031,7 @@ static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
 {
 	struct hdmi_context *hdata = ctx_from_connector(connector);
 
-	return hdata->encoder;
+	return &hdata->encoder.base;
 }
 
 static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
@@ -1040,14 +1040,12 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 	.best_encoder = hdmi_best_encoder,
 };
 
-static int hdmi_create_connector(struct exynos_drm_display *display,
-			struct drm_encoder *encoder)
+static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 {
-	struct hdmi_context *hdata = display_to_hdmi(display);
+	struct hdmi_context *hdata = encoder_to_hdmi(exynos_encoder);
 	struct drm_connector *connector = &hdata->connector;
 	int ret;
 
-	hdata->encoder = encoder;
 	connector->interlace_allowed = true;
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
@@ -1060,12 +1058,12 @@ static int hdmi_create_connector(struct exynos_drm_display *display,
 
 	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 	drm_connector_register(connector);
-	drm_mode_connector_attach_encoder(connector, encoder);
+	drm_mode_connector_attach_encoder(connector, &exynos_encoder->base);
 
 	return 0;
 }
 
-static void hdmi_mode_fixup(struct exynos_drm_display *display,
+static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
 				struct drm_connector *connector,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
@@ -1698,10 +1696,10 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
 	hdmi_regs_dump(hdata, "start");
 }
 
-static void hdmi_mode_set(struct exynos_drm_display *display,
+static void hdmi_mode_set(struct exynos_drm_encoder *encoder,
 			struct drm_display_mode *mode)
 {
-	struct hdmi_context *hdata = display_to_hdmi(display);
+	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct drm_display_mode *m = mode;
 
 	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
@@ -1713,9 +1711,9 @@ static void hdmi_mode_set(struct exynos_drm_display *display,
 	hdata->cea_video_id = drm_match_cea_mode(mode);
 }
 
-static void hdmi_commit(struct exynos_drm_display *display)
+static void hdmi_commit(struct exynos_drm_encoder *encoder)
 {
-	struct hdmi_context *hdata = display_to_hdmi(display);
+	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 
 	if (!hdata->powered)
 		return;
@@ -1723,9 +1721,9 @@ static void hdmi_commit(struct exynos_drm_display *display)
 	hdmi_conf_apply(hdata);
 }
 
-static void hdmi_enable(struct exynos_drm_display *display)
+static void hdmi_enable(struct exynos_drm_encoder *encoder)
 {
-	struct hdmi_context *hdata = display_to_hdmi(display);
+	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct hdmi_resources *res = &hdata->res;
 
 	if (hdata->powered)
@@ -1746,14 +1744,14 @@ static void hdmi_enable(struct exynos_drm_display *display)
 	clk_prepare_enable(res->sclk_hdmi);
 
 	hdmiphy_poweron(hdata);
-	hdmi_commit(display);
+	hdmi_commit(encoder);
 }
 
-static void hdmi_disable(struct exynos_drm_display *display)
+static void hdmi_disable(struct exynos_drm_encoder *encoder)
 {
-	struct hdmi_context *hdata = display_to_hdmi(display);
+	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct hdmi_resources *res = &hdata->res;
-	struct drm_crtc *crtc = hdata->encoder->crtc;
+	struct drm_crtc *crtc = hdata->encoder.base.crtc;
 	const struct drm_crtc_helper_funcs *funcs = NULL;
 
 	if (!hdata->powered)
@@ -1794,7 +1792,7 @@ static void hdmi_disable(struct exynos_drm_display *display)
 	hdata->powered = false;
 }
 
-static struct exynos_drm_display_ops hdmi_display_ops = {
+static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
 	.create_connector = hdmi_create_connector,
 	.mode_fixup	= hdmi_mode_fixup,
 	.mode_set	= hdmi_mode_set,
@@ -1933,7 +1931,8 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
 
 	hdata->drm_dev = drm_dev;
 
-	return exynos_drm_create_enc_conn(drm_dev, &hdata->display);
+	return exynos_drm_create_enc_conn(drm_dev, &hdata->encoder,
+					  EXYNOS_DISPLAY_TYPE_HDMI);
 }
 
 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
@@ -1982,8 +1981,7 @@ static int hdmi_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	hdata->drv_data = match->data;
-	hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
-	hdata->display.ops = &hdmi_display_ops;
+	hdata->encoder.ops = &hdmi_encoder_ops;
 
 	platform_set_drvdata(pdev, hdata);
 
-- 
2.1.0

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

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

* [PATCH v2 06/11] drm/exynos: remove extra call to hdmi_commit()
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (4 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 05/11] drm/exynos: remove struct exynos_drm_display Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 07/11] drm/exynos: remove extra call to exynos_dp_commit() Gustavo Padovan
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

hdmi_commit() was getting called twice by exynos encoder core, once inside
the .enable() call and another time by .commit() itself.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 1aed7ea..11bac50 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1711,16 +1711,6 @@ static void hdmi_mode_set(struct exynos_drm_encoder *encoder,
 	hdata->cea_video_id = drm_match_cea_mode(mode);
 }
 
-static void hdmi_commit(struct exynos_drm_encoder *encoder)
-{
-	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
-
-	if (!hdata->powered)
-		return;
-
-	hdmi_conf_apply(hdata);
-}
-
 static void hdmi_enable(struct exynos_drm_encoder *encoder)
 {
 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
@@ -1744,7 +1734,7 @@ static void hdmi_enable(struct exynos_drm_encoder *encoder)
 	clk_prepare_enable(res->sclk_hdmi);
 
 	hdmiphy_poweron(hdata);
-	hdmi_commit(encoder);
+	hdmi_conf_apply(hdata);
 }
 
 static void hdmi_disable(struct exynos_drm_encoder *encoder)
@@ -1798,7 +1788,6 @@ static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
 	.mode_set	= hdmi_mode_set,
 	.enable		= hdmi_enable,
 	.disable	= hdmi_disable,
-	.commit		= hdmi_commit,
 };
 
 static void hdmi_hotplug_work_func(struct work_struct *work)
-- 
2.1.0

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

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

* [PATCH v2 07/11] drm/exynos: remove extra call to exynos_dp_commit()
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (5 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 06/11] drm/exynos: remove extra call to hdmi_commit() Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 08/11] drm/exynos: remove exynos_encoder's .commit() op Gustavo Padovan
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

exynos_dp_commit() was getting called twice by exynos encoder core, once
inside the .enable() call and another time by .commit() itself.

The remove of the second call caused the wake of a bug, the operations
orders inside exynos_dp_commit was wrong and we had to move
exynos_dp_start_video() to be the last operation in there.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_dp_core.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 002a233..6d9d115 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -795,9 +795,6 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp)
 	/* Configure video slave mode */
 	exynos_dp_enable_video_master(dp, 0);
 
-	/* Enable video */
-	exynos_dp_start_video(dp);
-
 	timeout_loop = 0;
 
 	for (;;) {
@@ -938,6 +935,9 @@ static void exynos_dp_commit(struct exynos_drm_encoder *encoder)
 		if (drm_panel_enable(dp->panel))
 			DRM_ERROR("failed to enable the panel\n");
 	}
+
+	/* Enable video */
+	exynos_dp_start_video(dp);
 }
 
 static enum drm_connector_status exynos_dp_detect(
@@ -1110,7 +1110,6 @@ static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
 	.create_connector = exynos_dp_create_connector,
 	.enable = exynos_dp_enable,
 	.disable = exynos_dp_disable,
-	.commit = exynos_dp_commit,
 };
 
 static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
-- 
2.1.0

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

* [PATCH v2 08/11] drm/exynos: remove exynos_encoder's .commit() op
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (6 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 07/11] drm/exynos: remove extra call to exynos_dp_commit() Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-05 23:24 ` [PATCH v2 09/11] drm/exynos: remove exynos_drm_create_enc_conn() Gustavo Padovan
  2015-08-06 11:55 ` [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Inki Dae
  9 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

.commit() is not used anymore, Exynos encoders now follow the
.enable()/.disable() semantics from drm atomic core, so remove this
callback.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.h     | 2 --
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 4931193..76ed6a1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -87,7 +87,6 @@ struct exynos_drm_plane {
  *	      would be called by encoder->mode_set().
  * @enable: display device on.
  * @disable: display device off.
- * @commit: apply changes to hw
  */
 struct exynos_drm_encoder;
 struct exynos_drm_encoder_ops {
@@ -100,7 +99,6 @@ struct exynos_drm_encoder_ops {
 				struct drm_display_mode *mode);
 	void (*enable)(struct exynos_drm_encoder *encoder);
 	void (*disable)(struct exynos_drm_encoder *encoder);
-	void (*commit)(struct exynos_drm_encoder *encoder);
 };
 
 /*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index b9a1c93..ce7b97e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -56,9 +56,6 @@ static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
 
 	if (exynos_encoder->ops->enable)
 		exynos_encoder->ops->enable(exynos_encoder);
-
-	if (exynos_encoder->ops->commit)
-		exynos_encoder->ops->commit(exynos_encoder);
 }
 
 static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
-- 
2.1.0

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

* [PATCH v2 09/11] drm/exynos: remove exynos_drm_create_enc_conn()
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (7 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 08/11] drm/exynos: remove exynos_encoder's .commit() op Gustavo Padovan
@ 2015-08-05 23:24 ` Gustavo Padovan
  2015-08-06 13:31   ` [PATCH v2 10/11] drm/exynos: fold encoder setup into exynos_drm_load() Gustavo Padovan
  2015-08-06 11:55 ` [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Inki Dae
  9 siblings, 1 reply; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-05 23:24 UTC (permalink / raw)
  To: linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

This functions was just hiding the encoder and connector creation in
a way that was less clean than if we get rid of it. For example,
exynos_encoder ops had .create_connector() defined only because we were
handing off the encoder and connector creation to
exynos_drm_create_enc_conn(). Without this function we can directly call
the create_connector function internally in the code, without the need of
any vtable access.

It also does some refactoring in the code like creating a bind function
for dpi devices.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
v2: check ret value of hdmi_create_connector()
---
 drivers/gpu/drm/exynos/exynos7_drm_decon.c  |  3 +--
 drivers/gpu/drm/exynos/exynos_dp_core.c     | 20 ++++++++++++++++---
 drivers/gpu/drm/exynos/exynos_drm_core.c    | 30 -----------------------------
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     | 26 +++++++++++++++++++++++--
 drivers/gpu/drm/exynos/exynos_drm_drv.h     | 12 ++++++------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     | 20 ++++++++++++-------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 11 +++++++----
 drivers/gpu/drm/exynos/exynos_drm_encoder.h |  4 +++-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c    |  3 +--
 drivers/gpu/drm/exynos/exynos_drm_vidi.c    | 20 ++++++++++---------
 drivers/gpu/drm/exynos/exynos_hdmi.c        | 21 +++++++++++++++++---
 11 files changed, 101 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 1b89e94..e1a2ce7 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -682,8 +682,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
 	}
 
 	if (ctx->encoder)
-		exynos_drm_create_enc_conn(drm_dev, ctx->encoder,
-					   EXYNOS_DISPLAY_TYPE_LCD);
+		exynos_dpi_bind(drm_dev, ctx->encoder);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 6d9d115..4d49d25 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -32,6 +32,7 @@
 #include <drm/drm_panel.h>
 
 #include "exynos_dp_core.h"
+#include "exynos_drm_encoder.h"
 
 #define ctx_from_connector(c)	container_of(c, struct exynos_dp_device, \
 					connector)
@@ -1107,7 +1108,6 @@ static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
 }
 
 static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
-	.create_connector = exynos_dp_create_connector,
 	.enable = exynos_dp_enable,
 	.disable = exynos_dp_disable,
 };
@@ -1188,6 +1188,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm_dev = data;
+	struct exynos_drm_encoder *exynos_encoder = &dp->encoder;
 	struct resource *res;
 	unsigned int irq_flags;
 	int ret = 0;
@@ -1280,8 +1281,21 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 
 	dp->drm_dev = drm_dev;
 
-	return exynos_drm_create_enc_conn(drm_dev, &dp->encoder,
-					  EXYNOS_DISPLAY_TYPE_LCD);
+	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
+					EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret) {
+		DRM_ERROR("failed to create encoder\n");
+		return ret;
+	}
+
+	ret = exynos_dp_create_connector(exynos_encoder);
+	if (ret) {
+		DRM_ERROR("failed to create connector ret = %d\n", ret);
+		drm_encoder_cleanup(&exynos_encoder->base);
+		return ret;
+	}
+
+	return 0;
 }
 
 static void exynos_dp_unbind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index e386452..1f38a44 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -20,36 +20,6 @@
 
 static LIST_HEAD(exynos_drm_subdrv_list);
 
-int exynos_drm_create_enc_conn(struct drm_device *dev,
-			       struct exynos_drm_encoder *exynos_encoder,
-			       enum exynos_drm_output_type type)
-{
-	int ret;
-	unsigned long possible_crtcs = 0;
-
-	ret = exynos_drm_crtc_get_pipe_from_type(dev, type);
-	if (ret < 0)
-		return ret;
-
-	possible_crtcs |= 1 << ret;
-
-	/* create and initialize a encoder for this sub driver. */
-	ret = exynos_drm_encoder_create(dev, exynos_encoder, possible_crtcs);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
-
-	ret = exynos_encoder->ops->create_connector(exynos_encoder);
-	if (ret) {
-		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
-		return ret;
-	}
-
-	return 0;
-}
-
 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
 {
 	if (!subdrv)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 60a3161..6850ce5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -20,7 +20,8 @@
 #include <video/of_videomode.h>
 #include <video/videomode.h>
 
-#include "exynos_drm_drv.h"
+#include "exynos_drm_encoder.h"
+#include "exynos_drm_crtc.h"
 
 struct exynos_dpi {
 	struct exynos_drm_encoder encoder;
@@ -151,7 +152,6 @@ static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
 }
 
 static struct exynos_drm_encoder_ops exynos_dpi_encoder_ops = {
-	.create_connector = exynos_dpi_create_connector,
 	.enable = exynos_dpi_enable,
 	.disable = exynos_dpi_disable,
 };
@@ -280,6 +280,28 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
 	return 0;
 }
 
+int exynos_dpi_bind(struct drm_device *dev,
+		    struct exynos_drm_encoder *exynos_encoder)
+{
+	int ret;
+
+	ret = exynos_drm_encoder_create(dev, exynos_encoder,
+					EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret) {
+		DRM_ERROR("failed to create encoder\n");
+		return ret;
+	}
+
+	ret = exynos_dpi_create_connector(exynos_encoder);
+	if (ret) {
+		DRM_ERROR("failed to create connector ret = %d\n", ret);
+		drm_encoder_cleanup(&exynos_encoder->base);
+		return ret;
+	}
+
+	return 0;
+}
+
 struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
 {
 	struct exynos_dpi *ctx;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 76ed6a1..a4977be 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -81,7 +81,6 @@ struct exynos_drm_plane {
  * Exynos DRM Encoder Structure.
  *	- this structure is common to analog tv, digital tv and lcd panel.
  *
- * @create_connector: initialize and register a new connector
  * @mode_fixup: fix mode data comparing to hw specific display mode.
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *	      would be called by encoder->mode_set().
@@ -90,7 +89,6 @@ struct exynos_drm_plane {
  */
 struct exynos_drm_encoder;
 struct exynos_drm_encoder_ops {
-	int (*create_connector)(struct exynos_drm_encoder *encoder);
 	void (*mode_fixup)(struct exynos_drm_encoder *encoder,
 				struct drm_connector *connector,
 				const struct drm_display_mode *mode,
@@ -259,6 +257,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
 #ifdef CONFIG_DRM_EXYNOS_DPI
 struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev);
 int exynos_dpi_remove(struct exynos_drm_encoder *encoder);
+int exynos_dpi_bind(struct drm_device *dev, struct exynos_drm_encoder *encoder);
 #else
 static inline struct exynos_drm_encoder *
 exynos_dpi_probe(struct device *dev) { return NULL; }
@@ -266,12 +265,13 @@ static inline int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
 {
 	return 0;
 }
+static inline int exynos_dpi_bind(struct drm_device *dev,
+				  struct exynos_drm_encoder *encoder)
+{
+	return 0;
+}
 #endif
 
-/* This function creates a encoder and a connector, and initializes them. */
-int exynos_drm_create_enc_conn(struct drm_device *dev,
-			       struct exynos_drm_encoder *encoder,
-			       enum exynos_drm_output_type type);
 
 extern struct platform_driver fimd_driver;
 extern struct platform_driver exynos5433_decon_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index fef3a61..d791ad4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -30,6 +30,7 @@
 #include <video/videomode.h>
 
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_encoder.h"
 #include "exynos_drm_drv.h"
 
 /* returns true iff both arguments logically differs */
@@ -1678,7 +1679,6 @@ static void exynos_dsi_mode_set(struct exynos_drm_encoder *encoder,
 }
 
 static struct exynos_drm_encoder_ops exynos_dsi_encoder_ops = {
-	.create_connector = exynos_dsi_create_connector,
 	.mode_set = exynos_dsi_mode_set,
 	.enable = exynos_dsi_enable,
 	.disable = exynos_dsi_disable,
@@ -1804,17 +1804,23 @@ end:
 static int exynos_dsi_bind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
-	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
+	struct exynos_drm_encoder *exynos_encoder = dev_get_drvdata(dev);
+	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
 	struct drm_device *drm_dev = data;
 	struct drm_bridge *bridge;
 	int ret;
 
-	ret = exynos_drm_create_enc_conn(drm_dev, encoder,
-					 EXYNOS_DISPLAY_TYPE_LCD);
+	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
+					EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret) {
+		DRM_ERROR("failed to create encoder\n");
+		return ret;
+	}
+
+	ret = exynos_dsi_create_connector(exynos_encoder);
 	if (ret) {
-		DRM_ERROR("Encoder create [%d] failed with %d\n",
-			  EXYNOS_DISPLAY_TYPE_LCD, ret);
+		DRM_ERROR("failed to create connector ret = %d\n", ret);
+		drm_encoder_cleanup(&exynos_encoder->base);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index ce7b97e..4ed360b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -17,6 +17,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_encoder.h"
+#include "exynos_drm_crtc.h"
 
 static bool
 exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -92,15 +93,17 @@ void exynos_drm_encoder_setup(struct drm_device *dev)
 
 int exynos_drm_encoder_create(struct drm_device *dev,
 			      struct exynos_drm_encoder *exynos_encoder,
-			      unsigned long possible_crtcs)
+			      enum exynos_drm_output_type type)
 {
 	struct drm_encoder *encoder;
+	int pipe;
 
-	if (!possible_crtcs)
-		return -EINVAL;
+	pipe = exynos_drm_crtc_get_pipe_from_type(dev, type);
+	if (pipe < 0)
+		return pipe;
 
 	encoder = &exynos_encoder->base;
-	encoder->possible_crtcs = possible_crtcs;
+	encoder->possible_crtcs = 1 << pipe;
 
 	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
index 005f583..e998b82 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
@@ -14,8 +14,10 @@
 #ifndef _EXYNOS_DRM_ENCODER_H_
 #define _EXYNOS_DRM_ENCODER_H_
 
+#include "exynos_drm_drv.h"
+
 void exynos_drm_encoder_setup(struct drm_device *dev);
 int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
-			      *encoder, unsigned long possible_crtcs);
+			      *encoder, enum exynos_drm_output_type type);
 
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9edd11d..6c0d3de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -946,8 +946,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 
 	if (ctx->encoder)
-		exynos_drm_create_enc_conn(drm_dev, ctx->encoder,
-					   EXYNOS_DISPLAY_TYPE_LCD);
+		exynos_dpi_bind(drm_dev, ctx->encoder);
 
 	if (is_drm_iommu_supported(drm_dev))
 		fimd_clear_channels(ctx->crtc);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index d7f9501..9b64c77 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -389,15 +389,11 @@ static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 	return 0;
 }
 
-
-static struct exynos_drm_encoder_ops vidi_encoder_ops = {
-	.create_connector = vidi_create_connector,
-};
-
 static int vidi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct vidi_context *ctx = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
+	struct exynos_drm_encoder *exynos_encoder = &ctx->encoder;
 	struct exynos_drm_plane *exynos_plane;
 	enum drm_plane_type type;
 	unsigned int zpos;
@@ -423,10 +419,17 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 	}
 
-	ret = exynos_drm_create_enc_conn(drm_dev, &ctx->encoder,
-					 EXYNOS_DISPLAY_TYPE_VIDI);
+	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
+					EXYNOS_DISPLAY_TYPE_VIDI);
+	if (ret) {
+		DRM_ERROR("failed to create encoder\n");
+		return ret;
+	}
+
+	ret = vidi_create_connector(exynos_encoder);
 	if (ret) {
-		ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
+		DRM_ERROR("failed to create connector ret = %d\n", ret);
+		drm_encoder_cleanup(&exynos_encoder->base);
 		return ret;
 	}
 
@@ -452,7 +455,6 @@ static int vidi_probe(struct platform_device *pdev)
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->encoder.ops = &vidi_encoder_ops;
 	ctx->default_win = 0;
 	ctx->pdev = pdev;
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 11bac50..148e42f 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -44,6 +44,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_encoder.h"
 #include "exynos_mixer.h"
 
 #include <linux/gpio.h>
@@ -1783,7 +1784,6 @@ static void hdmi_disable(struct exynos_drm_encoder *encoder)
 }
 
 static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
-	.create_connector = hdmi_create_connector,
 	.mode_fixup	= hdmi_mode_fixup,
 	.mode_set	= hdmi_mode_set,
 	.enable		= hdmi_enable,
@@ -1917,11 +1917,26 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct drm_device *drm_dev = data;
 	struct hdmi_context *hdata = dev_get_drvdata(dev);
+	struct exynos_drm_encoder *exynos_encoder = &hdata->encoder;
+	int ret;
 
 	hdata->drm_dev = drm_dev;
 
-	return exynos_drm_create_enc_conn(drm_dev, &hdata->encoder,
-					  EXYNOS_DISPLAY_TYPE_HDMI);
+	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
+					EXYNOS_DISPLAY_TYPE_HDMI);
+	if (ret) {
+		DRM_ERROR("failed to create encoder\n");
+		return ret;
+	}
+
+	ret = hdmi_create_connector(exynos_encoder);
+	if (ret) {
+		DRM_ERROR("failed to create connector ret = %d\n", ret);
+		drm_encoder_cleanup(&exynos_encoder->base);
+		return ret;
+	}
+
+	return 0;
 }
 
 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
-- 
2.1.0

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

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

* Re: [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder
  2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
                   ` (8 preceding siblings ...)
  2015-08-05 23:24 ` [PATCH v2 09/11] drm/exynos: remove exynos_drm_create_enc_conn() Gustavo Padovan
@ 2015-08-06 11:55 ` Inki Dae
  2015-08-06 13:27   ` Gustavo Padovan
  9 siblings, 1 reply; 27+ messages in thread
From: Inki Dae @ 2015-08-06 11:55 UTC (permalink / raw)
  To: Gustavo Padovan, linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

On 2015년 08월 06일 08:24, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> Hi,
> 
> This patchset is another important step in the exynos clean up, it removes
> two exynos internal structs in favor of wider use of struct drm_encoder.
> 
> Structs exynos_drm_display and exynos_drm_encoder were doing exactly what
> struct drm_encoder does so remove them makes the code cleaner, easier
> to understand and less error prone.
> 
> Please review,
> 
>        Gustavo
> 
> ---
> v2:  - check ret value of hdmi_create_connector()
>      - set dp->dpms_mode after enable/disable	

I don't see patch v2 10/11 and 11/11 in my mailbox. Did you miss them?

Thanks,
Inki Dae

> 
> Gustavo Padovan (11):
>   drm/exynos: split display's .dpms() into .enable() and .disable()
>   drm/exynos: remove wrappers for phy_power_{on,off}
>   drm/exynos: remove unused .remove() and .check_mode() ops from display
>   drm/exynos: simplify calculation of possible CRTCs
>   drm/exynos: remove struct exynos_drm_display
>   drm/exynos: remove extra call to hdmi_commit()
>   drm/exynos: remove extra call to exynos_dp_commit()
>   drm/exynos: remove exynos_encoder's .commit() op
>   drm/exynos: remove exynos_drm_create_enc_conn()
>   drm/exynos: fold encoder setup into exynos_drm_load()
>   drm/exynos: remove struct exynos_drm_encoder layer
> 
>  drivers/gpu/drm/exynos/Makefile             |   7 +-
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c  |  16 +--
>  drivers/gpu/drm/exynos/exynos_dp_core.c     | 119 ++++++++++---------
>  drivers/gpu/drm/exynos/exynos_dp_core.h     |   3 +-
>  drivers/gpu/drm/exynos/exynos_drm_core.c    |  36 ------
>  drivers/gpu/drm/exynos/exynos_drm_crtc.c    |   3 +-
>  drivers/gpu/drm/exynos/exynos_drm_crtc.h    |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c     |  96 ++++++++-------
>  drivers/gpu/drm/exynos/exynos_drm_drv.c     |  13 ++-
>  drivers/gpu/drm/exynos/exynos_drm_drv.h     |  65 ++---------
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c     | 130 ++++++++++-----------
>  drivers/gpu/drm/exynos/exynos_drm_encoder.c | 174 ----------------------------
>  drivers/gpu/drm/exynos/exynos_drm_encoder.h |  23 ----
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c    |  17 ++-
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c    |  90 ++++++++------
>  drivers/gpu/drm/exynos/exynos_hdmi.c        | 160 ++++++++++++-------------
>  16 files changed, 355 insertions(+), 599 deletions(-)
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.c
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.h
> 

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

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

* Re: [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder
  2015-08-06 11:55 ` [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Inki Dae
@ 2015-08-06 13:27   ` Gustavo Padovan
  0 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-06 13:27 UTC (permalink / raw)
  To: Inki Dae
  Cc: linux-samsung-soc, dri-devel, jy0922.shim, tjakobi, Gustavo Padovan

Hi Inki,

2015-08-06 Inki Dae <inki.dae@samsung.com>:

> On 2015년 08월 06일 08:24, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >
> > Hi,
> >
> > This patchset is another important step in the exynos clean up, it removes
> > two exynos internal structs in favor of wider use of struct drm_encoder.
> >
> > Structs exynos_drm_display and exynos_drm_encoder were doing exactly what
> > struct drm_encoder does so remove them makes the code cleaner, easier
> > to understand and less error prone.
> >
> > Please review,
> >
> >        Gustavo
> >
> > ---
> > v2:  - check ret value of hdmi_create_connector()
> >      - set dp->dpms_mode after enable/disable
> 
> I don't see patch v2 10/11 and 11/11 in my mailbox. Did you miss them?

Hmm, yeah. I've used 000* to send my patches, which excluded 10 and 11.
I'll append them here.

	Gustavo

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

* [PATCH v2 10/11] drm/exynos: fold encoder setup into exynos_drm_load()
  2015-08-05 23:24 ` [PATCH v2 09/11] drm/exynos: remove exynos_drm_create_enc_conn() Gustavo Padovan
@ 2015-08-06 13:31   ` Gustavo Padovan
  2015-08-06 13:31     ` [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer Gustavo Padovan
  0 siblings, 1 reply; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-06 13:31 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

As we are removing the exynos encoder move the encoder setup operation
directly inside the exynos_drm_load()

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c     | 12 ++++++++++--
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 13 -------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.h |  1 -
 3 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index f1d6966..105f10e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -41,7 +41,9 @@
 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 {
 	struct exynos_drm_private *private;
-	int ret;
+	struct drm_encoder *encoder;
+	unsigned int clone_mask;
+	int cnt, ret;
 
 	private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
 	if (!private)
@@ -67,7 +69,13 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 	exynos_drm_mode_config_init(dev);
 
 	/* setup possible_clones. */
-	exynos_drm_encoder_setup(dev);
+	cnt = 0;
+	clone_mask = 0;
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+		clone_mask |= (1 << (cnt++));
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+		encoder->possible_clones = clone_mask;
 
 	platform_set_drvdata(dev->platformdev, dev);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 4ed360b..d45a5c5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -78,19 +78,6 @@ static struct drm_encoder_funcs exynos_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
 
-void exynos_drm_encoder_setup(struct drm_device *dev)
-{
-	struct drm_encoder *encoder;
-	unsigned int clone_mask = 0;
-	int cnt = 0;
-
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		clone_mask |= (1 << (cnt++));
-
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		encoder->possible_clones = clone_mask;
-}
-
 int exynos_drm_encoder_create(struct drm_device *dev,
 			      struct exynos_drm_encoder *exynos_encoder,
 			      enum exynos_drm_output_type type)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
index e998b82..6610dee 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
@@ -16,7 +16,6 @@
 
 #include "exynos_drm_drv.h"
 
-void exynos_drm_encoder_setup(struct drm_device *dev);
 int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
 			      *encoder, enum exynos_drm_output_type type);
 
-- 
2.1.0

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

* [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-06 13:31   ` [PATCH v2 10/11] drm/exynos: fold encoder setup into exynos_drm_load() Gustavo Padovan
@ 2015-08-06 13:31     ` Gustavo Padovan
  2015-08-07 11:50       ` Inki Dae
  2015-08-15 15:14       ` [PATCH -v3 " Gustavo Padovan
  0 siblings, 2 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-06 13:31 UTC (permalink / raw)
  To: linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
only a drm_encoder member and the internal exynos_drm_encoders ops that
was directly mapped to the drm_encoder helper funcs.

So now exynos DRM uses struct drm_encoder directly, this removes
completely the struct exynos_drm_encoder.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/Makefile             |   7 +-
 drivers/gpu/drm/exynos/exynos7_drm_decon.c  |   2 +-
 drivers/gpu/drm/exynos/exynos_dp_core.c     |  68 ++++++++++++------
 drivers/gpu/drm/exynos/exynos_dp_core.h     |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c    |   1 -
 drivers/gpu/drm/exynos/exynos_drm_crtc.c    |   1 -
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     |  51 ++++++++------
 drivers/gpu/drm/exynos/exynos_drm_drv.c     |   1 -
 drivers/gpu/drm/exynos/exynos_drm_drv.h     |  47 ++-----------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     |  80 +++++++++++----------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 105 ----------------------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.h |  22 ------
 drivers/gpu/drm/exynos/exynos_drm_fimd.c    |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c    |  71 ++++++++++++++-----
 drivers/gpu/drm/exynos/exynos_hdmi.c        |  85 +++++++++++++---------
 15 files changed, 236 insertions(+), 309 deletions(-)
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.h

diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 7de0b10..61c2906 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -3,10 +3,9 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
-exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
-		exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
-		exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
-		exynos_drm_plane.o exynos_drm_dmabuf.o
+exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
+		exynos_drm_fb.o exynos_drm_buf.o exynos_drm_gem.o \
+		exynos_drm_core.o exynos_drm_plane.o exynos_drm_dmabuf.o
 
 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index e1a2ce7..0792654 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -61,7 +61,7 @@ struct decon_context {
 	atomic_t			wait_vsync_event;
 
 	struct exynos_drm_panel_info panel;
-	struct exynos_drm_encoder *encoder;
+	struct drm_encoder *encoder;
 };
 
 static const struct of_device_id decon_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 4d49d25..92864ef 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -32,18 +32,18 @@
 #include <drm/drm_panel.h>
 
 #include "exynos_dp_core.h"
-#include "exynos_drm_encoder.h"
+#include "exynos_drm_crtc.h"
 
 #define ctx_from_connector(c)	container_of(c, struct exynos_dp_device, \
 					connector)
 
 static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
 {
-	return to_exynos_crtc(dp->encoder.base.crtc);
+	return to_exynos_crtc(dp->encoder.crtc);
 }
 
 static inline struct exynos_dp_device *encoder_to_dp(
-						struct exynos_drm_encoder *e)
+						struct drm_encoder *e)
 {
 	return container_of(e, struct exynos_dp_device, encoder);
 }
@@ -889,7 +889,7 @@ static void exynos_dp_hotplug(struct work_struct *work)
 		drm_helper_hpd_irq_event(dp->drm_dev);
 }
 
-static void exynos_dp_commit(struct exynos_drm_encoder *encoder)
+static void exynos_dp_commit(struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	int ret;
@@ -995,7 +995,7 @@ static struct drm_encoder *exynos_dp_best_encoder(
 {
 	struct exynos_dp_device *dp = ctx_from_connector(connector);
 
-	return &dp->encoder.base;
+	return &dp->encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
@@ -1020,10 +1020,9 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 	return 0;
 }
 
-static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
+static int exynos_dp_create_connector(struct drm_encoder *encoder)
 {
-	struct exynos_dp_device *dp = encoder_to_dp(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct drm_connector *connector = &dp->connector;
 	int ret;
 
@@ -1053,7 +1052,20 @@ static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
 	return ret;
 }
 
-static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
+static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_dp_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void exynos_dp_enable(struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
@@ -1078,7 +1090,7 @@ static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
 	exynos_dp_commit(&dp->encoder);
 }
 
-static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
+static void exynos_dp_disable(struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
@@ -1107,11 +1119,17 @@ static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
 	}
 }
 
-static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
+static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
+	.mode_fixup = exynos_dp_mode_fixup,
+	.mode_set = exynos_dp_mode_set,
 	.enable = exynos_dp_enable,
 	.disable = exynos_dp_disable,
 };
 
+static struct drm_encoder_funcs exynos_dp_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 {
 	struct device_node *dp_node = dev->of_node;
@@ -1188,10 +1206,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm_dev = data;
-	struct exynos_drm_encoder *exynos_encoder = &dp->encoder;
+	struct drm_encoder *encoder = &dp->encoder;
 	struct resource *res;
 	unsigned int irq_flags;
-	int ret = 0;
+	int pipe, ret = 0;
 
 	dp->dev = &pdev->dev;
 	dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1281,17 +1299,24 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 
 	dp->drm_dev = drm_dev;
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
+	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_LCD);
+	if (pipe < 0)
+		return pipe;
+
+	encoder->possible_crtcs = 1 << pipe;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
 
-	ret = exynos_dp_create_connector(exynos_encoder);
+	ret = exynos_dp_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
@@ -1322,7 +1347,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (!dp)
 		return -ENOMEM;
 
-	dp->encoder.ops = &exynos_dp_encoder_ops;
 	platform_set_drvdata(pdev, dp);
 
 	panel_node = of_parse_phandle(dev->of_node, "panel", 0);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index f8cc202..e413b6f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -147,7 +147,7 @@ struct link_train {
 };
 
 struct exynos_dp_device {
-	struct exynos_drm_encoder encoder;
+	struct drm_encoder	encoder;
 	struct device		*dev;
 	struct drm_device	*drm_dev;
 	struct drm_connector	connector;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 1f38a44..c68a6a2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -15,7 +15,6 @@
 #include <drm/drmP.h>
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_fbdev.h"
 
 static LIST_HEAD(exynos_drm_subdrv_list);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 2715c2a..b9b0e9c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -19,7 +19,6 @@
 
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_plane.h"
 
 static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 6850ce5..0476260 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -20,11 +20,10 @@
 #include <video/of_videomode.h>
 #include <video/videomode.h>
 
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_crtc.h"
 
 struct exynos_dpi {
-	struct exynos_drm_encoder encoder;
+	struct drm_encoder encoder;
 	struct device *dev;
 	struct device_node *panel_node;
 
@@ -36,7 +35,7 @@ struct exynos_dpi {
 
 #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
 
-static inline struct exynos_dpi *encoder_to_dpi(struct exynos_drm_encoder *e)
+static inline struct exynos_dpi *encoder_to_dpi(struct drm_encoder *e)
 {
 	return container_of(e, struct exynos_dpi, encoder);
 }
@@ -98,7 +97,7 @@ exynos_dpi_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dpi *ctx = connector_to_dpi(connector);
 
-	return &ctx->encoder.base;
+	return &ctx->encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
@@ -106,11 +105,9 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
 	.best_encoder = exynos_dpi_best_encoder,
 };
 
-static int exynos_dpi_create_connector(
-				struct exynos_drm_encoder *exynos_encoder)
+static int exynos_dpi_create_connector(struct drm_encoder *encoder)
 {
-	struct exynos_dpi *ctx = encoder_to_dpi(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 	struct drm_connector *connector = &ctx->connector;
 	int ret;
 
@@ -131,7 +128,7 @@ static int exynos_dpi_create_connector(
 	return 0;
 }
 
-static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
+static void exynos_dpi_enable(struct drm_encoder *encoder)
 {
 	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
@@ -141,7 +138,7 @@ static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
 	}
 }
 
-static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
+static void exynos_dpi_disable(struct drm_encoder *encoder)
 {
 	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
@@ -151,11 +148,15 @@ static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
 	}
 }
 
-static struct exynos_drm_encoder_ops exynos_dpi_encoder_ops = {
+static struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = {
 	.enable = exynos_dpi_enable,
 	.disable = exynos_dpi_disable,
 };
 
+static struct drm_encoder_funcs exynos_dpi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 /* of_* functions will be removed after merge of of_graph patches */
 static struct device_node *
 of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
@@ -280,29 +281,34 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
 	return 0;
 }
 
-int exynos_dpi_bind(struct drm_device *dev,
-		    struct exynos_drm_encoder *exynos_encoder)
+int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder)
 {
 	int ret;
 
-	ret = exynos_drm_encoder_create(dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
+	ret = exynos_drm_crtc_get_pipe_from_type(dev, EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret < 0)
 		return ret;
-	}
 
-	ret = exynos_dpi_create_connector(exynos_encoder);
+	encoder->possible_crtcs = 1 << ret;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(dev, encoder, &exynos_dpi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_dpi_encoder_helper_funcs);
+
+	ret = exynos_dpi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
 	return 0;
 }
 
-struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
+struct drm_encoder *exynos_dpi_probe(struct device *dev)
 {
 	struct exynos_dpi *ctx;
 	int ret;
@@ -311,7 +317,6 @@ struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
 	if (!ctx)
 		return ERR_PTR(-ENOMEM);
 
-	ctx->encoder.ops = &exynos_dpi_encoder_ops;
 	ctx->dev = dev;
 
 	ret = exynos_dpi_parse_dt(ctx);
@@ -329,7 +334,7 @@ struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
 	return &ctx->encoder;
 }
 
-int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
+int exynos_dpi_remove(struct drm_encoder *encoder)
 {
 	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 105f10e..6675e76 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -21,7 +21,6 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a4977be..6b8a30f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -22,7 +22,6 @@
 #define MAX_PLANE	5
 #define MAX_FB_BUFFER	4
 
-#define to_exynos_encoder(x)	container_of(x, struct exynos_drm_encoder, base)
 #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
 #define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)
 
@@ -78,40 +77,6 @@ struct exynos_drm_plane {
 };
 
 /*
- * Exynos DRM Encoder Structure.
- *	- this structure is common to analog tv, digital tv and lcd panel.
- *
- * @mode_fixup: fix mode data comparing to hw specific display mode.
- * @mode_set: convert drm_display_mode to hw specific display mode and
- *	      would be called by encoder->mode_set().
- * @enable: display device on.
- * @disable: display device off.
- */
-struct exynos_drm_encoder;
-struct exynos_drm_encoder_ops {
-	void (*mode_fixup)(struct exynos_drm_encoder *encoder,
-				struct drm_connector *connector,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode);
-	void (*mode_set)(struct exynos_drm_encoder *encoder,
-				struct drm_display_mode *mode);
-	void (*enable)(struct exynos_drm_encoder *encoder);
-	void (*disable)(struct exynos_drm_encoder *encoder);
-};
-
-/*
- * exynos specific encoder structure.
- *
- * @drm_encoder: encoder object.
- * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
- * @ops: pointer to callbacks for exynos drm specific functionality
- */
-struct exynos_drm_encoder {
-	struct drm_encoder		base;
-	struct exynos_drm_encoder_ops	*ops;
-};
-
-/*
  * Exynos drm crtc ops
  *
  * @enable: enable the device
@@ -255,18 +220,18 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
 
 #ifdef CONFIG_DRM_EXYNOS_DPI
-struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev);
-int exynos_dpi_remove(struct exynos_drm_encoder *encoder);
-int exynos_dpi_bind(struct drm_device *dev, struct exynos_drm_encoder *encoder);
+struct drm_encoder *exynos_dpi_probe(struct device *dev);
+int exynos_dpi_remove(struct drm_encoder *encoder);
+int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder);
 #else
-static inline struct exynos_drm_encoder *
+static inline struct drm_encoder *
 exynos_dpi_probe(struct device *dev) { return NULL; }
-static inline int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
+static inline int exynos_dpi_remove(struct drm_encoder *encoder)
 {
 	return 0;
 }
 static inline int exynos_dpi_bind(struct drm_device *dev,
-				  struct exynos_drm_encoder *encoder)
+				  struct drm_encoder *encoder)
 {
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index d791ad4..a87d030 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -30,7 +30,6 @@
 #include <video/videomode.h>
 
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_drv.h"
 
 /* returns true iff both arguments logically differs */
@@ -260,7 +259,7 @@ struct exynos_dsi_driver_data {
 };
 
 struct exynos_dsi {
-	struct exynos_drm_encoder encoder;
+	struct drm_encoder encoder;
 	struct mipi_dsi_host dsi_host;
 	struct drm_connector connector;
 	struct device_node *panel_node;
@@ -296,7 +295,7 @@ struct exynos_dsi {
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct exynos_drm_encoder *e)
+static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
 {
 	return container_of(e, struct exynos_dsi, encoder);
 }
@@ -1273,7 +1272,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
 {
 	struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
-	struct drm_encoder *encoder = &dsi->encoder.base;
+	struct drm_encoder *encoder = &dsi->encoder;
 
 	if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
 		exynos_drm_crtc_te_handler(encoder->crtc);
@@ -1519,7 +1518,7 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
 		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
 }
 
-static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
+static void exynos_dsi_enable(struct drm_encoder *encoder)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	int ret;
@@ -1555,7 +1554,7 @@ static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 }
 
-static void exynos_dsi_disable(struct exynos_drm_encoder *encoder)
+static void exynos_dsi_disable(struct drm_encoder *encoder)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 
@@ -1583,7 +1582,7 @@ exynos_dsi_detect(struct drm_connector *connector, bool force)
 		if (dsi->panel)
 			drm_panel_attach(dsi->panel, &dsi->connector);
 	} else if (!dsi->panel_node) {
-		struct exynos_drm_encoder *encoder;
+		struct drm_encoder *encoder;
 
 		encoder = platform_get_drvdata(to_platform_device(dsi->dev));
 		exynos_dsi_disable(encoder);
@@ -1629,7 +1628,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dsi *dsi = connector_to_dsi(connector);
 
-	return &dsi->encoder.base;
+	return &dsi->encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
@@ -1637,11 +1636,9 @@ static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
 	.best_encoder = exynos_dsi_best_encoder,
 };
 
-static int exynos_dsi_create_connector(
-				struct exynos_drm_encoder *exynos_encoder)
+static int exynos_dsi_create_connector(struct drm_encoder *encoder)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct drm_connector *connector = &dsi->connector;
 	int ret;
 
@@ -1662,28 +1659,34 @@ static int exynos_dsi_create_connector(
 	return 0;
 }
 
-static void exynos_dsi_mode_set(struct exynos_drm_encoder *encoder,
-			 struct drm_display_mode *mode)
+static void exynos_dsi_mode_set(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct videomode *vm = &dsi->vm;
-
-	vm->hactive = mode->hdisplay;
-	vm->vactive = mode->vdisplay;
-	vm->vfront_porch = mode->vsync_start - mode->vdisplay;
-	vm->vback_porch = mode->vtotal - mode->vsync_end;
-	vm->vsync_len = mode->vsync_end - mode->vsync_start;
-	vm->hfront_porch = mode->hsync_start - mode->hdisplay;
-	vm->hback_porch = mode->htotal - mode->hsync_end;
-	vm->hsync_len = mode->hsync_end - mode->hsync_start;
+	struct drm_display_mode *m = adjusted_mode;
+
+	vm->hactive = m->hdisplay;
+	vm->vactive = m->vdisplay;
+	vm->vfront_porch = m->vsync_start - m->vdisplay;
+	vm->vback_porch = m->vtotal - m->vsync_end;
+	vm->vsync_len = m->vsync_end - m->vsync_start;
+	vm->hfront_porch = m->hsync_start - m->hdisplay;
+	vm->hback_porch = m->htotal - m->hsync_end;
+	vm->hsync_len = m->hsync_end - m->hsync_start;
 }
 
-static struct exynos_drm_encoder_ops exynos_dsi_encoder_ops = {
+static struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
 	.mode_set = exynos_dsi_mode_set,
 	.enable = exynos_dsi_enable,
 	.disable = exynos_dsi_disable,
 };
 
+static struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
 
 /* of_* functions will be removed after merge of of_graph patches */
@@ -1804,23 +1807,30 @@ end:
 static int exynos_dsi_bind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_encoder *exynos_encoder = dev_get_drvdata(dev);
-	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
+	struct drm_encoder *encoder = dev_get_drvdata(dev);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct drm_device *drm_dev = data;
 	struct drm_bridge *bridge;
 	int ret;
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
+	ret = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret < 0)
 		return ret;
-	}
 
-	ret = exynos_dsi_create_connector(exynos_encoder);
+	encoder->possible_crtcs = 1 << ret;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
+
+	ret = exynos_dsi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
@@ -1835,7 +1845,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 static void exynos_dsi_unbind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
+	struct drm_encoder *encoder = dev_get_drvdata(dev);
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 
 	exynos_dsi_disable(encoder);
@@ -1859,8 +1869,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	dsi->encoder.ops = &exynos_dsi_encoder_ops;
-
 	/* To be checked as invalid one */
 	dsi->te_gpio = -ENOENT;
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
deleted file mode 100644
index d45a5c5..0000000
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* exynos_drm_encoder.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Authors:
- *	Inki Dae <inki.dae@samsung.com>
- *	Joonyoung Shim <jy0922.shim@samsung.com>
- *	Seung-Woo Kim <sw0312.kim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-
-#include "exynos_drm_drv.h"
-#include "exynos_drm_encoder.h"
-#include "exynos_drm_crtc.h"
-
-static bool
-exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
-			       const struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct drm_connector *connector;
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->encoder != encoder)
-			continue;
-
-		if (exynos_encoder->ops->mode_fixup)
-			exynos_encoder->ops->mode_fixup(exynos_encoder,
-							connector, mode,
-							adjusted_mode);
-	}
-
-	return true;
-}
-
-static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
-					 struct drm_display_mode *mode,
-					 struct drm_display_mode *adjusted_mode)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	if (exynos_encoder->ops->mode_set)
-		exynos_encoder->ops->mode_set(exynos_encoder, adjusted_mode);
-}
-
-static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	if (exynos_encoder->ops->enable)
-		exynos_encoder->ops->enable(exynos_encoder);
-}
-
-static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	if (exynos_encoder->ops->disable)
-		exynos_encoder->ops->disable(exynos_encoder);
-}
-
-static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
-	.mode_fixup	= exynos_drm_encoder_mode_fixup,
-	.mode_set	= exynos_drm_encoder_mode_set,
-	.enable		= exynos_drm_encoder_enable,
-	.disable	= exynos_drm_encoder_disable,
-};
-
-static struct drm_encoder_funcs exynos_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-int exynos_drm_encoder_create(struct drm_device *dev,
-			      struct exynos_drm_encoder *exynos_encoder,
-			      enum exynos_drm_output_type type)
-{
-	struct drm_encoder *encoder;
-	int pipe;
-
-	pipe = exynos_drm_crtc_get_pipe_from_type(dev, type);
-	if (pipe < 0)
-		return pipe;
-
-	encoder = &exynos_encoder->base;
-	encoder->possible_crtcs = 1 << pipe;
-
-	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
-	drm_encoder_init(dev, encoder, &exynos_encoder_funcs,
-			DRM_MODE_ENCODER_TMDS);
-
-	drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs);
-
-	DRM_DEBUG_KMS("encoder has been created\n");
-
-	return 0;
-}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
deleted file mode 100644
index 6610dee..0000000
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Authors:
- *	Inki Dae <inki.dae@samsung.com>
- *	Joonyoung Shim <jy0922.shim@samsung.com>
- *	Seung-Woo Kim <sw0312.kim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef _EXYNOS_DRM_ENCODER_H_
-#define _EXYNOS_DRM_ENCODER_H_
-
-#include "exynos_drm_drv.h"
-
-int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
-			      *encoder, enum exynos_drm_output_type type);
-
-#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 6c0d3de..5def6bc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -169,7 +169,7 @@ struct fimd_context {
 
 	struct exynos_drm_panel_info panel;
 	struct fimd_driver_data *driver_data;
-	struct exynos_drm_encoder *encoder;
+	struct drm_encoder *encoder;
 };
 
 static const struct of_device_id fimd_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 9b64c77..581af35 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -25,7 +25,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_plane.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_vidi.h"
 
 /* vidi has totally three virtual windows. */
@@ -35,7 +34,7 @@
 					connector)
 
 struct vidi_context {
-	struct exynos_drm_encoder	encoder;
+	struct drm_encoder		encoder;
 	struct platform_device		*pdev;
 	struct drm_device		*drm_dev;
 	struct exynos_drm_crtc		*crtc;
@@ -54,7 +53,7 @@ struct vidi_context {
 	int				pipe;
 };
 
-static inline struct vidi_context *encoder_to_vidi(struct exynos_drm_encoder *e)
+static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e)
 {
 	return container_of(e, struct vidi_context, encoder);
 }
@@ -358,7 +357,7 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
 {
 	struct vidi_context *ctx = ctx_from_connector(connector);
 
-	return &ctx->encoder.base;
+	return &ctx->encoder;
 }
 
 static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
@@ -366,10 +365,9 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
 	.best_encoder = vidi_best_encoder,
 };
 
-static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
+static int vidi_create_connector(struct drm_encoder *encoder)
 {
-	struct vidi_context *ctx = encoder_to_vidi(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct vidi_context *ctx = encoder_to_vidi(encoder);
 	struct drm_connector *connector = &ctx->connector;
 	int ret;
 
@@ -389,15 +387,47 @@ static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 	return 0;
 }
 
+static bool exynos_vidi_mode_fixup(struct drm_encoder *encoder,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_vidi_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void exynos_vidi_enable(struct drm_encoder *encoder)
+{
+}
+
+static void exynos_vidi_disable(struct drm_encoder *encoder)
+{
+}
+
+static struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs = {
+	.mode_fixup = exynos_vidi_mode_fixup,
+	.mode_set = exynos_vidi_mode_set,
+	.enable = exynos_vidi_enable,
+	.disable = exynos_vidi_disable,
+};
+
+static struct drm_encoder_funcs exynos_vidi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static int vidi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct vidi_context *ctx = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
-	struct exynos_drm_encoder *exynos_encoder = &ctx->encoder;
+	struct drm_encoder *encoder = &ctx->encoder;
 	struct exynos_drm_plane *exynos_plane;
 	enum drm_plane_type type;
 	unsigned int zpos;
-	int ret;
+	int pipe, ret;
 
 	vidi_ctx_initialize(ctx, drm_dev);
 
@@ -419,17 +449,24 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 	}
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_VIDI);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
+	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_VIDI);
+	if (pipe < 0)
+		return pipe;
+
+	encoder->possible_crtcs = 1 << pipe;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs);
 
-	ret = vidi_create_connector(exynos_encoder);
+	ret = vidi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 148e42f..932f7fa 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -44,7 +44,6 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_mixer.h"
 
 #include <linux/gpio.h>
@@ -88,7 +87,7 @@ struct hdmi_resources {
 };
 
 struct hdmi_context {
-	struct exynos_drm_encoder	encoder;
+	struct drm_encoder		encoder;
 	struct device			*dev;
 	struct drm_device		*drm_dev;
 	struct drm_connector		connector;
@@ -116,7 +115,7 @@ struct hdmi_context {
 	struct regmap			*pmureg;
 };
 
-static inline struct hdmi_context *encoder_to_hdmi(struct exynos_drm_encoder *e)
+static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
 {
 	return container_of(e, struct hdmi_context, encoder);
 }
@@ -1032,7 +1031,7 @@ static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
 {
 	struct hdmi_context *hdata = ctx_from_connector(connector);
 
-	return &hdata->encoder.base;
+	return &hdata->encoder;
 }
 
 static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
@@ -1041,9 +1040,9 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 	.best_encoder = hdmi_best_encoder,
 };
 
-static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
+static int hdmi_create_connector(struct drm_encoder *encoder)
 {
-	struct hdmi_context *hdata = encoder_to_hdmi(exynos_encoder);
+	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct drm_connector *connector = &hdata->connector;
 	int ret;
 
@@ -1059,28 +1058,35 @@ static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 
 	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 	drm_connector_register(connector);
-	drm_mode_connector_attach_encoder(connector, &exynos_encoder->base);
+	drm_mode_connector_attach_encoder(connector, encoder);
 
 	return 0;
 }
 
-static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
-				struct drm_connector *connector,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+static bool hdmi_mode_fixup(struct drm_encoder *encoder,
+			    const struct drm_display_mode *mode,
+			    struct drm_display_mode *adjusted_mode)
 {
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector;
 	struct drm_display_mode *m;
 	int mode_ok;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder == encoder)
+			break;
+	}
+
+	if (connector->encoder != encoder)
+		return true;
+
 	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
 
 	/* just return if user desired mode exists. */
 	if (mode_ok == MODE_OK)
-		return;
+		return true;
 
 	/*
 	 * otherwise, find the most suitable mode among modes and change it
@@ -1100,6 +1106,8 @@ static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
 			break;
 		}
 	}
+
+	return true;
 }
 
 static void hdmi_set_acr(u32 freq, u8 *acr)
@@ -1697,22 +1705,23 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
 	hdmi_regs_dump(hdata, "start");
 }
 
-static void hdmi_mode_set(struct exynos_drm_encoder *encoder,
-			struct drm_display_mode *mode)
+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 = mode;
+	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, mode);
+	drm_mode_copy(&hdata->current_mode, m);
 	hdata->cea_video_id = drm_match_cea_mode(mode);
 }
 
-static void hdmi_enable(struct exynos_drm_encoder *encoder)
+static void hdmi_enable(struct drm_encoder *encoder)
 {
 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct hdmi_resources *res = &hdata->res;
@@ -1738,11 +1747,11 @@ static void hdmi_enable(struct exynos_drm_encoder *encoder)
 	hdmi_conf_apply(hdata);
 }
 
-static void hdmi_disable(struct exynos_drm_encoder *encoder)
+static void hdmi_disable(struct drm_encoder *encoder)
 {
 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct hdmi_resources *res = &hdata->res;
-	struct drm_crtc *crtc = hdata->encoder.base.crtc;
+	struct drm_crtc *crtc = encoder->crtc;
 	const struct drm_crtc_helper_funcs *funcs = NULL;
 
 	if (!hdata->powered)
@@ -1783,13 +1792,17 @@ static void hdmi_disable(struct exynos_drm_encoder *encoder)
 	hdata->powered = false;
 }
 
-static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
+static 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,
 };
 
+static struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static void hdmi_hotplug_work_func(struct work_struct *work)
 {
 	struct hdmi_context *hdata;
@@ -1917,22 +1930,29 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct drm_device *drm_dev = data;
 	struct hdmi_context *hdata = dev_get_drvdata(dev);
-	struct exynos_drm_encoder *exynos_encoder = &hdata->encoder;
-	int ret;
+	struct drm_encoder *encoder = &hdata->encoder;
+	int ret, pipe;
 
 	hdata->drm_dev = drm_dev;
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_HDMI);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
+	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_HDMI);
+	if (pipe < 0)
+		return pipe;
+
+	encoder->possible_crtcs = 1 << pipe;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
 
-	ret = hdmi_create_connector(exynos_encoder);
+	ret = hdmi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
@@ -1985,7 +2005,6 @@ static int hdmi_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	hdata->drv_data = match->data;
-	hdata->encoder.ops = &hdmi_encoder_ops;
 
 	platform_set_drvdata(pdev, hdata);
 
-- 
2.1.0

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

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-06 13:31     ` [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer Gustavo Padovan
@ 2015-08-07 11:50       ` Inki Dae
  2015-08-07 12:28         ` Daniel Vetter
  2015-08-11  0:38         ` Gustavo Padovan
  2015-08-15 15:14       ` [PATCH -v3 " Gustavo Padovan
  1 sibling, 2 replies; 27+ messages in thread
From: Inki Dae @ 2015-08-07 11:50 UTC (permalink / raw)
  To: Gustavo Padovan, linux-samsung-soc; +Cc: tjakobi, Gustavo Padovan, dri-devel

Hi Gustavo,

On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
> only a drm_encoder member and the internal exynos_drm_encoders ops that
> was directly mapped to the drm_encoder helper funcs.
> 
> So now exynos DRM uses struct drm_encoder directly, this removes
> completely the struct exynos_drm_encoder.
> 

Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
is applied. Below is the booting logs,
[    1.171318] console [ttySAC2] enabled
[    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
base_baud = 0) is a S3C6400/10
[    1.185545] [drm] Initialized drm 1.1.0 20060810
[    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
fimd_component_ops)
[    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
exynos_dsi_component_ops)
[    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    1.214313] [drm] No driver support for vblank timestamp query.
[    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0

Booting is locked up here. This patch looks good to me so I tried to
find why locked up and I found the booting is locked up as soon as
console_lock function is called. Can you and other guys look into this
issue?

Thanks,
Inki Dae

> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>  drivers/gpu/drm/exynos/Makefile             |   7 +-
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c  |   2 +-
>  drivers/gpu/drm/exynos/exynos_dp_core.c     |  68 ++++++++++++------
>  drivers/gpu/drm/exynos/exynos_dp_core.h     |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_core.c    |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_crtc.c    |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_dpi.c     |  51 ++++++++------
>  drivers/gpu/drm/exynos/exynos_drm_drv.c     |   1 -
>  drivers/gpu/drm/exynos/exynos_drm_drv.h     |  47 ++-----------
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c     |  80 +++++++++++----------
>  drivers/gpu/drm/exynos/exynos_drm_encoder.c | 105 ----------------------------
>  drivers/gpu/drm/exynos/exynos_drm_encoder.h |  22 ------
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c    |   2 +-
>  drivers/gpu/drm/exynos/exynos_drm_vidi.c    |  71 ++++++++++++++-----
>  drivers/gpu/drm/exynos/exynos_hdmi.c        |  85 +++++++++++++---------
>  15 files changed, 236 insertions(+), 309 deletions(-)
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.c
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.h
> 
> diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
> index 7de0b10..61c2906 100644
> --- a/drivers/gpu/drm/exynos/Makefile
> +++ b/drivers/gpu/drm/exynos/Makefile
> @@ -3,10 +3,9 @@
>  # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
>  
>  ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
> -exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
> -		exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
> -		exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
> -		exynos_drm_plane.o exynos_drm_dmabuf.o
> +exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
> +		exynos_drm_fb.o exynos_drm_buf.o exynos_drm_gem.o \
> +		exynos_drm_core.o exynos_drm_plane.o exynos_drm_dmabuf.o
>  
>  exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
>  exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
> diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> index e1a2ce7..0792654 100644
> --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
> @@ -61,7 +61,7 @@ struct decon_context {
>  	atomic_t			wait_vsync_event;
>  
>  	struct exynos_drm_panel_info panel;
> -	struct exynos_drm_encoder *encoder;
> +	struct drm_encoder *encoder;
>  };
>  
>  static const struct of_device_id decon_driver_dt_match[] = {
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
> index 4d49d25..92864ef 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
> @@ -32,18 +32,18 @@
>  #include <drm/drm_panel.h>
>  
>  #include "exynos_dp_core.h"
> -#include "exynos_drm_encoder.h"
> +#include "exynos_drm_crtc.h"
>  
>  #define ctx_from_connector(c)	container_of(c, struct exynos_dp_device, \
>  					connector)
>  
>  static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
>  {
> -	return to_exynos_crtc(dp->encoder.base.crtc);
> +	return to_exynos_crtc(dp->encoder.crtc);
>  }
>  
>  static inline struct exynos_dp_device *encoder_to_dp(
> -						struct exynos_drm_encoder *e)
> +						struct drm_encoder *e)
>  {
>  	return container_of(e, struct exynos_dp_device, encoder);
>  }
> @@ -889,7 +889,7 @@ static void exynos_dp_hotplug(struct work_struct *work)
>  		drm_helper_hpd_irq_event(dp->drm_dev);
>  }
>  
> -static void exynos_dp_commit(struct exynos_drm_encoder *encoder)
> +static void exynos_dp_commit(struct drm_encoder *encoder)
>  {
>  	struct exynos_dp_device *dp = encoder_to_dp(encoder);
>  	int ret;
> @@ -995,7 +995,7 @@ static struct drm_encoder *exynos_dp_best_encoder(
>  {
>  	struct exynos_dp_device *dp = ctx_from_connector(connector);
>  
> -	return &dp->encoder.base;
> +	return &dp->encoder;
>  }
>  
>  static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
> @@ -1020,10 +1020,9 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
>  	return 0;
>  }
>  
> -static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
> +static int exynos_dp_create_connector(struct drm_encoder *encoder)
>  {
> -	struct exynos_dp_device *dp = encoder_to_dp(exynos_encoder);
> -	struct drm_encoder *encoder = &exynos_encoder->base;
> +	struct exynos_dp_device *dp = encoder_to_dp(encoder);
>  	struct drm_connector *connector = &dp->connector;
>  	int ret;
>  
> @@ -1053,7 +1052,20 @@ static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
>  	return ret;
>  }
>  
> -static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
> +static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
> +				 const struct drm_display_mode *mode,
> +				 struct drm_display_mode *adjusted_mode)
> +{
> +	return true;
> +}
> +
> +static void exynos_dp_mode_set(struct drm_encoder *encoder,
> +			       struct drm_display_mode *mode,
> +			       struct drm_display_mode *adjusted_mode)
> +{
> +}
> +
> +static void exynos_dp_enable(struct drm_encoder *encoder)
>  {
>  	struct exynos_dp_device *dp = encoder_to_dp(encoder);
>  	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
> @@ -1078,7 +1090,7 @@ static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
>  	exynos_dp_commit(&dp->encoder);
>  }
>  
> -static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
> +static void exynos_dp_disable(struct drm_encoder *encoder)
>  {
>  	struct exynos_dp_device *dp = encoder_to_dp(encoder);
>  	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
> @@ -1107,11 +1119,17 @@ static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
>  	}
>  }
>  
> -static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
> +static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
> +	.mode_fixup = exynos_dp_mode_fixup,
> +	.mode_set = exynos_dp_mode_set,
>  	.enable = exynos_dp_enable,
>  	.disable = exynos_dp_disable,
>  };
>  
> +static struct drm_encoder_funcs exynos_dp_encoder_funcs = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
>  static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
>  {
>  	struct device_node *dp_node = dev->of_node;
> @@ -1188,10 +1206,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
>  	struct exynos_dp_device *dp = dev_get_drvdata(dev);
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct drm_device *drm_dev = data;
> -	struct exynos_drm_encoder *exynos_encoder = &dp->encoder;
> +	struct drm_encoder *encoder = &dp->encoder;
>  	struct resource *res;
>  	unsigned int irq_flags;
> -	int ret = 0;
> +	int pipe, ret = 0;
>  
>  	dp->dev = &pdev->dev;
>  	dp->dpms_mode = DRM_MODE_DPMS_OFF;
> @@ -1281,17 +1299,24 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
>  
>  	dp->drm_dev = drm_dev;
>  
> -	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
> -					EXYNOS_DISPLAY_TYPE_LCD);
> -	if (ret) {
> -		DRM_ERROR("failed to create encoder\n");
> -		return ret;
> -	}
> +	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
> +						  EXYNOS_DISPLAY_TYPE_LCD);
> +	if (pipe < 0)
> +		return pipe;
> +
> +	encoder->possible_crtcs = 1 << pipe;
> +
> +	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
> +
> +	drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +
> +	drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
>  
> -	ret = exynos_dp_create_connector(exynos_encoder);
> +	ret = exynos_dp_create_connector(encoder);
>  	if (ret) {
>  		DRM_ERROR("failed to create connector ret = %d\n", ret);
> -		drm_encoder_cleanup(&exynos_encoder->base);
> +		drm_encoder_cleanup(encoder);
>  		return ret;
>  	}
>  
> @@ -1322,7 +1347,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
>  	if (!dp)
>  		return -ENOMEM;
>  
> -	dp->encoder.ops = &exynos_dp_encoder_ops;
>  	platform_set_drvdata(pdev, dp);
>  
>  	panel_node = of_parse_phandle(dev->of_node, "panel", 0);
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
> index f8cc202..e413b6f 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.h
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
> @@ -147,7 +147,7 @@ struct link_train {
>  };
>  
>  struct exynos_dp_device {
> -	struct exynos_drm_encoder encoder;
> +	struct drm_encoder	encoder;
>  	struct device		*dev;
>  	struct drm_device	*drm_dev;
>  	struct drm_connector	connector;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
> index 1f38a44..c68a6a2 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_core.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
> @@ -15,7 +15,6 @@
>  #include <drm/drmP.h>
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_crtc.h"
> -#include "exynos_drm_encoder.h"
>  #include "exynos_drm_fbdev.h"
>  
>  static LIST_HEAD(exynos_drm_subdrv_list);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
> index 2715c2a..b9b0e9c 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
> @@ -19,7 +19,6 @@
>  
>  #include "exynos_drm_crtc.h"
>  #include "exynos_drm_drv.h"
> -#include "exynos_drm_encoder.h"
>  #include "exynos_drm_plane.h"
>  
>  static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> index 6850ce5..0476260 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> @@ -20,11 +20,10 @@
>  #include <video/of_videomode.h>
>  #include <video/videomode.h>
>  
> -#include "exynos_drm_encoder.h"
>  #include "exynos_drm_crtc.h"
>  
>  struct exynos_dpi {
> -	struct exynos_drm_encoder encoder;
> +	struct drm_encoder encoder;
>  	struct device *dev;
>  	struct device_node *panel_node;
>  
> @@ -36,7 +35,7 @@ struct exynos_dpi {
>  
>  #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
>  
> -static inline struct exynos_dpi *encoder_to_dpi(struct exynos_drm_encoder *e)
> +static inline struct exynos_dpi *encoder_to_dpi(struct drm_encoder *e)
>  {
>  	return container_of(e, struct exynos_dpi, encoder);
>  }
> @@ -98,7 +97,7 @@ exynos_dpi_best_encoder(struct drm_connector *connector)
>  {
>  	struct exynos_dpi *ctx = connector_to_dpi(connector);
>  
> -	return &ctx->encoder.base;
> +	return &ctx->encoder;
>  }
>  
>  static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
> @@ -106,11 +105,9 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
>  	.best_encoder = exynos_dpi_best_encoder,
>  };
>  
> -static int exynos_dpi_create_connector(
> -				struct exynos_drm_encoder *exynos_encoder)
> +static int exynos_dpi_create_connector(struct drm_encoder *encoder)
>  {
> -	struct exynos_dpi *ctx = encoder_to_dpi(exynos_encoder);
> -	struct drm_encoder *encoder = &exynos_encoder->base;
> +	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
>  	struct drm_connector *connector = &ctx->connector;
>  	int ret;
>  
> @@ -131,7 +128,7 @@ static int exynos_dpi_create_connector(
>  	return 0;
>  }
>  
> -static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
> +static void exynos_dpi_enable(struct drm_encoder *encoder)
>  {
>  	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
>  
> @@ -141,7 +138,7 @@ static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
>  	}
>  }
>  
> -static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
> +static void exynos_dpi_disable(struct drm_encoder *encoder)
>  {
>  	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
>  
> @@ -151,11 +148,15 @@ static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
>  	}
>  }
>  
> -static struct exynos_drm_encoder_ops exynos_dpi_encoder_ops = {
> +static struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = {
>  	.enable = exynos_dpi_enable,
>  	.disable = exynos_dpi_disable,
>  };
>  
> +static struct drm_encoder_funcs exynos_dpi_encoder_funcs = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
>  /* of_* functions will be removed after merge of of_graph patches */
>  static struct device_node *
>  of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
> @@ -280,29 +281,34 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
>  	return 0;
>  }
>  
> -int exynos_dpi_bind(struct drm_device *dev,
> -		    struct exynos_drm_encoder *exynos_encoder)
> +int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder)
>  {
>  	int ret;
>  
> -	ret = exynos_drm_encoder_create(dev, exynos_encoder,
> -					EXYNOS_DISPLAY_TYPE_LCD);
> -	if (ret) {
> -		DRM_ERROR("failed to create encoder\n");
> +	ret = exynos_drm_crtc_get_pipe_from_type(dev, EXYNOS_DISPLAY_TYPE_LCD);
> +	if (ret < 0)
>  		return ret;
> -	}
>  
> -	ret = exynos_dpi_create_connector(exynos_encoder);
> +	encoder->possible_crtcs = 1 << ret;
> +
> +	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
> +
> +	drm_encoder_init(dev, encoder, &exynos_dpi_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +
> +	drm_encoder_helper_add(encoder, &exynos_dpi_encoder_helper_funcs);
> +
> +	ret = exynos_dpi_create_connector(encoder);
>  	if (ret) {
>  		DRM_ERROR("failed to create connector ret = %d\n", ret);
> -		drm_encoder_cleanup(&exynos_encoder->base);
> +		drm_encoder_cleanup(encoder);
>  		return ret;
>  	}
>  
>  	return 0;
>  }
>  
> -struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
> +struct drm_encoder *exynos_dpi_probe(struct device *dev)
>  {
>  	struct exynos_dpi *ctx;
>  	int ret;
> @@ -311,7 +317,6 @@ struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
>  	if (!ctx)
>  		return ERR_PTR(-ENOMEM);
>  
> -	ctx->encoder.ops = &exynos_dpi_encoder_ops;
>  	ctx->dev = dev;
>  
>  	ret = exynos_dpi_parse_dt(ctx);
> @@ -329,7 +334,7 @@ struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
>  	return &ctx->encoder;
>  }
>  
> -int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
> +int exynos_dpi_remove(struct drm_encoder *encoder)
>  {
>  	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
>  
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 105f10e..6675e76 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -21,7 +21,6 @@
>  
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_crtc.h"
> -#include "exynos_drm_encoder.h"
>  #include "exynos_drm_fbdev.h"
>  #include "exynos_drm_fb.h"
>  #include "exynos_drm_gem.h"
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index a4977be..6b8a30f 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -22,7 +22,6 @@
>  #define MAX_PLANE	5
>  #define MAX_FB_BUFFER	4
>  
> -#define to_exynos_encoder(x)	container_of(x, struct exynos_drm_encoder, base)
>  #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
>  #define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)
>  
> @@ -78,40 +77,6 @@ struct exynos_drm_plane {
>  };
>  
>  /*
> - * Exynos DRM Encoder Structure.
> - *	- this structure is common to analog tv, digital tv and lcd panel.
> - *
> - * @mode_fixup: fix mode data comparing to hw specific display mode.
> - * @mode_set: convert drm_display_mode to hw specific display mode and
> - *	      would be called by encoder->mode_set().
> - * @enable: display device on.
> - * @disable: display device off.
> - */
> -struct exynos_drm_encoder;
> -struct exynos_drm_encoder_ops {
> -	void (*mode_fixup)(struct exynos_drm_encoder *encoder,
> -				struct drm_connector *connector,
> -				const struct drm_display_mode *mode,
> -				struct drm_display_mode *adjusted_mode);
> -	void (*mode_set)(struct exynos_drm_encoder *encoder,
> -				struct drm_display_mode *mode);
> -	void (*enable)(struct exynos_drm_encoder *encoder);
> -	void (*disable)(struct exynos_drm_encoder *encoder);
> -};
> -
> -/*
> - * exynos specific encoder structure.
> - *
> - * @drm_encoder: encoder object.
> - * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
> - * @ops: pointer to callbacks for exynos drm specific functionality
> - */
> -struct exynos_drm_encoder {
> -	struct drm_encoder		base;
> -	struct exynos_drm_encoder_ops	*ops;
> -};
> -
> -/*
>   * Exynos drm crtc ops
>   *
>   * @enable: enable the device
> @@ -255,18 +220,18 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
>  void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
>  
>  #ifdef CONFIG_DRM_EXYNOS_DPI
> -struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev);
> -int exynos_dpi_remove(struct exynos_drm_encoder *encoder);
> -int exynos_dpi_bind(struct drm_device *dev, struct exynos_drm_encoder *encoder);
> +struct drm_encoder *exynos_dpi_probe(struct device *dev);
> +int exynos_dpi_remove(struct drm_encoder *encoder);
> +int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder);
>  #else
> -static inline struct exynos_drm_encoder *
> +static inline struct drm_encoder *
>  exynos_dpi_probe(struct device *dev) { return NULL; }
> -static inline int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
> +static inline int exynos_dpi_remove(struct drm_encoder *encoder)
>  {
>  	return 0;
>  }
>  static inline int exynos_dpi_bind(struct drm_device *dev,
> -				  struct exynos_drm_encoder *encoder)
> +				  struct drm_encoder *encoder)
>  {
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index d791ad4..a87d030 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -30,7 +30,6 @@
>  #include <video/videomode.h>
>  
>  #include "exynos_drm_crtc.h"
> -#include "exynos_drm_encoder.h"
>  #include "exynos_drm_drv.h"
>  
>  /* returns true iff both arguments logically differs */
> @@ -260,7 +259,7 @@ struct exynos_dsi_driver_data {
>  };
>  
>  struct exynos_dsi {
> -	struct exynos_drm_encoder encoder;
> +	struct drm_encoder encoder;
>  	struct mipi_dsi_host dsi_host;
>  	struct drm_connector connector;
>  	struct device_node *panel_node;
> @@ -296,7 +295,7 @@ struct exynos_dsi {
>  #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
>  #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
>  
> -static inline struct exynos_dsi *encoder_to_dsi(struct exynos_drm_encoder *e)
> +static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
>  {
>  	return container_of(e, struct exynos_dsi, encoder);
>  }
> @@ -1273,7 +1272,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
>  static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
>  {
>  	struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
> -	struct drm_encoder *encoder = &dsi->encoder.base;
> +	struct drm_encoder *encoder = &dsi->encoder;
>  
>  	if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
>  		exynos_drm_crtc_te_handler(encoder->crtc);
> @@ -1519,7 +1518,7 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
>  		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
>  }
>  
> -static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
> +static void exynos_dsi_enable(struct drm_encoder *encoder)
>  {
>  	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
>  	int ret;
> @@ -1555,7 +1554,7 @@ static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
>  	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
>  }
>  
> -static void exynos_dsi_disable(struct exynos_drm_encoder *encoder)
> +static void exynos_dsi_disable(struct drm_encoder *encoder)
>  {
>  	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
>  
> @@ -1583,7 +1582,7 @@ exynos_dsi_detect(struct drm_connector *connector, bool force)
>  		if (dsi->panel)
>  			drm_panel_attach(dsi->panel, &dsi->connector);
>  	} else if (!dsi->panel_node) {
> -		struct exynos_drm_encoder *encoder;
> +		struct drm_encoder *encoder;
>  
>  		encoder = platform_get_drvdata(to_platform_device(dsi->dev));
>  		exynos_dsi_disable(encoder);
> @@ -1629,7 +1628,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector)
>  {
>  	struct exynos_dsi *dsi = connector_to_dsi(connector);
>  
> -	return &dsi->encoder.base;
> +	return &dsi->encoder;
>  }
>  
>  static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
> @@ -1637,11 +1636,9 @@ static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
>  	.best_encoder = exynos_dsi_best_encoder,
>  };
>  
> -static int exynos_dsi_create_connector(
> -				struct exynos_drm_encoder *exynos_encoder)
> +static int exynos_dsi_create_connector(struct drm_encoder *encoder)
>  {
> -	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
> -	struct drm_encoder *encoder = &exynos_encoder->base;
> +	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
>  	struct drm_connector *connector = &dsi->connector;
>  	int ret;
>  
> @@ -1662,28 +1659,34 @@ static int exynos_dsi_create_connector(
>  	return 0;
>  }
>  
> -static void exynos_dsi_mode_set(struct exynos_drm_encoder *encoder,
> -			 struct drm_display_mode *mode)
> +static void exynos_dsi_mode_set(struct drm_encoder *encoder,
> +				struct drm_display_mode *mode,
> +				struct drm_display_mode *adjusted_mode)
>  {
>  	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
>  	struct videomode *vm = &dsi->vm;
> -
> -	vm->hactive = mode->hdisplay;
> -	vm->vactive = mode->vdisplay;
> -	vm->vfront_porch = mode->vsync_start - mode->vdisplay;
> -	vm->vback_porch = mode->vtotal - mode->vsync_end;
> -	vm->vsync_len = mode->vsync_end - mode->vsync_start;
> -	vm->hfront_porch = mode->hsync_start - mode->hdisplay;
> -	vm->hback_porch = mode->htotal - mode->hsync_end;
> -	vm->hsync_len = mode->hsync_end - mode->hsync_start;
> +	struct drm_display_mode *m = adjusted_mode;
> +
> +	vm->hactive = m->hdisplay;
> +	vm->vactive = m->vdisplay;
> +	vm->vfront_porch = m->vsync_start - m->vdisplay;
> +	vm->vback_porch = m->vtotal - m->vsync_end;
> +	vm->vsync_len = m->vsync_end - m->vsync_start;
> +	vm->hfront_porch = m->hsync_start - m->hdisplay;
> +	vm->hback_porch = m->htotal - m->hsync_end;
> +	vm->hsync_len = m->hsync_end - m->hsync_start;
>  }
>  
> -static struct exynos_drm_encoder_ops exynos_dsi_encoder_ops = {
> +static struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
>  	.mode_set = exynos_dsi_mode_set,
>  	.enable = exynos_dsi_enable,
>  	.disable = exynos_dsi_disable,
>  };
>  
> +static struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
>  MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
>  
>  /* of_* functions will be removed after merge of of_graph patches */
> @@ -1804,23 +1807,30 @@ end:
>  static int exynos_dsi_bind(struct device *dev, struct device *master,
>  				void *data)
>  {
> -	struct exynos_drm_encoder *exynos_encoder = dev_get_drvdata(dev);
> -	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
> +	struct drm_encoder *encoder = dev_get_drvdata(dev);
> +	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
>  	struct drm_device *drm_dev = data;
>  	struct drm_bridge *bridge;
>  	int ret;
>  
> -	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
> -					EXYNOS_DISPLAY_TYPE_LCD);
> -	if (ret) {
> -		DRM_ERROR("failed to create encoder\n");
> +	ret = exynos_drm_crtc_get_pipe_from_type(drm_dev,
> +						  EXYNOS_DISPLAY_TYPE_LCD);
> +	if (ret < 0)
>  		return ret;
> -	}
>  
> -	ret = exynos_dsi_create_connector(exynos_encoder);
> +	encoder->possible_crtcs = 1 << ret;
> +
> +	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
> +
> +	drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +
> +	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
> +
> +	ret = exynos_dsi_create_connector(encoder);
>  	if (ret) {
>  		DRM_ERROR("failed to create connector ret = %d\n", ret);
> -		drm_encoder_cleanup(&exynos_encoder->base);
> +		drm_encoder_cleanup(encoder);
>  		return ret;
>  	}
>  
> @@ -1835,7 +1845,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
>  static void exynos_dsi_unbind(struct device *dev, struct device *master,
>  				void *data)
>  {
> -	struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
> +	struct drm_encoder *encoder = dev_get_drvdata(dev);
>  	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
>  
>  	exynos_dsi_disable(encoder);
> @@ -1859,8 +1869,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>  	if (!dsi)
>  		return -ENOMEM;
>  
> -	dsi->encoder.ops = &exynos_dsi_encoder_ops;
> -
>  	/* To be checked as invalid one */
>  	dsi->te_gpio = -ENOENT;
>  
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
> deleted file mode 100644
> index d45a5c5..0000000
> --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
> +++ /dev/null
> @@ -1,105 +0,0 @@
> -/* exynos_drm_encoder.c
> - *
> - * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> - * Authors:
> - *	Inki Dae <inki.dae@samsung.com>
> - *	Joonyoung Shim <jy0922.shim@samsung.com>
> - *	Seung-Woo Kim <sw0312.kim@samsung.com>
> - *
> - * This program is free software; you can redistribute  it and/or modify it
> - * under  the terms of  the GNU General  Public License as published by the
> - * Free Software Foundation;  either version 2 of the  License, or (at your
> - * option) any later version.
> - */
> -
> -#include <drm/drmP.h>
> -#include <drm/drm_crtc_helper.h>
> -
> -#include "exynos_drm_drv.h"
> -#include "exynos_drm_encoder.h"
> -#include "exynos_drm_crtc.h"
> -
> -static bool
> -exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
> -			       const struct drm_display_mode *mode,
> -			       struct drm_display_mode *adjusted_mode)
> -{
> -	struct drm_device *dev = encoder->dev;
> -	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
> -	struct drm_connector *connector;
> -
> -	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> -		if (connector->encoder != encoder)
> -			continue;
> -
> -		if (exynos_encoder->ops->mode_fixup)
> -			exynos_encoder->ops->mode_fixup(exynos_encoder,
> -							connector, mode,
> -							adjusted_mode);
> -	}
> -
> -	return true;
> -}
> -
> -static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
> -					 struct drm_display_mode *mode,
> -					 struct drm_display_mode *adjusted_mode)
> -{
> -	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
> -
> -	if (exynos_encoder->ops->mode_set)
> -		exynos_encoder->ops->mode_set(exynos_encoder, adjusted_mode);
> -}
> -
> -static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
> -{
> -	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
> -
> -	if (exynos_encoder->ops->enable)
> -		exynos_encoder->ops->enable(exynos_encoder);
> -}
> -
> -static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
> -{
> -	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
> -
> -	if (exynos_encoder->ops->disable)
> -		exynos_encoder->ops->disable(exynos_encoder);
> -}
> -
> -static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
> -	.mode_fixup	= exynos_drm_encoder_mode_fixup,
> -	.mode_set	= exynos_drm_encoder_mode_set,
> -	.enable		= exynos_drm_encoder_enable,
> -	.disable	= exynos_drm_encoder_disable,
> -};
> -
> -static struct drm_encoder_funcs exynos_encoder_funcs = {
> -	.destroy = drm_encoder_cleanup,
> -};
> -
> -int exynos_drm_encoder_create(struct drm_device *dev,
> -			      struct exynos_drm_encoder *exynos_encoder,
> -			      enum exynos_drm_output_type type)
> -{
> -	struct drm_encoder *encoder;
> -	int pipe;
> -
> -	pipe = exynos_drm_crtc_get_pipe_from_type(dev, type);
> -	if (pipe < 0)
> -		return pipe;
> -
> -	encoder = &exynos_encoder->base;
> -	encoder->possible_crtcs = 1 << pipe;
> -
> -	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
> -
> -	drm_encoder_init(dev, encoder, &exynos_encoder_funcs,
> -			DRM_MODE_ENCODER_TMDS);
> -
> -	drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs);
> -
> -	DRM_DEBUG_KMS("encoder has been created\n");
> -
> -	return 0;
> -}
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
> deleted file mode 100644
> index 6610dee..0000000
> --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -/*
> - * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> - * Authors:
> - *	Inki Dae <inki.dae@samsung.com>
> - *	Joonyoung Shim <jy0922.shim@samsung.com>
> - *	Seung-Woo Kim <sw0312.kim@samsung.com>
> - *
> - * This program is free software; you can redistribute  it and/or modify it
> - * under  the terms of  the GNU General  Public License as published by the
> - * Free Software Foundation;  either version 2 of the  License, or (at your
> - * option) any later version.
> - */
> -
> -#ifndef _EXYNOS_DRM_ENCODER_H_
> -#define _EXYNOS_DRM_ENCODER_H_
> -
> -#include "exynos_drm_drv.h"
> -
> -int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
> -			      *encoder, enum exynos_drm_output_type type);
> -
> -#endif
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 6c0d3de..5def6bc 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -169,7 +169,7 @@ struct fimd_context {
>  
>  	struct exynos_drm_panel_info panel;
>  	struct fimd_driver_data *driver_data;
> -	struct exynos_drm_encoder *encoder;
> +	struct drm_encoder *encoder;
>  };
>  
>  static const struct of_device_id fimd_driver_dt_match[] = {
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> index 9b64c77..581af35 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
> @@ -25,7 +25,6 @@
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_crtc.h"
>  #include "exynos_drm_plane.h"
> -#include "exynos_drm_encoder.h"
>  #include "exynos_drm_vidi.h"
>  
>  /* vidi has totally three virtual windows. */
> @@ -35,7 +34,7 @@
>  					connector)
>  
>  struct vidi_context {
> -	struct exynos_drm_encoder	encoder;
> +	struct drm_encoder		encoder;
>  	struct platform_device		*pdev;
>  	struct drm_device		*drm_dev;
>  	struct exynos_drm_crtc		*crtc;
> @@ -54,7 +53,7 @@ struct vidi_context {
>  	int				pipe;
>  };
>  
> -static inline struct vidi_context *encoder_to_vidi(struct exynos_drm_encoder *e)
> +static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e)
>  {
>  	return container_of(e, struct vidi_context, encoder);
>  }
> @@ -358,7 +357,7 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
>  {
>  	struct vidi_context *ctx = ctx_from_connector(connector);
>  
> -	return &ctx->encoder.base;
> +	return &ctx->encoder;
>  }
>  
>  static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
> @@ -366,10 +365,9 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
>  	.best_encoder = vidi_best_encoder,
>  };
>  
> -static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
> +static int vidi_create_connector(struct drm_encoder *encoder)
>  {
> -	struct vidi_context *ctx = encoder_to_vidi(exynos_encoder);
> -	struct drm_encoder *encoder = &exynos_encoder->base;
> +	struct vidi_context *ctx = encoder_to_vidi(encoder);
>  	struct drm_connector *connector = &ctx->connector;
>  	int ret;
>  
> @@ -389,15 +387,47 @@ static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
>  	return 0;
>  }
>  
> +static bool exynos_vidi_mode_fixup(struct drm_encoder *encoder,
> +				 const struct drm_display_mode *mode,
> +				 struct drm_display_mode *adjusted_mode)
> +{
> +	return true;
> +}
> +
> +static void exynos_vidi_mode_set(struct drm_encoder *encoder,
> +			       struct drm_display_mode *mode,
> +			       struct drm_display_mode *adjusted_mode)
> +{
> +}
> +
> +static void exynos_vidi_enable(struct drm_encoder *encoder)
> +{
> +}
> +
> +static void exynos_vidi_disable(struct drm_encoder *encoder)
> +{
> +}
> +
> +static struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs = {
> +	.mode_fixup = exynos_vidi_mode_fixup,
> +	.mode_set = exynos_vidi_mode_set,
> +	.enable = exynos_vidi_enable,
> +	.disable = exynos_vidi_disable,
> +};
> +
> +static struct drm_encoder_funcs exynos_vidi_encoder_funcs = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
>  static int vidi_bind(struct device *dev, struct device *master, void *data)
>  {
>  	struct vidi_context *ctx = dev_get_drvdata(dev);
>  	struct drm_device *drm_dev = data;
> -	struct exynos_drm_encoder *exynos_encoder = &ctx->encoder;
> +	struct drm_encoder *encoder = &ctx->encoder;
>  	struct exynos_drm_plane *exynos_plane;
>  	enum drm_plane_type type;
>  	unsigned int zpos;
> -	int ret;
> +	int pipe, ret;
>  
>  	vidi_ctx_initialize(ctx, drm_dev);
>  
> @@ -419,17 +449,24 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
>  		return PTR_ERR(ctx->crtc);
>  	}
>  
> -	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
> -					EXYNOS_DISPLAY_TYPE_VIDI);
> -	if (ret) {
> -		DRM_ERROR("failed to create encoder\n");
> -		return ret;
> -	}
> +	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
> +						  EXYNOS_DISPLAY_TYPE_VIDI);
> +	if (pipe < 0)
> +		return pipe;
> +
> +	encoder->possible_crtcs = 1 << pipe;
> +
> +	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
> +
> +	drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +
> +	drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs);
>  
> -	ret = vidi_create_connector(exynos_encoder);
> +	ret = vidi_create_connector(encoder);
>  	if (ret) {
>  		DRM_ERROR("failed to create connector ret = %d\n", ret);
> -		drm_encoder_cleanup(&exynos_encoder->base);
> +		drm_encoder_cleanup(encoder);
>  		return ret;
>  	}
>  
> diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
> index 148e42f..932f7fa 100644
> --- a/drivers/gpu/drm/exynos/exynos_hdmi.c
> +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
> @@ -44,7 +44,6 @@
>  
>  #include "exynos_drm_drv.h"
>  #include "exynos_drm_crtc.h"
> -#include "exynos_drm_encoder.h"
>  #include "exynos_mixer.h"
>  
>  #include <linux/gpio.h>
> @@ -88,7 +87,7 @@ struct hdmi_resources {
>  };
>  
>  struct hdmi_context {
> -	struct exynos_drm_encoder	encoder;
> +	struct drm_encoder		encoder;
>  	struct device			*dev;
>  	struct drm_device		*drm_dev;
>  	struct drm_connector		connector;
> @@ -116,7 +115,7 @@ struct hdmi_context {
>  	struct regmap			*pmureg;
>  };
>  
> -static inline struct hdmi_context *encoder_to_hdmi(struct exynos_drm_encoder *e)
> +static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
>  {
>  	return container_of(e, struct hdmi_context, encoder);
>  }
> @@ -1032,7 +1031,7 @@ static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
>  {
>  	struct hdmi_context *hdata = ctx_from_connector(connector);
>  
> -	return &hdata->encoder.base;
> +	return &hdata->encoder;
>  }
>  
>  static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
> @@ -1041,9 +1040,9 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
>  	.best_encoder = hdmi_best_encoder,
>  };
>  
> -static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
> +static int hdmi_create_connector(struct drm_encoder *encoder)
>  {
> -	struct hdmi_context *hdata = encoder_to_hdmi(exynos_encoder);
> +	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
>  	struct drm_connector *connector = &hdata->connector;
>  	int ret;
>  
> @@ -1059,28 +1058,35 @@ static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
>  
>  	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
>  	drm_connector_register(connector);
> -	drm_mode_connector_attach_encoder(connector, &exynos_encoder->base);
> +	drm_mode_connector_attach_encoder(connector, encoder);
>  
>  	return 0;
>  }
>  
> -static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
> -				struct drm_connector *connector,
> -				const struct drm_display_mode *mode,
> -				struct drm_display_mode *adjusted_mode)
> +static bool hdmi_mode_fixup(struct drm_encoder *encoder,
> +			    const struct drm_display_mode *mode,
> +			    struct drm_display_mode *adjusted_mode)
>  {
> +	struct drm_device *dev = encoder->dev;
> +	struct drm_connector *connector;
>  	struct drm_display_mode *m;
>  	int mode_ok;
>  
> -	DRM_DEBUG_KMS("%s\n", __FILE__);
> -
>  	drm_mode_set_crtcinfo(adjusted_mode, 0);
>  
> +	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> +		if (connector->encoder == encoder)
> +			break;
> +	}
> +
> +	if (connector->encoder != encoder)
> +		return true;
> +
>  	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
>  
>  	/* just return if user desired mode exists. */
>  	if (mode_ok == MODE_OK)
> -		return;
> +		return true;
>  
>  	/*
>  	 * otherwise, find the most suitable mode among modes and change it
> @@ -1100,6 +1106,8 @@ static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
>  			break;
>  		}
>  	}
> +
> +	return true;
>  }
>  
>  static void hdmi_set_acr(u32 freq, u8 *acr)
> @@ -1697,22 +1705,23 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
>  	hdmi_regs_dump(hdata, "start");
>  }
>  
> -static void hdmi_mode_set(struct exynos_drm_encoder *encoder,
> -			struct drm_display_mode *mode)
> +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 = mode;
> +	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, mode);
> +	drm_mode_copy(&hdata->current_mode, m);
>  	hdata->cea_video_id = drm_match_cea_mode(mode);
>  }
>  
> -static void hdmi_enable(struct exynos_drm_encoder *encoder)
> +static void hdmi_enable(struct drm_encoder *encoder)
>  {
>  	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
>  	struct hdmi_resources *res = &hdata->res;
> @@ -1738,11 +1747,11 @@ static void hdmi_enable(struct exynos_drm_encoder *encoder)
>  	hdmi_conf_apply(hdata);
>  }
>  
> -static void hdmi_disable(struct exynos_drm_encoder *encoder)
> +static void hdmi_disable(struct drm_encoder *encoder)
>  {
>  	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
>  	struct hdmi_resources *res = &hdata->res;
> -	struct drm_crtc *crtc = hdata->encoder.base.crtc;
> +	struct drm_crtc *crtc = encoder->crtc;
>  	const struct drm_crtc_helper_funcs *funcs = NULL;
>  
>  	if (!hdata->powered)
> @@ -1783,13 +1792,17 @@ static void hdmi_disable(struct exynos_drm_encoder *encoder)
>  	hdata->powered = false;
>  }
>  
> -static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
> +static 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,
>  };
>  
> +static struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
>  static void hdmi_hotplug_work_func(struct work_struct *work)
>  {
>  	struct hdmi_context *hdata;
> @@ -1917,22 +1930,29 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
>  {
>  	struct drm_device *drm_dev = data;
>  	struct hdmi_context *hdata = dev_get_drvdata(dev);
> -	struct exynos_drm_encoder *exynos_encoder = &hdata->encoder;
> -	int ret;
> +	struct drm_encoder *encoder = &hdata->encoder;
> +	int ret, pipe;
>  
>  	hdata->drm_dev = drm_dev;
>  
> -	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
> -					EXYNOS_DISPLAY_TYPE_HDMI);
> -	if (ret) {
> -		DRM_ERROR("failed to create encoder\n");
> -		return ret;
> -	}
> +	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
> +						  EXYNOS_DISPLAY_TYPE_HDMI);
> +	if (pipe < 0)
> +		return pipe;
> +
> +	encoder->possible_crtcs = 1 << pipe;
> +
> +	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
> +
> +	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +
> +	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
>  
> -	ret = hdmi_create_connector(exynos_encoder);
> +	ret = hdmi_create_connector(encoder);
>  	if (ret) {
>  		DRM_ERROR("failed to create connector ret = %d\n", ret);
> -		drm_encoder_cleanup(&exynos_encoder->base);
> +		drm_encoder_cleanup(encoder);
>  		return ret;
>  	}
>  
> @@ -1985,7 +2005,6 @@ static int hdmi_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  
>  	hdata->drv_data = match->data;
> -	hdata->encoder.ops = &hdmi_encoder_ops;
>  
>  	platform_set_drvdata(pdev, hdata);
>  
> 

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

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-07 11:50       ` Inki Dae
@ 2015-08-07 12:28         ` Daniel Vetter
  2015-08-07 13:22           ` Inki Dae
  2015-08-11  0:38         ` Gustavo Padovan
  1 sibling, 1 reply; 27+ messages in thread
From: Daniel Vetter @ 2015-08-07 12:28 UTC (permalink / raw)
  To: Inki Dae
  Cc: Gustavo Padovan, linux-samsung-soc, Tobias Jakobi,
	Gustavo Padovan, dri-devel

On Fri, Aug 7, 2015 at 1:50 PM, Inki Dae <inki.dae@samsung.com> wrote:
>
> Booting is locked up here. This patch looks good to me so I tried to
> find why locked up and I found the booting is locked up as soon as
> console_lock function is called. Can you and other guys look into this
> issue?

It's not locked up, you simply won't see any dmesg output after that.
Use Archit's Kconfig support in drm-misc to disable fbdev emulation
and try again.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-07 12:28         ` Daniel Vetter
@ 2015-08-07 13:22           ` Inki Dae
  0 siblings, 0 replies; 27+ messages in thread
From: Inki Dae @ 2015-08-07 13:22 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Gustavo Padovan, linux-samsung-soc, Tobias Jakobi,
	Gustavo Padovan, dri-devel

Hi Daniel,

On 2015년 08월 07일 21:28, Daniel Vetter wrote:
> On Fri, Aug 7, 2015 at 1:50 PM, Inki Dae <inki.dae@samsung.com> wrote:
>>
>> Booting is locked up here. This patch looks good to me so I tried to
>> find why locked up and I found the booting is locked up as soon as
>> console_lock function is called. Can you and other guys look into this
>> issue?
> 
> It's not locked up, you simply won't see any dmesg output after that.
> Use Archit's Kconfig support in drm-misc to disable fbdev emulation
> and try again.

I didn't really look into this patch series. I will check it with this
patch series next week and give Acked-by to you.

Thanks,
Inki Dae

> -Daniel
> 

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

* [PATCH 01/11] drm/exynos: split display's .dpms() into .enable() and .disable()
  2015-08-05 23:24 ` [PATCH v2 01/11] drm/exynos: split display's .dpms() into .enable() and .disable() Gustavo Padovan
@ 2015-08-11  0:37   ` Gustavo Padovan
  0 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-11  0:37 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

The DRM Core doesn't have a dpms() operation anymore, everything
now is enable() or disable().

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
v2: set dp->dpms_mode after enable/disable
---
 drivers/gpu/drm/exynos/exynos_dp_core.c     | 36 ++++++----------
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     | 36 ++++------------
 drivers/gpu/drm/exynos/exynos_drm_drv.h     |  6 ++-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     | 44 ++++++-------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c |  8 ++--
 drivers/gpu/drm/exynos/exynos_hdmi.c        | 65 ++++++++++-------------------
 6 files changed, 65 insertions(+), 130 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..ef24952 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1066,8 +1066,9 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 		phy_power_off(dp->phy);
 }
 
-static void exynos_dp_poweron(struct exynos_dp_device *dp)
+static void exynos_dp_enable(struct exynos_drm_display *display)
 {
+	struct exynos_dp_device *dp = display_to_dp(display);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode == DRM_MODE_DPMS_ON)
@@ -1088,10 +1089,13 @@ static void exynos_dp_poweron(struct exynos_dp_device *dp)
 	exynos_dp_init_dp(dp);
 	enable_irq(dp->irq);
 	exynos_dp_commit(&dp->display);
+
+	dp->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
-static void exynos_dp_poweroff(struct exynos_dp_device *dp)
+static void exynos_dp_disable(struct exynos_drm_display *display)
 {
+	struct exynos_dp_device *dp = display_to_dp(display);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode != DRM_MODE_DPMS_ON)
@@ -1116,30 +1120,14 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
 		if (drm_panel_unprepare(dp->panel))
 			DRM_ERROR("failed to turnoff the panel\n");
 	}
-}
-
-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct exynos_dp_device *dp = display_to_dp(display);
 
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		exynos_dp_poweron(dp);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		exynos_dp_poweroff(dp);
-		break;
-	default:
-		break;
-	}
-	dp->dpms_mode = mode;
+	dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
 static struct exynos_drm_display_ops exynos_dp_display_ops = {
 	.create_connector = exynos_dp_create_connector,
-	.dpms = exynos_dp_dpms,
+	.enable = exynos_dp_enable,
+	.disable = exynos_dp_disable,
 	.commit = exynos_dp_commit,
 };
 
@@ -1319,7 +1307,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_disable(&dp->display);
 }
 
 static const struct component_ops exynos_dp_ops = {
@@ -1377,7 +1365,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_disable(&dp->display);
 	return 0;
 }
 
@@ -1385,7 +1373,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
+	exynos_dp_enable(&dp->display);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 7cb6595..e042670 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -32,7 +32,6 @@ struct exynos_dpi {
 	struct drm_encoder *encoder;
 
 	struct videomode *vm;
-	int dpms_mode;
 };
 
 #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
@@ -133,46 +132,30 @@ static int exynos_dpi_create_connector(struct exynos_drm_display *display,
 	return 0;
 }
 
-static void exynos_dpi_poweron(struct exynos_dpi *ctx)
+static void exynos_dpi_enable(struct exynos_drm_display *display)
 {
+	struct exynos_dpi *ctx = display_to_dpi(display);
+
 	if (ctx->panel) {
 		drm_panel_prepare(ctx->panel);
 		drm_panel_enable(ctx->panel);
 	}
 }
 
-static void exynos_dpi_poweroff(struct exynos_dpi *ctx)
+static void exynos_dpi_disable(struct exynos_drm_display *display)
 {
+	struct exynos_dpi *ctx = display_to_dpi(display);
+
 	if (ctx->panel) {
 		drm_panel_disable(ctx->panel);
 		drm_panel_unprepare(ctx->panel);
 	}
 }
 
-static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct exynos_dpi *ctx = display_to_dpi(display);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		if (ctx->dpms_mode != DRM_MODE_DPMS_ON)
-				exynos_dpi_poweron(ctx);
-			break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		if (ctx->dpms_mode == DRM_MODE_DPMS_ON)
-			exynos_dpi_poweroff(ctx);
-		break;
-	default:
-		break;
-	}
-	ctx->dpms_mode = mode;
-}
-
 static struct exynos_drm_display_ops exynos_dpi_display_ops = {
 	.create_connector = exynos_dpi_create_connector,
-	.dpms = exynos_dpi_dpms
+	.enable = exynos_dpi_enable,
+	.disable = exynos_dpi_disable,
 };
 
 /* of_* functions will be removed after merge of of_graph patches */
@@ -311,7 +294,6 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
 	ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD;
 	ctx->display.ops = &exynos_dpi_display_ops;
 	ctx->dev = dev;
-	ctx->dpms_mode = DRM_MODE_DPMS_OFF;
 
 	ret = exynos_dpi_parse_dt(ctx);
 	if (ret < 0) {
@@ -332,7 +314,7 @@ int exynos_dpi_remove(struct exynos_drm_display *display)
 {
 	struct exynos_dpi *ctx = display_to_dpi(display);
 
-	exynos_dpi_dpms(&ctx->display, DRM_MODE_DPMS_OFF);
+	exynos_dpi_disable(&ctx->display);
 
 	if (ctx->panel)
 		drm_panel_detach(ctx->panel);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 9f23db4..5c55606 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -86,7 +86,8 @@ struct exynos_drm_plane {
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *	      would be called by encoder->mode_set().
  * @check_mode: check if mode is valid or not.
- * @dpms: display device on or off.
+ * @enable: display device on.
+ * @disable: display device off.
  * @commit: apply changes to hw
  */
 struct exynos_drm_display;
@@ -102,7 +103,8 @@ struct exynos_drm_display_ops {
 				struct drm_display_mode *mode);
 	int (*check_mode)(struct exynos_drm_display *display,
 				struct drm_display_mode *mode);
-	void (*dpms)(struct exynos_drm_display *display, int mode);
+	void (*enable)(struct exynos_drm_display *display);
+	void (*disable)(struct exynos_drm_display *display);
 	void (*commit)(struct exynos_drm_display *display);
 };
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 0e58b36..281b97d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1518,16 +1518,17 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
 		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
 }
 
-static int exynos_dsi_enable(struct exynos_dsi *dsi)
+static void exynos_dsi_enable(struct exynos_drm_display *display)
 {
+	struct exynos_dsi *dsi = display_to_dsi(display);
 	int ret;
 
 	if (dsi->state & DSIM_STATE_ENABLED)
-		return 0;
+		return;
 
 	ret = exynos_dsi_poweron(dsi);
 	if (ret < 0)
-		return ret;
+		return;
 
 	dsi->state |= DSIM_STATE_ENABLED;
 
@@ -1535,7 +1536,7 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
 	if (ret < 0) {
 		dsi->state &= ~DSIM_STATE_ENABLED;
 		exynos_dsi_poweroff(dsi);
-		return ret;
+		return;
 	}
 
 	exynos_dsi_set_display_mode(dsi);
@@ -1547,16 +1548,16 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
 		exynos_dsi_set_display_enable(dsi, false);
 		drm_panel_unprepare(dsi->panel);
 		exynos_dsi_poweroff(dsi);
-		return ret;
+		return;
 	}
 
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
-
-	return 0;
 }
 
-static void exynos_dsi_disable(struct exynos_dsi *dsi)
+static void exynos_dsi_disable(struct exynos_drm_display *display)
 {
+	struct exynos_dsi *dsi = display_to_dsi(display);
+
 	if (!(dsi->state & DSIM_STATE_ENABLED))
 		return;
 
@@ -1571,26 +1572,6 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi)
 	exynos_dsi_poweroff(dsi);
 }
 
-static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct exynos_dsi *dsi = display_to_dsi(display);
-
-	if (dsi->panel) {
-		switch (mode) {
-		case DRM_MODE_DPMS_ON:
-			exynos_dsi_enable(dsi);
-			break;
-		case DRM_MODE_DPMS_STANDBY:
-		case DRM_MODE_DPMS_SUSPEND:
-		case DRM_MODE_DPMS_OFF:
-			exynos_dsi_disable(dsi);
-			break;
-		default:
-			break;
-		}
-	}
-}
-
 static enum drm_connector_status
 exynos_dsi_detect(struct drm_connector *connector, bool force)
 {
@@ -1604,7 +1585,7 @@ exynos_dsi_detect(struct drm_connector *connector, bool force)
 		struct exynos_drm_display *display;
 
 		display = platform_get_drvdata(to_platform_device(dsi->dev));
-		exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF);
+		exynos_dsi_disable(display);
 		drm_panel_detach(dsi->panel);
 		dsi->panel = NULL;
 	}
@@ -1698,7 +1679,8 @@ static void exynos_dsi_mode_set(struct exynos_drm_display *display,
 static struct exynos_drm_display_ops exynos_dsi_display_ops = {
 	.create_connector = exynos_dsi_create_connector,
 	.mode_set = exynos_dsi_mode_set,
-	.dpms = exynos_dsi_dpms
+	.enable = exynos_dsi_enable,
+	.disable = exynos_dsi_disable,
 };
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
@@ -1849,7 +1831,7 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
 	struct exynos_drm_display *display = dev_get_drvdata(dev);
 	struct exynos_dsi *dsi = display_to_dsi(display);
 
-	exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF);
+	exynos_dsi_disable(display);
 
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 7b89fd5..0aa4a58 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -70,8 +70,8 @@ static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
 	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->dpms)
-		display->ops->dpms(display, DRM_MODE_DPMS_ON);
+	if (display->ops->enable)
+		display->ops->enable(display);
 
 	if (display->ops->commit)
 		display->ops->commit(display);
@@ -82,8 +82,8 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
 	struct exynos_drm_display *display = exynos_encoder->display;
 
-	if (display->ops->dpms)
-		display->ops->dpms(display, DRM_MODE_DPMS_OFF);
+	if (display->ops->disable)
+		display->ops->disable(display);
 }
 
 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 448f534..9b9396a 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1723,8 +1723,9 @@ static void hdmi_commit(struct exynos_drm_display *display)
 	hdmi_conf_apply(hdata);
 }
 
-static void hdmi_poweron(struct hdmi_context *hdata)
+static void hdmi_enable(struct exynos_drm_display *display)
 {
+	struct hdmi_context *hdata = display_to_hdmi(display);
 	struct hdmi_resources *res = &hdata->res;
 
 	if (hdata->powered)
@@ -1745,16 +1746,33 @@ static void hdmi_poweron(struct hdmi_context *hdata)
 	clk_prepare_enable(res->sclk_hdmi);
 
 	hdmiphy_poweron(hdata);
-	hdmi_commit(&hdata->display);
+	hdmi_commit(display);
 }
 
-static void hdmi_poweroff(struct hdmi_context *hdata)
+static void hdmi_disable(struct exynos_drm_display *display)
 {
+	struct hdmi_context *hdata = display_to_hdmi(display);
 	struct hdmi_resources *res = &hdata->res;
+	struct drm_crtc *crtc = hdata->encoder->crtc;
+	const struct drm_crtc_helper_funcs *funcs = NULL;
 
 	if (!hdata->powered)
 		return;
 
+	/*
+	 * The SFRs of VP and Mixer are updated by Vertical Sync of
+	 * Timing generator which is a part of HDMI so the sequence
+	 * to disable TV Subsystem should be as following,
+	 *	VP -> Mixer -> HDMI
+	 *
+	 * Below codes will try to disable Mixer and VP(if used)
+	 * prior to disabling HDMI.
+	 */
+	if (crtc)
+		funcs = crtc->helper_private;
+	if (funcs && funcs->disable)
+		(*funcs->disable)(crtc);
+
 	/* HDMI System Disable */
 	hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
 
@@ -1776,49 +1794,12 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
 	hdata->powered = false;
 }
 
-static void hdmi_dpms(struct exynos_drm_display *display, int mode)
-{
-	struct hdmi_context *hdata = display_to_hdmi(display);
-	struct drm_encoder *encoder = hdata->encoder;
-	struct drm_crtc *crtc = encoder->crtc;
-	const struct drm_crtc_helper_funcs *funcs = NULL;
-
-	DRM_DEBUG_KMS("mode %d\n", mode);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		hdmi_poweron(hdata);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		/*
-		 * The SFRs of VP and Mixer are updated by Vertical Sync of
-		 * Timing generator which is a part of HDMI so the sequence
-		 * to disable TV Subsystem should be as following,
-		 *	VP -> Mixer -> HDMI
-		 *
-		 * Below codes will try to disable Mixer and VP(if used)
-		 * prior to disabling HDMI.
-		 */
-		if (crtc)
-			funcs = crtc->helper_private;
-		if (funcs && funcs->disable)
-			(*funcs->disable)(crtc);
-
-		hdmi_poweroff(hdata);
-		break;
-	default:
-		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
-		break;
-	}
-}
-
 static struct exynos_drm_display_ops hdmi_display_ops = {
 	.create_connector = hdmi_create_connector,
 	.mode_fixup	= hdmi_mode_fixup,
 	.mode_set	= hdmi_mode_set,
-	.dpms		= hdmi_dpms,
+	.enable		= hdmi_enable,
+	.disable	= hdmi_disable,
 	.commit		= hdmi_commit,
 };
 
-- 
2.1.0

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-07 11:50       ` Inki Dae
  2015-08-07 12:28         ` Daniel Vetter
@ 2015-08-11  0:38         ` Gustavo Padovan
  2015-08-11 12:13           ` Inki Dae
  1 sibling, 1 reply; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-11  0:38 UTC (permalink / raw)
  To: Inki Dae
  Cc: linux-samsung-soc, dri-devel, jy0922.shim, tjakobi, Gustavo Padovan

Hi Inki,

2015-08-07 Inki Dae <inki.dae@samsung.com>:

> Hi Gustavo,
> 
> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > 
> > struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
> > only a drm_encoder member and the internal exynos_drm_encoders ops that
> > was directly mapped to the drm_encoder helper funcs.
> > 
> > So now exynos DRM uses struct drm_encoder directly, this removes
> > completely the struct exynos_drm_encoder.
> > 
> 
> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
> is applied. Below is the booting logs,
> [    1.171318] console [ttySAC2] enabled
> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
> base_baud = 0) is a S3C6400/10
> [    1.185545] [drm] Initialized drm 1.1.0 20060810
> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
> fimd_component_ops)
> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
> exynos_dsi_component_ops)
> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [    1.214313] [drm] No driver support for vblank timestamp query.
> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
> 
> Booting is locked up here. This patch looks good to me so I tried to
> find why locked up and I found the booting is locked up as soon as
> console_lock function is called. Can you and other guys look into this
> issue?

I've realized that I left a fix for patch 01 behind, it could be the
cause of this issue. I've just resent this patch with the added v2 fix
up.

	Gustavo

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-11  0:38         ` Gustavo Padovan
@ 2015-08-11 12:13           ` Inki Dae
  2015-08-11 15:03             ` Daniel Vetter
  2015-08-12 15:49             ` Gustavo Padovan
  0 siblings, 2 replies; 27+ messages in thread
From: Inki Dae @ 2015-08-11 12:13 UTC (permalink / raw)
  To: Gustavo Padovan, linux-samsung-soc, dri-devel, jy0922.shim,
	tjakobi, Gustavo Padovan

On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
> Hi Inki,
> 
> 2015-08-07 Inki Dae <inki.dae@samsung.com>:
> 
>> Hi Gustavo,
>>
>> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
>>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>>
>>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
>>> only a drm_encoder member and the internal exynos_drm_encoders ops that
>>> was directly mapped to the drm_encoder helper funcs.
>>>
>>> So now exynos DRM uses struct drm_encoder directly, this removes
>>> completely the struct exynos_drm_encoder.
>>>
>>
>> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
>> is applied. Below is the booting logs,
>> [    1.171318] console [ttySAC2] enabled
>> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
>> base_baud = 0) is a S3C6400/10
>> [    1.185545] [drm] Initialized drm 1.1.0 20060810
>> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
>> fimd_component_ops)
>> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
>> exynos_dsi_component_ops)
>> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [    1.214313] [drm] No driver support for vblank timestamp query.
>> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
>>
>> Booting is locked up here. This patch looks good to me so I tried to
>> find why locked up and I found the booting is locked up as soon as
>> console_lock function is called. Can you and other guys look into this
>> issue?
> 
> I've realized that I left a fix for patch 01 behind, it could be the
> cause of this issue. I've just resent this patch with the added v2 fix
> up.

With above change, still locked up. So your updated patch doesn't
resolve this issue.

Anyway, I tested it with fbdev emulation relevant patch series[1] and
the booting was ok with disabling fbdev emulation as Daniel commented.
However, I think the booting should also be ok with fbdev emulation so I
don't want for your last patch to be merged to mainline until the issue
is resolved.

[1] http://www.spinics.net/lists/dri-devel/msg86617.html
    http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html

Thanks,
Inki Dae

> 
> 	Gustavo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-11 12:13           ` Inki Dae
@ 2015-08-11 15:03             ` Daniel Vetter
  2015-08-12  2:53               ` Inki Dae
  2015-08-12 15:49             ` Gustavo Padovan
  1 sibling, 1 reply; 27+ messages in thread
From: Daniel Vetter @ 2015-08-11 15:03 UTC (permalink / raw)
  To: Inki Dae; +Cc: linux-samsung-soc, dri-devel, tjakobi, Gustavo Padovan

On Tue, Aug 11, 2015 at 09:13:54PM +0900, Inki Dae wrote:
> On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
> > Hi Inki,
> > 
> > 2015-08-07 Inki Dae <inki.dae@samsung.com>:
> > 
> >> Hi Gustavo,
> >>
> >> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
> >>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >>>
> >>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
> >>> only a drm_encoder member and the internal exynos_drm_encoders ops that
> >>> was directly mapped to the drm_encoder helper funcs.
> >>>
> >>> So now exynos DRM uses struct drm_encoder directly, this removes
> >>> completely the struct exynos_drm_encoder.
> >>>
> >>
> >> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
> >> is applied. Below is the booting logs,
> >> [    1.171318] console [ttySAC2] enabled
> >> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
> >> base_baud = 0) is a S3C6400/10
> >> [    1.185545] [drm] Initialized drm 1.1.0 20060810
> >> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
> >> fimd_component_ops)
> >> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
> >> exynos_dsi_component_ops)
> >> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> >> [    1.214313] [drm] No driver support for vblank timestamp query.
> >> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
> >>
> >> Booting is locked up here. This patch looks good to me so I tried to
> >> find why locked up and I found the booting is locked up as soon as
> >> console_lock function is called. Can you and other guys look into this
> >> issue?
> > 
> > I've realized that I left a fix for patch 01 behind, it could be the
> > cause of this issue. I've just resent this patch with the added v2 fix
> > up.
> 
> With above change, still locked up. So your updated patch doesn't
> resolve this issue.
> 
> Anyway, I tested it with fbdev emulation relevant patch series[1] and
> the booting was ok with disabling fbdev emulation as Daniel commented.
> However, I think the booting should also be ok with fbdev emulation so I
> don't want for your last patch to be merged to mainline until the issue
> is resolved.

Without fbdev you need to start a kms client (X, whatever) to force a
modeset. Otherwise you won't reproduce anything. And sometimes it requires
a bit of trickery to create a sequence of modeset calls which exactly
match what fbcon would do.
-Daniel

> 
> [1] http://www.spinics.net/lists/dri-devel/msg86617.html
>     http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
> 
> Thanks,
> Inki Dae
> 
> > 
> > 	Gustavo
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-11 15:03             ` Daniel Vetter
@ 2015-08-12  2:53               ` Inki Dae
  0 siblings, 0 replies; 27+ messages in thread
From: Inki Dae @ 2015-08-12  2:53 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: linux-samsung-soc, dri-devel, tjakobi, Gustavo Padovan

On 2015년 08월 12일 00:03, Daniel Vetter wrote:
> On Tue, Aug 11, 2015 at 09:13:54PM +0900, Inki Dae wrote:
>> On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
>>> Hi Inki,
>>>
>>> 2015-08-07 Inki Dae <inki.dae@samsung.com>:
>>>
>>>> Hi Gustavo,
>>>>
>>>> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
>>>>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>>>>
>>>>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
>>>>> only a drm_encoder member and the internal exynos_drm_encoders ops that
>>>>> was directly mapped to the drm_encoder helper funcs.
>>>>>
>>>>> So now exynos DRM uses struct drm_encoder directly, this removes
>>>>> completely the struct exynos_drm_encoder.
>>>>>
>>>>
>>>> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
>>>> is applied. Below is the booting logs,
>>>> [    1.171318] console [ttySAC2] enabled
>>>> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
>>>> base_baud = 0) is a S3C6400/10
>>>> [    1.185545] [drm] Initialized drm 1.1.0 20060810
>>>> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
>>>> fimd_component_ops)
>>>> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
>>>> exynos_dsi_component_ops)
>>>> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>>>> [    1.214313] [drm] No driver support for vblank timestamp query.
>>>> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
>>>>
>>>> Booting is locked up here. This patch looks good to me so I tried to
>>>> find why locked up and I found the booting is locked up as soon as
>>>> console_lock function is called. Can you and other guys look into this
>>>> issue?
>>>
>>> I've realized that I left a fix for patch 01 behind, it could be the
>>> cause of this issue. I've just resent this patch with the added v2 fix
>>> up.
>>
>> With above change, still locked up. So your updated patch doesn't
>> resolve this issue.
>>
>> Anyway, I tested it with fbdev emulation relevant patch series[1] and
>> the booting was ok with disabling fbdev emulation as Daniel commented.
>> However, I think the booting should also be ok with fbdev emulation so I
>> don't want for your last patch to be merged to mainline until the issue
>> is resolved.
> 
> Without fbdev you need to start a kms client (X, whatever) to force a

Of course I know. Without fbdev, modeset never be performed at booting
time. However, without fbdev, we cannot use text console and that is
definitely a problem.

Thanks,
Inki Dae

> modeset. Otherwise you won't reproduce anything. And sometimes it requires
> a bit of trickery to create a sequence of modeset calls which exactly
> match what fbcon would do.
> -Daniel
> 
>>
>> [1] http://www.spinics.net/lists/dri-devel/msg86617.html
>>     http://lists.freedesktop.org/archives/dri-devel/2015-March/078975.html
>>
>> Thanks,
>> Inki Dae
>>
>>>
>>> 	Gustavo
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

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

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-11 12:13           ` Inki Dae
  2015-08-11 15:03             ` Daniel Vetter
@ 2015-08-12 15:49             ` Gustavo Padovan
  2015-08-12 15:54               ` Gustavo Padovan
  1 sibling, 1 reply; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-12 15:49 UTC (permalink / raw)
  To: Inki Dae
  Cc: Gustavo Padovan, linux-samsung-soc, dri-devel, jy0922.shim, tjakobi

Hi Inki,

2015-08-11 Inki Dae <inki.dae@samsung.com>:

> On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
> > Hi Inki,
> > 
> > 2015-08-07 Inki Dae <inki.dae@samsung.com>:
> > 
> >> Hi Gustavo,
> >>
> >> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
> >>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >>>
> >>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
> >>> only a drm_encoder member and the internal exynos_drm_encoders ops that
> >>> was directly mapped to the drm_encoder helper funcs.
> >>>
> >>> So now exynos DRM uses struct drm_encoder directly, this removes
> >>> completely the struct exynos_drm_encoder.
> >>>
> >>
> >> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
> >> is applied. Below is the booting logs,
> >> [    1.171318] console [ttySAC2] enabled
> >> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
> >> base_baud = 0) is a S3C6400/10
> >> [    1.185545] [drm] Initialized drm 1.1.0 20060810
> >> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
> >> fimd_component_ops)
> >> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
> >> exynos_dsi_component_ops)
> >> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> >> [    1.214313] [drm] No driver support for vblank timestamp query.
> >> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
> >>
> >> Booting is locked up here. This patch looks good to me so I tried to
> >> find why locked up and I found the booting is locked up as soon as
> >> console_lock function is called. Can you and other guys look into this
> >> issue?
> > 
> > I've realized that I left a fix for patch 01 behind, it could be the
> > cause of this issue. I've just resent this patch with the added v2 fix
> > up.
> 
> With above change, still locked up. So your updated patch doesn't
> resolve this issue.
> 
> Anyway, I tested it with fbdev emulation relevant patch series[1] and
> the booting was ok with disabling fbdev emulation as Daniel commented.
> However, I think the booting should also be ok with fbdev emulation so I
> don't want for your last patch to be merged to mainline until the issue
> is resolved.

I've tried to reproduce your issue with these patches on a odroid-x2
(exynos4412) but it seems to work fine for me with fbdev emulation
enabled. In snow and peach-pi it also works fine. We would need
to debug better on your side to figure out what is breaking for you.

	Gustavo

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-12 15:49             ` Gustavo Padovan
@ 2015-08-12 15:54               ` Gustavo Padovan
  2015-08-15 14:33                 ` Inki Dae
  0 siblings, 1 reply; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-12 15:54 UTC (permalink / raw)
  To: Gustavo Padovan
  Cc: Inki Dae, linux-samsung-soc, dri-devel, jy0922.shim, tjakobi

2015-08-12 Gustavo Padovan <gustavo.padovan@collabora.co.uk>:

> Hi Inki,
> 
> 2015-08-11 Inki Dae <inki.dae@samsung.com>:
> 
> > On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
> > > Hi Inki,
> > > 
> > > 2015-08-07 Inki Dae <inki.dae@samsung.com>:
> > > 
> > >> Hi Gustavo,
> > >>
> > >> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
> > >>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > >>>
> > >>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
> > >>> only a drm_encoder member and the internal exynos_drm_encoders ops that
> > >>> was directly mapped to the drm_encoder helper funcs.
> > >>>
> > >>> So now exynos DRM uses struct drm_encoder directly, this removes
> > >>> completely the struct exynos_drm_encoder.
> > >>>
> > >>
> > >> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
> > >> is applied. Below is the booting logs,
> > >> [    1.171318] console [ttySAC2] enabled
> > >> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
> > >> base_baud = 0) is a S3C6400/10
> > >> [    1.185545] [drm] Initialized drm 1.1.0 20060810
> > >> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
> > >> fimd_component_ops)
> > >> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
> > >> exynos_dsi_component_ops)
> > >> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> > >> [    1.214313] [drm] No driver support for vblank timestamp query.
> > >> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
> > >>
> > >> Booting is locked up here. This patch looks good to me so I tried to
> > >> find why locked up and I found the booting is locked up as soon as
> > >> console_lock function is called. Can you and other guys look into this
> > >> issue?
> > > 
> > > I've realized that I left a fix for patch 01 behind, it could be the
> > > cause of this issue. I've just resent this patch with the added v2 fix
> > > up.
> > 
> > With above change, still locked up. So your updated patch doesn't
> > resolve this issue.
> > 
> > Anyway, I tested it with fbdev emulation relevant patch series[1] and
> > the booting was ok with disabling fbdev emulation as Daniel commented.
> > However, I think the booting should also be ok with fbdev emulation so I
> > don't want for your last patch to be merged to mainline until the issue
> > is resolved.
> 
> I've tried to reproduce your issue with these patches on a odroid-x2
> (exynos4412) but it seems to work fine for me with fbdev emulation
> enabled. In snow and peach-pi it also works fine. We would need
> to debug better on your side to figure out what is breaking for you.

Can you please git bisect this? So we can figure out which commit is
causing the issue. That would be great.

	Gustavo

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-12 15:54               ` Gustavo Padovan
@ 2015-08-15 14:33                 ` Inki Dae
  2015-08-15 15:22                   ` Gustavo Padovan
  0 siblings, 1 reply; 27+ messages in thread
From: Inki Dae @ 2015-08-15 14:33 UTC (permalink / raw)
  To: Gustavo Padovan, Gustavo Padovan, Inki Dae, linux-samsung-soc,
	DRI mailing list, Joonyoung Shim, Tobias Jakobi

2015-08-13 0:54 GMT+09:00 Gustavo Padovan <gustavo@padovan.org>:
> 2015-08-12 Gustavo Padovan <gustavo.padovan@collabora.co.uk>:
>
>> Hi Inki,
>>
>> 2015-08-11 Inki Dae <inki.dae@samsung.com>:
>>
>> > On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
>> > > Hi Inki,
>> > >
>> > > 2015-08-07 Inki Dae <inki.dae@samsung.com>:
>> > >
>> > >> Hi Gustavo,
>> > >>
>> > >> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
>> > >>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>> > >>>
>> > >>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
>> > >>> only a drm_encoder member and the internal exynos_drm_encoders ops that
>> > >>> was directly mapped to the drm_encoder helper funcs.
>> > >>>
>> > >>> So now exynos DRM uses struct drm_encoder directly, this removes
>> > >>> completely the struct exynos_drm_encoder.
>> > >>>
>> > >>
>> > >> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
>> > >> is applied. Below is the booting logs,
>> > >> [    1.171318] console [ttySAC2] enabled
>> > >> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
>> > >> base_baud = 0) is a S3C6400/10
>> > >> [    1.185545] [drm] Initialized drm 1.1.0 20060810
>> > >> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
>> > >> fimd_component_ops)
>> > >> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
>> > >> exynos_dsi_component_ops)
>> > >> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> > >> [    1.214313] [drm] No driver support for vblank timestamp query.
>> > >> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
>> > >>
>> > >> Booting is locked up here. This patch looks good to me so I tried to
>> > >> find why locked up and I found the booting is locked up as soon as
>> > >> console_lock function is called. Can you and other guys look into this
>> > >> issue?
>> > >
>> > > I've realized that I left a fix for patch 01 behind, it could be the
>> > > cause of this issue. I've just resent this patch with the added v2 fix
>> > > up.
>> >
>> > With above change, still locked up. So your updated patch doesn't
>> > resolve this issue.
>> >
>> > Anyway, I tested it with fbdev emulation relevant patch series[1] and
>> > the booting was ok with disabling fbdev emulation as Daniel commented.
>> > However, I think the booting should also be ok with fbdev emulation so I
>> > don't want for your last patch to be merged to mainline until the issue
>> > is resolved.
>>
>> I've tried to reproduce your issue with these patches on a odroid-x2
>> (exynos4412) but it seems to work fine for me with fbdev emulation
>> enabled. In snow and peach-pi it also works fine. We would need
>> to debug better on your side to figure out what is breaking for you.
>
> Can you please git bisect this? So we can figure out which commit is
> causing the issue. That would be great.

I already commented above, your last patch - 11/11. Without 11/11, it
worked well. Did you test odroid-x2 with LVDS based Display panel? If
so, it's not different because I tested it with Trats2 board with
MIPI-DSI + Display panel. AFAIK, Odroid-x2 board doesn't support
MIPI-DSI panel. I will have a pull request soon without 11/11. After
that, I think we could find and resolve the issue later.

Thanks,
Inki Dae

>
>         Gustavo
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH -v3 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-06 13:31     ` [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer Gustavo Padovan
  2015-08-07 11:50       ` Inki Dae
@ 2015-08-15 15:14       ` Gustavo Padovan
  1 sibling, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-15 15:14 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: dri-devel, inki.dae, jy0922.shim, tjakobi, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
only a drm_encoder member and the internal exynos_drm_encoders ops that
was directly mapped to the drm_encoder helper funcs.

So now exynos DRM uses struct drm_encoder directly, this removes
completely the struct exynos_drm_encoder.

v2: add empty .mode_fixup() and .mode_set() to DSI and DPI to avoid null
pointer.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/gpu/drm/exynos/Makefile             |   7 +-
 drivers/gpu/drm/exynos/exynos7_drm_decon.c  |   2 +-
 drivers/gpu/drm/exynos/exynos_dp_core.c     |  68 ++++++++++++------
 drivers/gpu/drm/exynos/exynos_dp_core.h     |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_core.c    |   1 -
 drivers/gpu/drm/exynos/exynos_drm_crtc.c    |   1 -
 drivers/gpu/drm/exynos/exynos_drm_dpi.c     |  66 +++++++++++------
 drivers/gpu/drm/exynos/exynos_drm_drv.c     |   1 -
 drivers/gpu/drm/exynos/exynos_drm_drv.h     |  47 ++-----------
 drivers/gpu/drm/exynos/exynos_drm_dsi.c     |  88 +++++++++++++----------
 drivers/gpu/drm/exynos/exynos_drm_encoder.c | 105 ----------------------------
 drivers/gpu/drm/exynos/exynos_drm_encoder.h |  22 ------
 drivers/gpu/drm/exynos/exynos_drm_fimd.c    |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_vidi.c    |  71 ++++++++++++++-----
 drivers/gpu/drm/exynos/exynos_hdmi.c        |  85 +++++++++++++---------
 15 files changed, 259 insertions(+), 309 deletions(-)
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_encoder.h

diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 7de0b10..61c2906 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -3,10 +3,9 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
-exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
-		exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
-		exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
-		exynos_drm_plane.o exynos_drm_dmabuf.o
+exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
+		exynos_drm_fb.o exynos_drm_buf.o exynos_drm_gem.o \
+		exynos_drm_core.o exynos_drm_plane.o exynos_drm_dmabuf.o
 
 exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)	+= exynos_drm_fimd.o
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index e1a2ce7..0792654 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -61,7 +61,7 @@ struct decon_context {
 	atomic_t			wait_vsync_event;
 
 	struct exynos_drm_panel_info panel;
-	struct exynos_drm_encoder *encoder;
+	struct drm_encoder *encoder;
 };
 
 static const struct of_device_id decon_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 67c5cd1..d66ade0 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -32,18 +32,18 @@
 #include <drm/drm_panel.h>
 
 #include "exynos_dp_core.h"
-#include "exynos_drm_encoder.h"
+#include "exynos_drm_crtc.h"
 
 #define ctx_from_connector(c)	container_of(c, struct exynos_dp_device, \
 					connector)
 
 static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp)
 {
-	return to_exynos_crtc(dp->encoder.base.crtc);
+	return to_exynos_crtc(dp->encoder.crtc);
 }
 
 static inline struct exynos_dp_device *encoder_to_dp(
-						struct exynos_drm_encoder *e)
+						struct drm_encoder *e)
 {
 	return container_of(e, struct exynos_dp_device, encoder);
 }
@@ -889,7 +889,7 @@ static void exynos_dp_hotplug(struct work_struct *work)
 		drm_helper_hpd_irq_event(dp->drm_dev);
 }
 
-static void exynos_dp_commit(struct exynos_drm_encoder *encoder)
+static void exynos_dp_commit(struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	int ret;
@@ -995,7 +995,7 @@ static struct drm_encoder *exynos_dp_best_encoder(
 {
 	struct exynos_dp_device *dp = ctx_from_connector(connector);
 
-	return &dp->encoder.base;
+	return &dp->encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
@@ -1020,10 +1020,9 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 	return 0;
 }
 
-static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
+static int exynos_dp_create_connector(struct drm_encoder *encoder)
 {
-	struct exynos_dp_device *dp = encoder_to_dp(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct drm_connector *connector = &dp->connector;
 	int ret;
 
@@ -1053,7 +1052,20 @@ static int exynos_dp_create_connector(struct exynos_drm_encoder *exynos_encoder)
 	return ret;
 }
 
-static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
+static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_dp_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void exynos_dp_enable(struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
@@ -1080,7 +1092,7 @@ static void exynos_dp_enable(struct exynos_drm_encoder *encoder)
 	dp->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
-static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
+static void exynos_dp_disable(struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = encoder_to_dp(encoder);
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
@@ -1111,11 +1123,17 @@ static void exynos_dp_disable(struct exynos_drm_encoder *encoder)
 	dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
-static struct exynos_drm_encoder_ops exynos_dp_encoder_ops = {
+static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
+	.mode_fixup = exynos_dp_mode_fixup,
+	.mode_set = exynos_dp_mode_set,
 	.enable = exynos_dp_enable,
 	.disable = exynos_dp_disable,
 };
 
+static struct drm_encoder_funcs exynos_dp_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 {
 	struct device_node *dp_node = dev->of_node;
@@ -1192,10 +1210,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm_dev = data;
-	struct exynos_drm_encoder *exynos_encoder = &dp->encoder;
+	struct drm_encoder *encoder = &dp->encoder;
 	struct resource *res;
 	unsigned int irq_flags;
-	int ret = 0;
+	int pipe, ret = 0;
 
 	dp->dev = &pdev->dev;
 	dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1285,17 +1303,24 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 
 	dp->drm_dev = drm_dev;
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
+	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_LCD);
+	if (pipe < 0)
+		return pipe;
+
+	encoder->possible_crtcs = 1 << pipe;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
 
-	ret = exynos_dp_create_connector(exynos_encoder);
+	ret = exynos_dp_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
@@ -1326,7 +1351,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (!dp)
 		return -ENOMEM;
 
-	dp->encoder.ops = &exynos_dp_encoder_ops;
 	platform_set_drvdata(pdev, dp);
 
 	panel_node = of_parse_phandle(dev->of_node, "panel", 0);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index f8cc202..e413b6f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -147,7 +147,7 @@ struct link_train {
 };
 
 struct exynos_dp_device {
-	struct exynos_drm_encoder encoder;
+	struct drm_encoder	encoder;
 	struct device		*dev;
 	struct drm_device	*drm_dev;
 	struct drm_connector	connector;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 1f38a44..c68a6a2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -15,7 +15,6 @@
 #include <drm/drmP.h>
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_fbdev.h"
 
 static LIST_HEAD(exynos_drm_subdrv_list);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 2715c2a..b9b0e9c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -19,7 +19,6 @@
 
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_plane.h"
 
 static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 6850ce5..c748b87 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -20,11 +20,10 @@
 #include <video/of_videomode.h>
 #include <video/videomode.h>
 
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_crtc.h"
 
 struct exynos_dpi {
-	struct exynos_drm_encoder encoder;
+	struct drm_encoder encoder;
 	struct device *dev;
 	struct device_node *panel_node;
 
@@ -36,7 +35,7 @@ struct exynos_dpi {
 
 #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
 
-static inline struct exynos_dpi *encoder_to_dpi(struct exynos_drm_encoder *e)
+static inline struct exynos_dpi *encoder_to_dpi(struct drm_encoder *e)
 {
 	return container_of(e, struct exynos_dpi, encoder);
 }
@@ -98,7 +97,7 @@ exynos_dpi_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dpi *ctx = connector_to_dpi(connector);
 
-	return &ctx->encoder.base;
+	return &ctx->encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
@@ -106,11 +105,9 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
 	.best_encoder = exynos_dpi_best_encoder,
 };
 
-static int exynos_dpi_create_connector(
-				struct exynos_drm_encoder *exynos_encoder)
+static int exynos_dpi_create_connector(struct drm_encoder *encoder)
 {
-	struct exynos_dpi *ctx = encoder_to_dpi(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 	struct drm_connector *connector = &ctx->connector;
 	int ret;
 
@@ -131,7 +128,20 @@ static int exynos_dpi_create_connector(
 	return 0;
 }
 
-static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
+static bool exynos_dpi_mode_fixup(struct drm_encoder *encoder,
+				  const struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_dpi_mode_set(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void exynos_dpi_enable(struct drm_encoder *encoder)
 {
 	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
@@ -141,7 +151,7 @@ static void exynos_dpi_enable(struct exynos_drm_encoder *encoder)
 	}
 }
 
-static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
+static void exynos_dpi_disable(struct drm_encoder *encoder)
 {
 	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
@@ -151,11 +161,17 @@ static void exynos_dpi_disable(struct exynos_drm_encoder *encoder)
 	}
 }
 
-static struct exynos_drm_encoder_ops exynos_dpi_encoder_ops = {
+static struct drm_encoder_helper_funcs exynos_dpi_encoder_helper_funcs = {
+	.mode_fixup = exynos_dpi_mode_fixup,
+	.mode_set = exynos_dpi_mode_set,
 	.enable = exynos_dpi_enable,
 	.disable = exynos_dpi_disable,
 };
 
+static struct drm_encoder_funcs exynos_dpi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 /* of_* functions will be removed after merge of of_graph patches */
 static struct device_node *
 of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
@@ -280,29 +296,34 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
 	return 0;
 }
 
-int exynos_dpi_bind(struct drm_device *dev,
-		    struct exynos_drm_encoder *exynos_encoder)
+int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder)
 {
 	int ret;
 
-	ret = exynos_drm_encoder_create(dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
+	ret = exynos_drm_crtc_get_pipe_from_type(dev, EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret < 0)
 		return ret;
-	}
 
-	ret = exynos_dpi_create_connector(exynos_encoder);
+	encoder->possible_crtcs = 1 << ret;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(dev, encoder, &exynos_dpi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_dpi_encoder_helper_funcs);
+
+	ret = exynos_dpi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
 	return 0;
 }
 
-struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
+struct drm_encoder *exynos_dpi_probe(struct device *dev)
 {
 	struct exynos_dpi *ctx;
 	int ret;
@@ -311,7 +332,6 @@ struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
 	if (!ctx)
 		return ERR_PTR(-ENOMEM);
 
-	ctx->encoder.ops = &exynos_dpi_encoder_ops;
 	ctx->dev = dev;
 
 	ret = exynos_dpi_parse_dt(ctx);
@@ -329,7 +349,7 @@ struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev)
 	return &ctx->encoder;
 }
 
-int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
+int exynos_dpi_remove(struct drm_encoder *encoder)
 {
 	struct exynos_dpi *ctx = encoder_to_dpi(encoder);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 99ad9ae..e8db234 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -21,7 +21,6 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a4977be..6b8a30f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -22,7 +22,6 @@
 #define MAX_PLANE	5
 #define MAX_FB_BUFFER	4
 
-#define to_exynos_encoder(x)	container_of(x, struct exynos_drm_encoder, base)
 #define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
 #define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)
 
@@ -78,40 +77,6 @@ struct exynos_drm_plane {
 };
 
 /*
- * Exynos DRM Encoder Structure.
- *	- this structure is common to analog tv, digital tv and lcd panel.
- *
- * @mode_fixup: fix mode data comparing to hw specific display mode.
- * @mode_set: convert drm_display_mode to hw specific display mode and
- *	      would be called by encoder->mode_set().
- * @enable: display device on.
- * @disable: display device off.
- */
-struct exynos_drm_encoder;
-struct exynos_drm_encoder_ops {
-	void (*mode_fixup)(struct exynos_drm_encoder *encoder,
-				struct drm_connector *connector,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode);
-	void (*mode_set)(struct exynos_drm_encoder *encoder,
-				struct drm_display_mode *mode);
-	void (*enable)(struct exynos_drm_encoder *encoder);
-	void (*disable)(struct exynos_drm_encoder *encoder);
-};
-
-/*
- * exynos specific encoder structure.
- *
- * @drm_encoder: encoder object.
- * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
- * @ops: pointer to callbacks for exynos drm specific functionality
- */
-struct exynos_drm_encoder {
-	struct drm_encoder		base;
-	struct exynos_drm_encoder_ops	*ops;
-};
-
-/*
  * Exynos drm crtc ops
  *
  * @enable: enable the device
@@ -255,18 +220,18 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
 
 #ifdef CONFIG_DRM_EXYNOS_DPI
-struct exynos_drm_encoder *exynos_dpi_probe(struct device *dev);
-int exynos_dpi_remove(struct exynos_drm_encoder *encoder);
-int exynos_dpi_bind(struct drm_device *dev, struct exynos_drm_encoder *encoder);
+struct drm_encoder *exynos_dpi_probe(struct device *dev);
+int exynos_dpi_remove(struct drm_encoder *encoder);
+int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder);
 #else
-static inline struct exynos_drm_encoder *
+static inline struct drm_encoder *
 exynos_dpi_probe(struct device *dev) { return NULL; }
-static inline int exynos_dpi_remove(struct exynos_drm_encoder *encoder)
+static inline int exynos_dpi_remove(struct drm_encoder *encoder)
 {
 	return 0;
 }
 static inline int exynos_dpi_bind(struct drm_device *dev,
-				  struct exynos_drm_encoder *encoder)
+				  struct drm_encoder *encoder)
 {
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index d791ad4..12b03b3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -30,7 +30,6 @@
 #include <video/videomode.h>
 
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_drv.h"
 
 /* returns true iff both arguments logically differs */
@@ -260,7 +259,7 @@ struct exynos_dsi_driver_data {
 };
 
 struct exynos_dsi {
-	struct exynos_drm_encoder encoder;
+	struct drm_encoder encoder;
 	struct mipi_dsi_host dsi_host;
 	struct drm_connector connector;
 	struct device_node *panel_node;
@@ -296,7 +295,7 @@ struct exynos_dsi {
 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
 
-static inline struct exynos_dsi *encoder_to_dsi(struct exynos_drm_encoder *e)
+static inline struct exynos_dsi *encoder_to_dsi(struct drm_encoder *e)
 {
 	return container_of(e, struct exynos_dsi, encoder);
 }
@@ -1273,7 +1272,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
 {
 	struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
-	struct drm_encoder *encoder = &dsi->encoder.base;
+	struct drm_encoder *encoder = &dsi->encoder;
 
 	if (dsi->state & DSIM_STATE_VIDOUT_AVAILABLE)
 		exynos_drm_crtc_te_handler(encoder->crtc);
@@ -1519,7 +1518,7 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
 		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);
 }
 
-static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
+static void exynos_dsi_enable(struct drm_encoder *encoder)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	int ret;
@@ -1555,7 +1554,7 @@ static void exynos_dsi_enable(struct exynos_drm_encoder *encoder)
 	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
 }
 
-static void exynos_dsi_disable(struct exynos_drm_encoder *encoder)
+static void exynos_dsi_disable(struct drm_encoder *encoder)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 
@@ -1583,7 +1582,7 @@ exynos_dsi_detect(struct drm_connector *connector, bool force)
 		if (dsi->panel)
 			drm_panel_attach(dsi->panel, &dsi->connector);
 	} else if (!dsi->panel_node) {
-		struct exynos_drm_encoder *encoder;
+		struct drm_encoder *encoder;
 
 		encoder = platform_get_drvdata(to_platform_device(dsi->dev));
 		exynos_dsi_disable(encoder);
@@ -1629,7 +1628,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dsi *dsi = connector_to_dsi(connector);
 
-	return &dsi->encoder.base;
+	return &dsi->encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
@@ -1637,11 +1636,9 @@ static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
 	.best_encoder = exynos_dsi_best_encoder,
 };
 
-static int exynos_dsi_create_connector(
-				struct exynos_drm_encoder *exynos_encoder)
+static int exynos_dsi_create_connector(struct drm_encoder *encoder)
 {
-	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct drm_connector *connector = &dsi->connector;
 	int ret;
 
@@ -1662,28 +1659,42 @@ static int exynos_dsi_create_connector(
 	return 0;
 }
 
-static void exynos_dsi_mode_set(struct exynos_drm_encoder *encoder,
-			 struct drm_display_mode *mode)
+static bool exynos_dsi_mode_fixup(struct drm_encoder *encoder,
+				  const struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_dsi_mode_set(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
 {
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct videomode *vm = &dsi->vm;
-
-	vm->hactive = mode->hdisplay;
-	vm->vactive = mode->vdisplay;
-	vm->vfront_porch = mode->vsync_start - mode->vdisplay;
-	vm->vback_porch = mode->vtotal - mode->vsync_end;
-	vm->vsync_len = mode->vsync_end - mode->vsync_start;
-	vm->hfront_porch = mode->hsync_start - mode->hdisplay;
-	vm->hback_porch = mode->htotal - mode->hsync_end;
-	vm->hsync_len = mode->hsync_end - mode->hsync_start;
+	struct drm_display_mode *m = adjusted_mode;
+
+	vm->hactive = m->hdisplay;
+	vm->vactive = m->vdisplay;
+	vm->vfront_porch = m->vsync_start - m->vdisplay;
+	vm->vback_porch = m->vtotal - m->vsync_end;
+	vm->vsync_len = m->vsync_end - m->vsync_start;
+	vm->hfront_porch = m->hsync_start - m->hdisplay;
+	vm->hback_porch = m->htotal - m->hsync_end;
+	vm->hsync_len = m->hsync_end - m->hsync_start;
 }
 
-static struct exynos_drm_encoder_ops exynos_dsi_encoder_ops = {
+static struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
+	.mode_fixup = exynos_dsi_mode_fixup,
 	.mode_set = exynos_dsi_mode_set,
 	.enable = exynos_dsi_enable,
 	.disable = exynos_dsi_disable,
 };
 
+static struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
 
 /* of_* functions will be removed after merge of of_graph patches */
@@ -1804,23 +1815,30 @@ end:
 static int exynos_dsi_bind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_encoder *exynos_encoder = dev_get_drvdata(dev);
-	struct exynos_dsi *dsi = encoder_to_dsi(exynos_encoder);
+	struct drm_encoder *encoder = dev_get_drvdata(dev);
+	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 	struct drm_device *drm_dev = data;
 	struct drm_bridge *bridge;
 	int ret;
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_LCD);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
+	ret = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_LCD);
+	if (ret < 0)
 		return ret;
-	}
 
-	ret = exynos_dsi_create_connector(exynos_encoder);
+	encoder->possible_crtcs = 1 << ret;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_dsi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_dsi_encoder_helper_funcs);
+
+	ret = exynos_dsi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
@@ -1835,7 +1853,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
 static void exynos_dsi_unbind(struct device *dev, struct device *master,
 				void *data)
 {
-	struct exynos_drm_encoder *encoder = dev_get_drvdata(dev);
+	struct drm_encoder *encoder = dev_get_drvdata(dev);
 	struct exynos_dsi *dsi = encoder_to_dsi(encoder);
 
 	exynos_dsi_disable(encoder);
@@ -1859,8 +1877,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	dsi->encoder.ops = &exynos_dsi_encoder_ops;
-
 	/* To be checked as invalid one */
 	dsi->te_gpio = -ENOENT;
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
deleted file mode 100644
index d45a5c5..0000000
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/* exynos_drm_encoder.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Authors:
- *	Inki Dae <inki.dae@samsung.com>
- *	Joonyoung Shim <jy0922.shim@samsung.com>
- *	Seung-Woo Kim <sw0312.kim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-
-#include "exynos_drm_drv.h"
-#include "exynos_drm_encoder.h"
-#include "exynos_drm_crtc.h"
-
-static bool
-exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
-			       const struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode)
-{
-	struct drm_device *dev = encoder->dev;
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-	struct drm_connector *connector;
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->encoder != encoder)
-			continue;
-
-		if (exynos_encoder->ops->mode_fixup)
-			exynos_encoder->ops->mode_fixup(exynos_encoder,
-							connector, mode,
-							adjusted_mode);
-	}
-
-	return true;
-}
-
-static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
-					 struct drm_display_mode *mode,
-					 struct drm_display_mode *adjusted_mode)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	if (exynos_encoder->ops->mode_set)
-		exynos_encoder->ops->mode_set(exynos_encoder, adjusted_mode);
-}
-
-static void exynos_drm_encoder_enable(struct drm_encoder *encoder)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	if (exynos_encoder->ops->enable)
-		exynos_encoder->ops->enable(exynos_encoder);
-}
-
-static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
-{
-	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
-
-	if (exynos_encoder->ops->disable)
-		exynos_encoder->ops->disable(exynos_encoder);
-}
-
-static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
-	.mode_fixup	= exynos_drm_encoder_mode_fixup,
-	.mode_set	= exynos_drm_encoder_mode_set,
-	.enable		= exynos_drm_encoder_enable,
-	.disable	= exynos_drm_encoder_disable,
-};
-
-static struct drm_encoder_funcs exynos_encoder_funcs = {
-	.destroy = drm_encoder_cleanup,
-};
-
-int exynos_drm_encoder_create(struct drm_device *dev,
-			      struct exynos_drm_encoder *exynos_encoder,
-			      enum exynos_drm_output_type type)
-{
-	struct drm_encoder *encoder;
-	int pipe;
-
-	pipe = exynos_drm_crtc_get_pipe_from_type(dev, type);
-	if (pipe < 0)
-		return pipe;
-
-	encoder = &exynos_encoder->base;
-	encoder->possible_crtcs = 1 << pipe;
-
-	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
-
-	drm_encoder_init(dev, encoder, &exynos_encoder_funcs,
-			DRM_MODE_ENCODER_TMDS);
-
-	drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs);
-
-	DRM_DEBUG_KMS("encoder has been created\n");
-
-	return 0;
-}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
deleted file mode 100644
index 6610dee..0000000
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * Authors:
- *	Inki Dae <inki.dae@samsung.com>
- *	Joonyoung Shim <jy0922.shim@samsung.com>
- *	Seung-Woo Kim <sw0312.kim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef _EXYNOS_DRM_ENCODER_H_
-#define _EXYNOS_DRM_ENCODER_H_
-
-#include "exynos_drm_drv.h"
-
-int exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_encoder
-			      *encoder, enum exynos_drm_output_type type);
-
-#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 6c0d3de..5def6bc 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -169,7 +169,7 @@ struct fimd_context {
 
 	struct exynos_drm_panel_info panel;
 	struct fimd_driver_data *driver_data;
-	struct exynos_drm_encoder *encoder;
+	struct drm_encoder *encoder;
 };
 
 static const struct of_device_id fimd_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 9b64c77..581af35 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -25,7 +25,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_plane.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_drm_vidi.h"
 
 /* vidi has totally three virtual windows. */
@@ -35,7 +34,7 @@
 					connector)
 
 struct vidi_context {
-	struct exynos_drm_encoder	encoder;
+	struct drm_encoder		encoder;
 	struct platform_device		*pdev;
 	struct drm_device		*drm_dev;
 	struct exynos_drm_crtc		*crtc;
@@ -54,7 +53,7 @@ struct vidi_context {
 	int				pipe;
 };
 
-static inline struct vidi_context *encoder_to_vidi(struct exynos_drm_encoder *e)
+static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e)
 {
 	return container_of(e, struct vidi_context, encoder);
 }
@@ -358,7 +357,7 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
 {
 	struct vidi_context *ctx = ctx_from_connector(connector);
 
-	return &ctx->encoder.base;
+	return &ctx->encoder;
 }
 
 static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
@@ -366,10 +365,9 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
 	.best_encoder = vidi_best_encoder,
 };
 
-static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
+static int vidi_create_connector(struct drm_encoder *encoder)
 {
-	struct vidi_context *ctx = encoder_to_vidi(exynos_encoder);
-	struct drm_encoder *encoder = &exynos_encoder->base;
+	struct vidi_context *ctx = encoder_to_vidi(encoder);
 	struct drm_connector *connector = &ctx->connector;
 	int ret;
 
@@ -389,15 +387,47 @@ static int vidi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 	return 0;
 }
 
+static bool exynos_vidi_mode_fixup(struct drm_encoder *encoder,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_vidi_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void exynos_vidi_enable(struct drm_encoder *encoder)
+{
+}
+
+static void exynos_vidi_disable(struct drm_encoder *encoder)
+{
+}
+
+static struct drm_encoder_helper_funcs exynos_vidi_encoder_helper_funcs = {
+	.mode_fixup = exynos_vidi_mode_fixup,
+	.mode_set = exynos_vidi_mode_set,
+	.enable = exynos_vidi_enable,
+	.disable = exynos_vidi_disable,
+};
+
+static struct drm_encoder_funcs exynos_vidi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static int vidi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct vidi_context *ctx = dev_get_drvdata(dev);
 	struct drm_device *drm_dev = data;
-	struct exynos_drm_encoder *exynos_encoder = &ctx->encoder;
+	struct drm_encoder *encoder = &ctx->encoder;
 	struct exynos_drm_plane *exynos_plane;
 	enum drm_plane_type type;
 	unsigned int zpos;
-	int ret;
+	int pipe, ret;
 
 	vidi_ctx_initialize(ctx, drm_dev);
 
@@ -419,17 +449,24 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
 		return PTR_ERR(ctx->crtc);
 	}
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_VIDI);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
+	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_VIDI);
+	if (pipe < 0)
+		return pipe;
+
+	encoder->possible_crtcs = 1 << pipe;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_vidi_encoder_helper_funcs);
 
-	ret = vidi_create_connector(exynos_encoder);
+	ret = vidi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 148e42f..932f7fa 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -44,7 +44,6 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
-#include "exynos_drm_encoder.h"
 #include "exynos_mixer.h"
 
 #include <linux/gpio.h>
@@ -88,7 +87,7 @@ struct hdmi_resources {
 };
 
 struct hdmi_context {
-	struct exynos_drm_encoder	encoder;
+	struct drm_encoder		encoder;
 	struct device			*dev;
 	struct drm_device		*drm_dev;
 	struct drm_connector		connector;
@@ -116,7 +115,7 @@ struct hdmi_context {
 	struct regmap			*pmureg;
 };
 
-static inline struct hdmi_context *encoder_to_hdmi(struct exynos_drm_encoder *e)
+static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
 {
 	return container_of(e, struct hdmi_context, encoder);
 }
@@ -1032,7 +1031,7 @@ static struct drm_encoder *hdmi_best_encoder(struct drm_connector *connector)
 {
 	struct hdmi_context *hdata = ctx_from_connector(connector);
 
-	return &hdata->encoder.base;
+	return &hdata->encoder;
 }
 
 static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
@@ -1041,9 +1040,9 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
 	.best_encoder = hdmi_best_encoder,
 };
 
-static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
+static int hdmi_create_connector(struct drm_encoder *encoder)
 {
-	struct hdmi_context *hdata = encoder_to_hdmi(exynos_encoder);
+	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct drm_connector *connector = &hdata->connector;
 	int ret;
 
@@ -1059,28 +1058,35 @@ static int hdmi_create_connector(struct exynos_drm_encoder *exynos_encoder)
 
 	drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
 	drm_connector_register(connector);
-	drm_mode_connector_attach_encoder(connector, &exynos_encoder->base);
+	drm_mode_connector_attach_encoder(connector, encoder);
 
 	return 0;
 }
 
-static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
-				struct drm_connector *connector,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+static bool hdmi_mode_fixup(struct drm_encoder *encoder,
+			    const struct drm_display_mode *mode,
+			    struct drm_display_mode *adjusted_mode)
 {
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector;
 	struct drm_display_mode *m;
 	int mode_ok;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder == encoder)
+			break;
+	}
+
+	if (connector->encoder != encoder)
+		return true;
+
 	mode_ok = hdmi_mode_valid(connector, adjusted_mode);
 
 	/* just return if user desired mode exists. */
 	if (mode_ok == MODE_OK)
-		return;
+		return true;
 
 	/*
 	 * otherwise, find the most suitable mode among modes and change it
@@ -1100,6 +1106,8 @@ static void hdmi_mode_fixup(struct exynos_drm_encoder *encoder,
 			break;
 		}
 	}
+
+	return true;
 }
 
 static void hdmi_set_acr(u32 freq, u8 *acr)
@@ -1697,22 +1705,23 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
 	hdmi_regs_dump(hdata, "start");
 }
 
-static void hdmi_mode_set(struct exynos_drm_encoder *encoder,
-			struct drm_display_mode *mode)
+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 = mode;
+	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, mode);
+	drm_mode_copy(&hdata->current_mode, m);
 	hdata->cea_video_id = drm_match_cea_mode(mode);
 }
 
-static void hdmi_enable(struct exynos_drm_encoder *encoder)
+static void hdmi_enable(struct drm_encoder *encoder)
 {
 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct hdmi_resources *res = &hdata->res;
@@ -1738,11 +1747,11 @@ static void hdmi_enable(struct exynos_drm_encoder *encoder)
 	hdmi_conf_apply(hdata);
 }
 
-static void hdmi_disable(struct exynos_drm_encoder *encoder)
+static void hdmi_disable(struct drm_encoder *encoder)
 {
 	struct hdmi_context *hdata = encoder_to_hdmi(encoder);
 	struct hdmi_resources *res = &hdata->res;
-	struct drm_crtc *crtc = hdata->encoder.base.crtc;
+	struct drm_crtc *crtc = encoder->crtc;
 	const struct drm_crtc_helper_funcs *funcs = NULL;
 
 	if (!hdata->powered)
@@ -1783,13 +1792,17 @@ static void hdmi_disable(struct exynos_drm_encoder *encoder)
 	hdata->powered = false;
 }
 
-static struct exynos_drm_encoder_ops hdmi_encoder_ops = {
+static 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,
 };
 
+static struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
 static void hdmi_hotplug_work_func(struct work_struct *work)
 {
 	struct hdmi_context *hdata;
@@ -1917,22 +1930,29 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
 {
 	struct drm_device *drm_dev = data;
 	struct hdmi_context *hdata = dev_get_drvdata(dev);
-	struct exynos_drm_encoder *exynos_encoder = &hdata->encoder;
-	int ret;
+	struct drm_encoder *encoder = &hdata->encoder;
+	int ret, pipe;
 
 	hdata->drm_dev = drm_dev;
 
-	ret = exynos_drm_encoder_create(drm_dev, exynos_encoder,
-					EXYNOS_DISPLAY_TYPE_HDMI);
-	if (ret) {
-		DRM_ERROR("failed to create encoder\n");
-		return ret;
-	}
+	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
+						  EXYNOS_DISPLAY_TYPE_HDMI);
+	if (pipe < 0)
+		return pipe;
+
+	encoder->possible_crtcs = 1 << pipe;
+
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	drm_encoder_init(drm_dev, encoder, &exynos_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	drm_encoder_helper_add(encoder, &exynos_hdmi_encoder_helper_funcs);
 
-	ret = hdmi_create_connector(exynos_encoder);
+	ret = hdmi_create_connector(encoder);
 	if (ret) {
 		DRM_ERROR("failed to create connector ret = %d\n", ret);
-		drm_encoder_cleanup(&exynos_encoder->base);
+		drm_encoder_cleanup(encoder);
 		return ret;
 	}
 
@@ -1985,7 +2005,6 @@ static int hdmi_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	hdata->drv_data = match->data;
-	hdata->encoder.ops = &hdmi_encoder_ops;
 
 	platform_set_drvdata(pdev, hdata);
 
-- 
2.1.0

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

* Re: [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer
  2015-08-15 14:33                 ` Inki Dae
@ 2015-08-15 15:22                   ` Gustavo Padovan
  0 siblings, 0 replies; 27+ messages in thread
From: Gustavo Padovan @ 2015-08-15 15:22 UTC (permalink / raw)
  To: Inki Dae
  Cc: Gustavo Padovan, linux-samsung-soc, DRI mailing list,
	Joonyoung Shim, Tobias Jakobi

Hi Inki,

2015-08-15 Inki Dae <inki.dae@samsung.com>:

> 2015-08-13 0:54 GMT+09:00 Gustavo Padovan <gustavo@padovan.org>:
> > 2015-08-12 Gustavo Padovan <gustavo.padovan@collabora.co.uk>:
> >
> >> Hi Inki,
> >>
> >> 2015-08-11 Inki Dae <inki.dae@samsung.com>:
> >>
> >> > On 2015년 08월 11일 09:38, Gustavo Padovan wrote:
> >> > > Hi Inki,
> >> > >
> >> > > 2015-08-07 Inki Dae <inki.dae@samsung.com>:
> >> > >
> >> > >> Hi Gustavo,
> >> > >>
> >> > >> On 2015년 08월 06일 22:31, Gustavo Padovan wrote:
> >> > >>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >> > >>>
> >> > >>> struct exynos_drm_encoder was justing wrapping struct drm_encoder, it had
> >> > >>> only a drm_encoder member and the internal exynos_drm_encoders ops that
> >> > >>> was directly mapped to the drm_encoder helper funcs.
> >> > >>>
> >> > >>> So now exynos DRM uses struct drm_encoder directly, this removes
> >> > >>> completely the struct exynos_drm_encoder.
> >> > >>>
> >> > >>
> >> > >> Trats2 board, which uses Exynos4412 Soc, doesn't work after this patch
> >> > >> is applied. Below is the booting logs,
> >> > >> [    1.171318] console [ttySAC2] enabled
> >> > >> [    1.175522] 13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 60,
> >> > >> base_baud = 0) is a S3C6400/10
> >> > >> [    1.185545] [drm] Initialized drm 1.1.0 20060810
> >> > >> [    1.194104] exynos-drm exynos-drm: bound 11c00000.fimd (ops
> >> > >> fimd_component_ops)
> >> > >> [    1.200352] exynos-drm exynos-drm: bound 11c80000.dsi (ops
> >> > >> exynos_dsi_component_ops)
> >> > >> [    1.207688] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> >> > >> [    1.214313] [drm] No driver support for vblank timestamp query.
> >> > >> [    1.220218] [drm] Initialized exynos 1.0.0 20110530 on minor 0
> >> > >>
> >> > >> Booting is locked up here. This patch looks good to me so I tried to
> >> > >> find why locked up and I found the booting is locked up as soon as
> >> > >> console_lock function is called. Can you and other guys look into this
> >> > >> issue?
> >> > >
> >> > > I've realized that I left a fix for patch 01 behind, it could be the
> >> > > cause of this issue. I've just resent this patch with the added v2 fix
> >> > > up.
> >> >
> >> > With above change, still locked up. So your updated patch doesn't
> >> > resolve this issue.
> >> >
> >> > Anyway, I tested it with fbdev emulation relevant patch series[1] and
> >> > the booting was ok with disabling fbdev emulation as Daniel commented.
> >> > However, I think the booting should also be ok with fbdev emulation so I
> >> > don't want for your last patch to be merged to mainline until the issue
> >> > is resolved.
> >>
> >> I've tried to reproduce your issue with these patches on a odroid-x2
> >> (exynos4412) but it seems to work fine for me with fbdev emulation
> >> enabled. In snow and peach-pi it also works fine. We would need
> >> to debug better on your side to figure out what is breaking for you.
> >
> > Can you please git bisect this? So we can figure out which commit is
> > causing the issue. That would be great.
> 
> I already commented above, your last patch - 11/11. Without 11/11, it
> worked well. Did you test odroid-x2 with LVDS based Display panel? If
> so, it's not different because I tested it with Trats2 board with
> MIPI-DSI + Display panel. AFAIK, Odroid-x2 board doesn't support
> MIPI-DSI panel. I will have a pull request soon without 11/11. After
> that, I think we could find and resolve the issue later.

Ah, I thougth your talking about whole patchset! I think I figured out
what was happend the .mode_fixup() and .mode_set() helpers for the DSI
drm_encoder was not set and leading to a null pointer at some pointer.
That is problably what you were experiencing. Could you please try the
new version of patch 11/11 that I've just sent to the mailing list?
And thanks for merging these patches!

	Gustavo

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

end of thread, other threads:[~2015-08-15 15:22 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-05 23:24 [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 01/11] drm/exynos: split display's .dpms() into .enable() and .disable() Gustavo Padovan
2015-08-11  0:37   ` [PATCH " Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 02/11] drm/exynos: remove wrappers for phy_power_{on,off} Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 03/11] drm/exynos: remove unused .remove() and .check_mode() ops from display Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 04/11] drm/exynos: simplify calculation of possible CRTCs Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 05/11] drm/exynos: remove struct exynos_drm_display Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 06/11] drm/exynos: remove extra call to hdmi_commit() Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 07/11] drm/exynos: remove extra call to exynos_dp_commit() Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 08/11] drm/exynos: remove exynos_encoder's .commit() op Gustavo Padovan
2015-08-05 23:24 ` [PATCH v2 09/11] drm/exynos: remove exynos_drm_create_enc_conn() Gustavo Padovan
2015-08-06 13:31   ` [PATCH v2 10/11] drm/exynos: fold encoder setup into exynos_drm_load() Gustavo Padovan
2015-08-06 13:31     ` [PATCH v2 11/11] drm/exynos: remove struct exynos_drm_encoder layer Gustavo Padovan
2015-08-07 11:50       ` Inki Dae
2015-08-07 12:28         ` Daniel Vetter
2015-08-07 13:22           ` Inki Dae
2015-08-11  0:38         ` Gustavo Padovan
2015-08-11 12:13           ` Inki Dae
2015-08-11 15:03             ` Daniel Vetter
2015-08-12  2:53               ` Inki Dae
2015-08-12 15:49             ` Gustavo Padovan
2015-08-12 15:54               ` Gustavo Padovan
2015-08-15 14:33                 ` Inki Dae
2015-08-15 15:22                   ` Gustavo Padovan
2015-08-15 15:14       ` [PATCH -v3 " Gustavo Padovan
2015-08-06 11:55 ` [PATCH v2 00/11] drm/exynos: remove exynos_drm_display and exynos_drm_encoder Inki Dae
2015-08-06 13:27   ` Gustavo Padovan

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.