struct imx_hdmi {
        struct drm_connector connector;
-       struct imx_drm_connector *imx_drm_connector;
        struct drm_encoder encoder;
-       struct imx_drm_encoder *imx_drm_encoder;
 
        enum imx_hdmi_devtype dev_type;
        struct device *dev;
        return connector_status_connected;
 }
 
-static void imx_hdmi_connector_destroy(struct drm_connector *connector)
-{
-}
-
 static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
 {
        struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
        imx_hdmi_poweron(hdmi);
 }
 
-static void imx_hdmi_encoder_destroy(struct drm_encoder *encoder)
-{
-       return;
-}
-
 static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
-       .destroy = imx_hdmi_encoder_destroy,
+       .destroy = imx_drm_encoder_destroy,
 };
 
 static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
        .dpms = drm_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = imx_hdmi_connector_detect,
-       .destroy = imx_hdmi_connector_destroy,
+       .destroy = imx_drm_connector_destroy,
 };
 
 static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
        return IRQ_HANDLED;
 }
 
-static int imx_hdmi_register(struct imx_hdmi *hdmi)
+static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
 {
        int ret;
 
-       hdmi->connector.funcs = &imx_hdmi_connector_funcs;
-       hdmi->encoder.funcs = &imx_hdmi_encoder_funcs;
-
-       hdmi->encoder.encoder_type = DRM_MODE_ENCODER_TMDS;
-       hdmi->connector.connector_type = DRM_MODE_CONNECTOR_HDMIA;
+       ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
+                                      hdmi->dev->of_node);
+       if (ret)
+               return ret;
 
        drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
-       ret = imx_drm_add_encoder(&hdmi->encoder, &hdmi->imx_drm_encoder,
-                       THIS_MODULE);
-       if (ret) {
-               dev_err(hdmi->dev, "adding encoder failed: %d\n", ret);
-               return ret;
-       }
+       drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
+                        DRM_MODE_ENCODER_TMDS);
 
        drm_connector_helper_add(&hdmi->connector,
                        &imx_hdmi_connector_helper_funcs);
-
-       ret = imx_drm_add_connector(&hdmi->connector,
-                       &hdmi->imx_drm_connector, THIS_MODULE);
-       if (ret) {
-               imx_drm_remove_encoder(hdmi->imx_drm_encoder);
-               dev_err(hdmi->dev, "adding connector failed: %d\n", ret);
-               return ret;
-       }
+       drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
+                          DRM_MODE_CONNECTOR_HDMIA);
 
        hdmi->connector.encoder = &hdmi->encoder;
 
        struct platform_device *pdev = to_platform_device(dev);
        const struct of_device_id *of_id =
                                of_match_device(imx_hdmi_dt_ids, dev);
+       struct drm_device *drm = data;
        struct device_node *np = dev->of_node;
        struct device_node *ddc_node;
        struct imx_hdmi *hdmi;
        if (ret)
                goto err_iahb;
 
-       ret = imx_hdmi_register(hdmi);
+       ret = imx_hdmi_register(drm, hdmi);
        if (ret)
                goto err_iahb;
 
-       imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np);
-
        dev_set_drvdata(dev, hdmi);
 
        return 0;
        void *data)
 {
        struct imx_hdmi *hdmi = dev_get_drvdata(dev);
-       struct drm_connector *connector = &hdmi->connector;
-       struct drm_encoder *encoder = &hdmi->encoder;
 
-       drm_mode_connector_detach_encoder(connector, encoder);
-       imx_drm_remove_connector(hdmi->imx_drm_connector);
-       imx_drm_remove_encoder(hdmi->imx_drm_encoder);
+       hdmi->connector.funcs->destroy(&hdmi->connector);
+       hdmi->encoder.funcs->destroy(&hdmi->encoder);
 
        clk_disable_unprepare(hdmi->iahb_clk);
        clk_disable_unprepare(hdmi->isfr_clk);
 
 struct imx_ldb_channel {
        struct imx_ldb *ldb;
        struct drm_connector connector;
-       struct imx_drm_connector *imx_drm_connector;
        struct drm_encoder encoder;
-       struct imx_drm_encoder *imx_drm_encoder;
+       struct device_node *child;
        int chno;
        void *edid;
        int edid_len;
        return connector_status_connected;
 }
 
-static void imx_ldb_connector_destroy(struct drm_connector *connector)
-{
-       /* do not free here */
-}
-
 static int imx_ldb_connector_get_modes(struct drm_connector *connector)
 {
        struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
        }
 }
 
-static void imx_ldb_encoder_destroy(struct drm_encoder *encoder)
-{
-       /* do not free here */
-}
-
 static struct drm_connector_funcs imx_ldb_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = imx_ldb_connector_detect,
-       .destroy = imx_ldb_connector_destroy,
+       .destroy = imx_drm_connector_destroy,
 };
 
 static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
 };
 
 static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
-       .destroy = imx_ldb_encoder_destroy,
+       .destroy = imx_drm_encoder_destroy,
 };
 
 static struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
        return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]);
 }
 
-static int imx_ldb_register(struct imx_ldb_channel *imx_ldb_ch)
+static int imx_ldb_register(struct drm_device *drm,
+       struct imx_ldb_channel *imx_ldb_ch)
 {
-       int ret;
        struct imx_ldb *ldb = imx_ldb_ch->ldb;
+       int ret;
+
+       ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder,
+                                      imx_ldb_ch->child);
+       if (ret)
+               return ret;
 
        ret = imx_ldb_get_clk(ldb, imx_ldb_ch->chno);
        if (ret)
                return ret;
+
        if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
-               ret |= imx_ldb_get_clk(ldb, 1);
+               ret = imx_ldb_get_clk(ldb, 1);
                if (ret)
                        return ret;
        }
 
-       imx_ldb_ch->connector.funcs = &imx_ldb_connector_funcs;
-       imx_ldb_ch->encoder.funcs = &imx_ldb_encoder_funcs;
-
-       imx_ldb_ch->encoder.encoder_type = DRM_MODE_ENCODER_LVDS;
-       imx_ldb_ch->connector.connector_type = DRM_MODE_CONNECTOR_LVDS;
-
        drm_encoder_helper_add(&imx_ldb_ch->encoder,
                        &imx_ldb_encoder_helper_funcs);
-       ret = imx_drm_add_encoder(&imx_ldb_ch->encoder,
-                       &imx_ldb_ch->imx_drm_encoder, THIS_MODULE);
-       if (ret) {
-               dev_err(ldb->dev, "adding encoder failed with %d\n", ret);
-               return ret;
-       }
+       drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs,
+                        DRM_MODE_ENCODER_LVDS);
 
        drm_connector_helper_add(&imx_ldb_ch->connector,
                        &imx_ldb_connector_helper_funcs);
-
-       ret = imx_drm_add_connector(&imx_ldb_ch->connector,
-                       &imx_ldb_ch->imx_drm_connector, THIS_MODULE);
-       if (ret) {
-               imx_drm_remove_encoder(imx_ldb_ch->imx_drm_encoder);
-               dev_err(ldb->dev, "adding connector failed with %d\n", ret);
-               return ret;
-       }
+       drm_connector_init(drm, &imx_ldb_ch->connector,
+                          &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
 
        drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
                        &imx_ldb_ch->encoder);
 
 static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
 {
+       struct drm_device *drm = data;
        struct device_node *np = dev->of_node;
        const struct of_device_id *of_id =
                        of_match_device(imx_ldb_dt_ids, dev);
                channel = &imx_ldb->channel[i];
                channel->ldb = imx_ldb;
                channel->chno = i;
+               channel->child = child;
 
                edidp = of_get_property(child, "edid", &channel->edid_len);
                if (edidp) {
                        return -EINVAL;
                }
 
-               ret = imx_ldb_register(channel);
+               ret = imx_ldb_register(drm, channel);
                if (ret)
                        return ret;
-
-               imx_drm_encoder_add_possible_crtcs(channel->imx_drm_encoder, child);
        }
 
        dev_set_drvdata(dev, imx_ldb);
 
        for (i = 0; i < 2; i++) {
                struct imx_ldb_channel *channel = &imx_ldb->channel[i];
-               struct drm_connector *connector = &channel->connector;
-               struct drm_encoder *encoder = &channel->encoder;
-
-               drm_mode_connector_detach_encoder(connector, encoder);
 
-               imx_drm_remove_connector(channel->imx_drm_connector);
-               imx_drm_remove_encoder(channel->imx_drm_encoder);
+               channel->connector.funcs->destroy(&channel->connector);
+               channel->encoder.funcs->destroy(&channel->encoder);
        }
 }
 
 
 
 struct imx_tve {
        struct drm_connector connector;
-       struct imx_drm_connector *imx_drm_connector;
        struct drm_encoder encoder;
-       struct imx_drm_encoder *imx_drm_encoder;
        struct device *dev;
        spinlock_t lock;        /* register lock */
        bool enabled;
        return connector_status_connected;
 }
 
-static void imx_tve_connector_destroy(struct drm_connector *connector)
-{
-       /* do not free here */
-}
-
 static int imx_tve_connector_get_modes(struct drm_connector *connector)
 {
        struct imx_tve *tve = con_to_tve(connector);
        tve_disable(tve);
 }
 
-static void imx_tve_encoder_destroy(struct drm_encoder *encoder)
-{
-       /* do not free here */
-}
-
 static struct drm_connector_funcs imx_tve_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = imx_tve_connector_detect,
-       .destroy = imx_tve_connector_destroy,
+       .destroy = imx_drm_connector_destroy,
 };
 
 static struct drm_connector_helper_funcs imx_tve_connector_helper_funcs = {
 };
 
 static struct drm_encoder_funcs imx_tve_encoder_funcs = {
-       .destroy = imx_tve_encoder_destroy,
+       .destroy = imx_drm_encoder_destroy,
 };
 
 static struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = {
        return 0;
 }
 
-static int imx_tve_register(struct imx_tve *tve)
+static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
 {
        int encoder_type;
        int ret;
        encoder_type = tve->mode == TVE_MODE_VGA ?
                                DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
 
-       tve->connector.funcs = &imx_tve_connector_funcs;
-       tve->encoder.funcs = &imx_tve_encoder_funcs;
-
-       tve->encoder.encoder_type = encoder_type;
-       tve->connector.connector_type = DRM_MODE_CONNECTOR_VGA;
+       ret = imx_drm_encoder_parse_of(drm, &tve->encoder,
+                                      tve->dev->of_node);
+       if (ret)
+               return ret;
 
        drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs);
-       ret = imx_drm_add_encoder(&tve->encoder, &tve->imx_drm_encoder,
-                       THIS_MODULE);
-       if (ret) {
-               dev_err(tve->dev, "adding encoder failed with %d\n", ret);
-               return ret;
-       }
+       drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs,
+                        encoder_type);
 
        drm_connector_helper_add(&tve->connector,
                        &imx_tve_connector_helper_funcs);
-
-       ret = imx_drm_add_connector(&tve->connector,
-                       &tve->imx_drm_connector, THIS_MODULE);
-       if (ret) {
-               imx_drm_remove_encoder(tve->imx_drm_encoder);
-               dev_err(tve->dev, "adding connector failed with %d\n", ret);
-               return ret;
-       }
+       drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs,
+                          DRM_MODE_CONNECTOR_VGA);
 
        drm_mode_connector_attach_encoder(&tve->connector, &tve->encoder);
 
 static int imx_tve_bind(struct device *dev, struct device *master, void *data)
 {
        struct platform_device *pdev = to_platform_device(dev);
+       struct drm_device *drm = data;
        struct device_node *np = dev->of_node;
        struct device_node *ddc_node;
        struct imx_tve *tve;
        /* disable cable detection for VGA mode */
        ret = regmap_write(tve->regmap, TVE_CD_CONT_REG, 0);
 
-       ret = imx_tve_register(tve);
+       ret = imx_tve_register(drm, tve);
        if (ret)
                return ret;
 
-       ret = imx_drm_encoder_add_possible_crtcs(tve->imx_drm_encoder, np);
-
        dev_set_drvdata(dev, tve);
 
        return 0;
        void *data)
 {
        struct imx_tve *tve = dev_get_drvdata(dev);
-       struct drm_connector *connector = &tve->connector;
-       struct drm_encoder *encoder = &tve->encoder;
-
-       drm_mode_connector_detach_encoder(connector, encoder);
 
-       imx_drm_remove_connector(tve->imx_drm_connector);
-       imx_drm_remove_encoder(tve->imx_drm_encoder);
+       tve->connector.funcs->destroy(&tve->connector);
+       tve->encoder.funcs->destroy(&tve->encoder);
 
        if (!IS_ERR(tve->dac_reg))
                regulator_disable(tve->dac_reg);
 
 
 struct imx_parallel_display {
        struct drm_connector connector;
-       struct imx_drm_connector *imx_drm_connector;
        struct drm_encoder encoder;
-       struct imx_drm_encoder *imx_drm_encoder;
        struct device *dev;
        void *edid;
        int edid_len;
        return connector_status_connected;
 }
 
-static void imx_pd_connector_destroy(struct drm_connector *connector)
-{
-       /* do not free here */
-}
-
 static int imx_pd_connector_get_modes(struct drm_connector *connector)
 {
        struct imx_parallel_display *imxpd = con_to_imxpd(connector);
 {
 }
 
-static void imx_pd_encoder_destroy(struct drm_encoder *encoder)
-{
-       /* do not free here */
-}
-
 static struct drm_connector_funcs imx_pd_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = imx_pd_connector_detect,
-       .destroy = imx_pd_connector_destroy,
+       .destroy = imx_drm_connector_destroy,
 };
 
 static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
 };
 
 static struct drm_encoder_funcs imx_pd_encoder_funcs = {
-       .destroy = imx_pd_encoder_destroy,
+       .destroy = imx_drm_encoder_destroy,
 };
 
 static struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
        .disable = imx_pd_encoder_disable,
 };
 
-static int imx_pd_register(struct imx_parallel_display *imxpd)
+static int imx_pd_register(struct drm_device *drm,
+       struct imx_parallel_display *imxpd)
 {
        int ret;
 
-       drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
-
-       imxpd->connector.funcs = &imx_pd_connector_funcs;
-       imxpd->encoder.funcs = &imx_pd_encoder_funcs;
-
-       imxpd->encoder.encoder_type = DRM_MODE_ENCODER_NONE;
-       imxpd->connector.connector_type = DRM_MODE_CONNECTOR_VGA;
+       ret = imx_drm_encoder_parse_of(drm, &imxpd->encoder,
+                                      imxpd->dev->of_node);
+       if (ret)
+               return ret;
 
        drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs);
-       ret = imx_drm_add_encoder(&imxpd->encoder, &imxpd->imx_drm_encoder,
-                       THIS_MODULE);
-       if (ret) {
-               dev_err(imxpd->dev, "adding encoder failed with %d\n", ret);
-               return ret;
-       }
+       drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs,
+                        DRM_MODE_ENCODER_NONE);
 
        drm_connector_helper_add(&imxpd->connector,
                        &imx_pd_connector_helper_funcs);
+       drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs,
+                          DRM_MODE_CONNECTOR_VGA);
 
-       ret = imx_drm_add_connector(&imxpd->connector,
-                       &imxpd->imx_drm_connector, THIS_MODULE);
-       if (ret) {
-               imx_drm_remove_encoder(imxpd->imx_drm_encoder);
-               dev_err(imxpd->dev, "adding connector failed with %d\n", ret);
-               return ret;
-       }
+       drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
 
        imxpd->connector.encoder = &imxpd->encoder;
 
 
 static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 {
+       struct drm_device *drm = data;
        struct device_node *np = dev->of_node;
        const u8 *edidp;
        struct imx_parallel_display *imxpd;
 
        imxpd->dev = dev;
 
-       ret = imx_pd_register(imxpd);
+       ret = imx_pd_register(drm, imxpd);
        if (ret)
                return ret;
 
-       ret = imx_drm_encoder_add_possible_crtcs(imxpd->imx_drm_encoder, np);
-
        dev_set_drvdata(dev, imxpd);
 
        return 0;
        void *data)
 {
        struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
-       struct drm_connector *connector = &imxpd->connector;
-       struct drm_encoder *encoder = &imxpd->encoder;
-
-       drm_mode_connector_detach_encoder(connector, encoder);
 
-       imx_drm_remove_connector(imxpd->imx_drm_connector);
-       imx_drm_remove_encoder(imxpd->imx_drm_encoder);
+       imxpd->encoder.funcs->destroy(&imxpd->encoder);
+       imxpd->connector.funcs->destroy(&imxpd->connector);
 }
 
 static const struct component_ops imx_pd_ops = {