drm: rcar-du: Replace manual bridge implementation with DRM bridge
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Fri, 7 Oct 2016 13:01:41 +0000 (16:01 +0300)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tue, 4 Apr 2017 14:04:02 +0000 (17:04 +0300)
The rcar-du driver contains a manual implementation of HDMI and VGA
bridges. Use DRM bridges to replace it.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/gpu/drm/rcar-du/Kconfig
drivers/gpu/drm/rcar-du/Makefile
drivers/gpu/drm/rcar-du/rcar_du_encoder.c
drivers/gpu/drm/rcar-du/rcar_du_encoder.h
drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c [deleted file]
drivers/gpu/drm/rcar-du/rcar_du_hdmienc.h [deleted file]
drivers/gpu/drm/rcar-du/rcar_du_vgacon.c [deleted file]
drivers/gpu/drm/rcar-du/rcar_du_vgacon.h [deleted file]

index 2bab449add7689388a71305ef512f687772c158b..06121eeba9e5ba29f5a5c2df67f0261fb5b60946 100644 (file)
@@ -11,12 +11,6 @@ config DRM_RCAR_DU
          Choose this option if you have an R-Car chipset.
          If M is selected the module will be called rcar-du-drm.
 
-config DRM_RCAR_HDMI
-       bool "R-Car DU HDMI Encoder Support"
-       depends on DRM_RCAR_DU
-       help
-         Enable support for external HDMI encoders.
-
 config DRM_RCAR_LVDS
        bool "R-Car DU LVDS Encoder Support"
        depends on DRM_RCAR_DU
index d3b44651061aa1799988d3d741986c8ed8bc644d..a492e6858691ec4aa02c4737b503827eea3605d0 100644 (file)
@@ -4,10 +4,7 @@ rcar-du-drm-y := rcar_du_crtc.o \
                 rcar_du_group.o \
                 rcar_du_kms.o \
                 rcar_du_lvdscon.o \
-                rcar_du_plane.o \
-                rcar_du_vgacon.o
-
-rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI)    += rcar_du_hdmienc.o
+                rcar_du_plane.o
 
 rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS)    += rcar_du_lvdsenc.o
 
index 3a3c9374794e3ffe8d014023aca8d93c64c6594a..92a0405c2fb25467b0d70a6258adb2a5c0a621c8 100644 (file)
 
 #include "rcar_du_drv.h"
 #include "rcar_du_encoder.h"
-#include "rcar_du_hdmienc.h"
 #include "rcar_du_kms.h"
 #include "rcar_du_lvdscon.h"
 #include "rcar_du_lvdsenc.h"
-#include "rcar_du_vgacon.h"
 
 /* -----------------------------------------------------------------------------
  * Encoder
@@ -63,29 +61,35 @@ static int rcar_du_encoder_atomic_check(struct drm_encoder *encoder,
        struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
        struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
        const struct drm_display_mode *mode = &crtc_state->mode;
-       const struct drm_display_mode *panel_mode;
        struct drm_connector *connector = conn_state->connector;
        struct drm_device *dev = encoder->dev;
 
-       /* DAC encoders have currently no restriction on the mode. */
-       if (encoder->encoder_type == DRM_MODE_ENCODER_DAC)
-               return 0;
+       /*
+        * Only panel-related encoder types require validation here, everything
+        * else is handled by the bridge drivers.
+        */
+       if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
+               const struct drm_display_mode *panel_mode;
 
-       if (list_empty(&connector->modes)) {
-               dev_dbg(dev->dev, "encoder: empty modes list\n");
-               return -EINVAL;
-       }
+               if (list_empty(&connector->modes)) {
+                       dev_dbg(dev->dev, "encoder: empty modes list\n");
+                       return -EINVAL;
+               }
 
-       panel_mode = list_first_entry(&connector->modes,
-                                     struct drm_display_mode, head);
+               panel_mode = list_first_entry(&connector->modes,
+                                             struct drm_display_mode, head);
 
-       /* We're not allowed to modify the resolution. */
-       if (mode->hdisplay != panel_mode->hdisplay ||
-           mode->vdisplay != panel_mode->vdisplay)
-               return -EINVAL;
+               /* We're not allowed to modify the resolution. */
+               if (mode->hdisplay != panel_mode->hdisplay ||
+                   mode->vdisplay != panel_mode->vdisplay)
+                       return -EINVAL;
 
-       /* The flat panel mode is fixed, just copy it to the adjusted mode. */
-       drm_mode_copy(adjusted_mode, panel_mode);
+               /*
+                * The flat panel mode is fixed, just copy it to the adjusted
+                * mode.
+                */
+               drm_mode_copy(adjusted_mode, panel_mode);
+       }
 
        if (renc->lvds)
                rcar_du_lvdsenc_atomic_check(renc->lvds, adjusted_mode);
@@ -159,6 +163,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 {
        struct rcar_du_encoder *renc;
        struct drm_encoder *encoder;
+       struct drm_bridge *bridge = NULL;
        unsigned int encoder_type;
        int ret;
 
@@ -182,6 +187,15 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
                break;
        }
 
+       if (enc_node) {
+               /* Locate the DRM bridge from the encoder DT node. */
+               bridge = of_drm_find_bridge(enc_node);
+               if (!bridge) {
+                       ret = -EPROBE_DEFER;
+                       goto done;
+               }
+       }
+
        switch (type) {
        case RCAR_DU_ENCODER_VGA:
                encoder_type = DRM_MODE_ENCODER_DAC;
@@ -199,35 +213,35 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
                break;
        }
 
-       if (type == RCAR_DU_ENCODER_HDMI) {
-               ret = rcar_du_hdmienc_init(rcdu, renc, enc_node);
-               if (ret < 0)
-                       goto done;
-       } else {
-               ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
-                                      encoder_type, NULL);
-               if (ret < 0)
-                       goto done;
-
-               drm_encoder_helper_add(encoder, &encoder_helper_funcs);
-       }
-
-       switch (encoder_type) {
-       case DRM_MODE_ENCODER_LVDS:
-               ret = rcar_du_lvds_connector_init(rcdu, renc, con_node);
-               break;
-
-       case DRM_MODE_ENCODER_DAC:
-               ret = rcar_du_vga_connector_init(rcdu, renc);
-               break;
+       ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
+                              encoder_type, NULL);
+       if (ret < 0)
+               goto done;
 
-       case DRM_MODE_ENCODER_TMDS:
-               /* connector managed by the bridge driver */
-               break;
+       drm_encoder_helper_add(encoder, &encoder_helper_funcs);
 
-       default:
-               ret = -EINVAL;
-               break;
+       if (bridge) {
+               /*
+                * Attach the bridge to the encoder. The bridge will create the
+                * connector.
+                */
+               ret = drm_bridge_attach(encoder, bridge, NULL);
+               if (ret) {
+                       drm_encoder_cleanup(encoder);
+                       return ret;
+               }
+       } else {
+               /* There's no bridge, create the connector manually. */
+               switch (output) {
+               case RCAR_DU_OUTPUT_LVDS0:
+               case RCAR_DU_OUTPUT_LVDS1:
+                       ret = rcar_du_lvds_connector_init(rcdu, renc, con_node);
+                       break;
+
+               default:
+                       ret = -EINVAL;
+                       break;
+               }
        }
 
 done:
index b79b2f075a74a4d06626735ee8b01c0fc3736294..c1cfbe0d54ceb0ed1005352b27b0fd40d4c42541 100644 (file)
@@ -19,7 +19,6 @@
 
 struct drm_panel;
 struct rcar_du_device;
-struct rcar_du_hdmienc;
 struct rcar_du_lvdsenc;
 
 enum rcar_du_encoder_type {
@@ -34,7 +33,6 @@ struct rcar_du_encoder {
        struct drm_encoder base;
        enum rcar_du_output output;
        struct rcar_du_connector *connector;
-       struct rcar_du_hdmienc *hdmi;
        struct rcar_du_lvdsenc *lvds;
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
deleted file mode 100644 (file)
index 933a254..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * R-Car Display Unit HDMI Encoder
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.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 <linux/slab.h>
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_encoder.h"
-#include "rcar_du_hdmienc.h"
-#include "rcar_du_lvdsenc.h"
-
-struct rcar_du_hdmienc {
-       struct rcar_du_encoder *renc;
-       bool enabled;
-};
-
-#define to_rcar_hdmienc(e)     (to_rcar_encoder(e)->hdmi)
-
-static void rcar_du_hdmienc_disable(struct drm_encoder *encoder)
-{
-       struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-
-       if (hdmienc->renc->lvds)
-               rcar_du_lvdsenc_enable(hdmienc->renc->lvds, encoder->crtc,
-                                      false);
-
-       hdmienc->enabled = false;
-}
-
-static void rcar_du_hdmienc_enable(struct drm_encoder *encoder)
-{
-       struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-
-       if (hdmienc->renc->lvds)
-               rcar_du_lvdsenc_enable(hdmienc->renc->lvds, encoder->crtc,
-                                      true);
-
-       hdmienc->enabled = true;
-}
-
-static int rcar_du_hdmienc_atomic_check(struct drm_encoder *encoder,
-                                       struct drm_crtc_state *crtc_state,
-                                       struct drm_connector_state *conn_state)
-{
-       struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-       struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
-
-       if (hdmienc->renc->lvds)
-               rcar_du_lvdsenc_atomic_check(hdmienc->renc->lvds,
-                                            adjusted_mode);
-
-       return 0;
-}
-
-
-static void rcar_du_hdmienc_mode_set(struct drm_encoder *encoder,
-                                    struct drm_crtc_state *crtc_state,
-                                    struct drm_connector_state *conn_state)
-{
-       struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-
-       rcar_du_crtc_route_output(crtc_state->crtc, hdmienc->renc->output);
-}
-
-static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
-       .atomic_mode_set = rcar_du_hdmienc_mode_set,
-       .disable = rcar_du_hdmienc_disable,
-       .enable = rcar_du_hdmienc_enable,
-       .atomic_check = rcar_du_hdmienc_atomic_check,
-};
-
-static void rcar_du_hdmienc_cleanup(struct drm_encoder *encoder)
-{
-       struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
-
-       if (hdmienc->enabled)
-               rcar_du_hdmienc_disable(encoder);
-
-       drm_encoder_cleanup(encoder);
-}
-
-static const struct drm_encoder_funcs encoder_funcs = {
-       .destroy = rcar_du_hdmienc_cleanup,
-};
-
-int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
-                        struct rcar_du_encoder *renc, struct device_node *np)
-{
-       struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
-       struct drm_bridge *bridge;
-       struct rcar_du_hdmienc *hdmienc;
-       int ret;
-
-       hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL);
-       if (hdmienc == NULL)
-               return -ENOMEM;
-
-       /* Locate the DRM bridge from the HDMI encoder DT node. */
-       bridge = of_drm_find_bridge(np);
-       if (!bridge)
-               return -EPROBE_DEFER;
-
-       ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
-                              DRM_MODE_ENCODER_TMDS, NULL);
-       if (ret < 0)
-               return ret;
-
-       drm_encoder_helper_add(encoder, &encoder_helper_funcs);
-
-       renc->hdmi = hdmienc;
-       hdmienc->renc = renc;
-
-       /* Link the bridge to the encoder. */
-       ret = drm_bridge_attach(encoder, bridge, NULL);
-       if (ret) {
-               drm_encoder_cleanup(encoder);
-               return ret;
-       }
-
-       return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.h b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.h
deleted file mode 100644 (file)
index 2ff0128..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * R-Car Display Unit HDMI Encoder
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.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 __RCAR_DU_HDMIENC_H__
-#define __RCAR_DU_HDMIENC_H__
-
-#include <linux/module.h>
-
-struct device_node;
-struct rcar_du_device;
-struct rcar_du_encoder;
-
-#if IS_ENABLED(CONFIG_DRM_RCAR_HDMI)
-int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
-                        struct rcar_du_encoder *renc, struct device_node *np);
-#else
-static inline int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
-                                      struct rcar_du_encoder *renc,
-                                      struct device_node *np)
-{
-       return -ENOSYS;
-}
-#endif
-
-#endif /* __RCAR_DU_HDMIENC_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
deleted file mode 100644 (file)
index 8d6125c..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * rcar_du_vgacon.c  --  R-Car Display Unit VGA Connector
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.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_atomic_helper.h>
-#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
-
-#include "rcar_du_drv.h"
-#include "rcar_du_encoder.h"
-#include "rcar_du_kms.h"
-#include "rcar_du_vgacon.h"
-
-static int rcar_du_vga_connector_get_modes(struct drm_connector *connector)
-{
-       return 0;
-}
-
-static const struct drm_connector_helper_funcs connector_helper_funcs = {
-       .get_modes = rcar_du_vga_connector_get_modes,
-};
-
-static enum drm_connector_status
-rcar_du_vga_connector_detect(struct drm_connector *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-static const struct drm_connector_funcs connector_funcs = {
-       .dpms = drm_atomic_helper_connector_dpms,
-       .reset = drm_atomic_helper_connector_reset,
-       .detect = rcar_du_vga_connector_detect,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .destroy = drm_connector_cleanup,
-       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
-                              struct rcar_du_encoder *renc)
-{
-       struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc);
-       struct rcar_du_connector *rcon;
-       struct drm_connector *connector;
-       int ret;
-
-       rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
-       if (rcon == NULL)
-               return -ENOMEM;
-
-       connector = &rcon->connector;
-       connector->display_info.width_mm = 0;
-       connector->display_info.height_mm = 0;
-       connector->interlace_allowed = true;
-
-       ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
-                                DRM_MODE_CONNECTOR_VGA);
-       if (ret < 0)
-               return ret;
-
-       drm_connector_helper_add(connector, &connector_helper_funcs);
-
-       connector->dpms = DRM_MODE_DPMS_OFF;
-       drm_object_property_set_value(&connector->base,
-               rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
-
-       ret = drm_mode_connector_attach_encoder(connector, encoder);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.h b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.h
deleted file mode 100644 (file)
index 112f503..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * rcar_du_vgacon.h  --  R-Car Display Unit VGA Connector
- *
- * Copyright (C) 2013-2014 Renesas Electronics Corporation
- *
- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.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 __RCAR_DU_VGACON_H__
-#define __RCAR_DU_VGACON_H__
-
-struct rcar_du_device;
-struct rcar_du_encoder;
-
-int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
-                              struct rcar_du_encoder *renc);
-
-#endif /* __RCAR_DU_VGACON_H__ */