diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-06-17 15:48:27 +0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-08-10 01:17:53 +0400 |
commit | 90374b5c25c9f04895c52a1e7a2468ee8dac525b (patch) | |
tree | 12d6f168083bdab0902c003b068527b3a7c130fe /drivers/gpu/drm/rcar-du/rcar_du_encoder.c | |
parent | 7cbc05cb518304b746bea00bc7c0b005217bcaf7 (diff) | |
download | linux-90374b5c25c9f04895c52a1e7a2468ee8dac525b.tar.xz |
drm/rcar-du: Add internal LVDS encoder support
The R8A7790 includes two internal LVDS encoders. Support them in the DU
driver.
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 | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index 2aac28d21f87..3daa7a168dc6 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -11,6 +11,8 @@ * (at your option) any later version. */ +#include <linux/export.h> + #include <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> @@ -19,6 +21,7 @@ #include "rcar_du_encoder.h" #include "rcar_du_kms.h" #include "rcar_du_lvdscon.h" +#include "rcar_du_lvdsenc.h" #include "rcar_du_vgacon.h" /* ----------------------------------------------------------------------------- @@ -39,12 +42,17 @@ rcar_du_connector_best_encoder(struct drm_connector *connector) static void rcar_du_encoder_dpms(struct drm_encoder *encoder, int mode) { + struct rcar_du_encoder *renc = to_rcar_encoder(encoder); + + if (renc->lvds) + rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, mode); } static bool rcar_du_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + struct rcar_du_encoder *renc = to_rcar_encoder(encoder); const struct drm_display_mode *panel_mode; struct drm_device *dev = encoder->dev; struct drm_connector *connector; @@ -82,15 +90,32 @@ static bool rcar_du_encoder_mode_fixup(struct drm_encoder *encoder, /* The flat panel mode is fixed, just copy it to the adjusted mode. */ drm_mode_copy(adjusted_mode, panel_mode); + /* The internal LVDS encoder has a clock frequency operating range of + * 30MHz to 150MHz. Clamp the clock accordingly. + */ + if (renc->lvds) + adjusted_mode->clock = clamp(adjusted_mode->clock, + 30000, 150000); + return true; } static void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder) { + struct rcar_du_encoder *renc = to_rcar_encoder(encoder); + + if (renc->lvds) + rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, + DRM_MODE_DPMS_OFF); } static void rcar_du_encoder_mode_commit(struct drm_encoder *encoder) { + struct rcar_du_encoder *renc = to_rcar_encoder(encoder); + + if (renc->lvds) + rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, + DRM_MODE_DPMS_ON); } static void rcar_du_encoder_mode_set(struct drm_encoder *encoder, @@ -129,6 +154,19 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, renc->output = output; + switch (output) { + case RCAR_DU_OUTPUT_LVDS0: + renc->lvds = rcdu->lvds[0]; + break; + + case RCAR_DU_OUTPUT_LVDS1: + renc->lvds = rcdu->lvds[1]; + break; + + default: + break; + } + switch (type) { case RCAR_DU_ENCODER_VGA: encoder_type = DRM_MODE_ENCODER_DAC; |