drm/exynos: remove struct exynos_drm_encoder layer
authorGustavo Padovan <gustavo.padovan@collabora.co.uk>
Sat, 15 Aug 2015 15:14:08 +0000 (12:14 -0300)
committerInki Dae <inki.dae@samsung.com>
Sun, 16 Aug 2015 01:35:54 +0000 (10:35 +0900)
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>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
15 files changed:
drivers/gpu/drm/exynos/Makefile
drivers/gpu/drm/exynos/exynos7_drm_decon.c
drivers/gpu/drm/exynos/exynos_dp_core.c
drivers/gpu/drm/exynos/exynos_dp_core.h
drivers/gpu/drm/exynos/exynos_drm_core.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_dpi.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_encoder.c [deleted file]
drivers/gpu/drm/exynos/exynos_drm_encoder.h [deleted file]
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c

index 7de0b1084fcd31e362a5fdeca6f1ecd20a07f720..61c290656f21e23bcb7de820cc418f83b0c4f96c 100644 (file)
@@ -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
index e1a2ce751871d0051ad61d0097d7e23c56d06b3f..07926547c94ff733090db523a2cb0be2ffa7e150 100644 (file)
@@ -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[] = {
index 67c5cd19721d009c9234e353ce485b4475553cdb..d66ade0efac892b84ce7e26c4f9e132870806d33 100644 (file)
 #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);
index f8cc20207dbd8cbf3ce426206937f4bb13a1f24c..e413b6f7b0e7d947f3d1d58a91fc99151ab97a34 100644 (file)
@@ -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;
index 1f38a44a5e84b1c753da609b0883906c0f43fbc8..c68a6a2a9b5794558015abdeefb0e58c4958049d 100644 (file)
@@ -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);
index 21427cca0a4960c3d7f6a1f7e7d8d56ae720c14e..c47899738eb48fe44ff60681fff06b9122afaed8 100644 (file)
@@ -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)
index 6850ce5a0e97a07e7a573476040a00888d5c3688..c748b8790de3ecad22bcd2c5f6276a4223ccfd10 100644 (file)
 #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);
 
index 105f10ef39562c1fda188bb4b9ceb290373f5576..6675e7668d60b5ca6c5595f15ac3b9d4ac50c3ab 100644 (file)
@@ -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"
index a4977bee319535c2ea3cc10d92f8ad659bc09a29..6b8a30f23473d694e68e302aeb4f3593147f1c35 100644 (file)
@@ -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)
 
@@ -77,40 +76,6 @@ struct exynos_drm_plane {
        unsigned int zpos;
 };
 
-/*
- * 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
  *
@@ -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;
 }
index d791ad48981daed973ba7fae281473bb44b715f3..12b03b3647034134411ffd1723f5c3c8141c979c 100644 (file)
@@ -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 (file)
index d45a5c5..0000000
+++ /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 (file)
index 6610dee..0000000
+++ /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
index 6c0d3defd1c2fd637a4270ecc3ca895b5dfd5cd2..5def6bc073ebb222ea4656a865108efd557a0eb2 100644 (file)
@@ -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[] = {
index 9b64c7771516dd11029e29e73369b7c65cd4bbdc..581af35861a6fcd5781cf207d5c1a821c0583d0d 100644 (file)
@@ -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;
        }
 
index 148e42fe1a516140872e5b23ea1c64db0ccda420..932f7fa240f83cface947f21fb30dd3684f8d7c8 100644 (file)
@@ -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);