diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2016-10-07 16:01:41 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2017-04-04 17:04:02 +0300 |
commit | 5c602531feb3db3926cdd76dda89314f0634c9e7 (patch) | |
tree | 2029942a4c0980756e42506be3a730cca3e3b6a6 /drivers/gpu/drm/rcar-du/rcar_du_encoder.c | |
parent | e947eccbeba45268bf3b5f4e30185d9bb87a293d (diff) | |
download | linux-5c602531feb3db3926cdd76dda89314f0634c9e7.tar.xz |
drm: rcar-du: Replace manual bridge implementation with DRM bridge
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>
Diffstat (limited to 'drivers/gpu/drm/rcar-du/rcar_du_encoder.c')
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 104 |
1 files changed, 59 insertions, 45 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index 3a3c9374794e..92a0405c2fb2 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -20,11 +20,9 @@ #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: |