Loading drivers/gpu/drm/rcar-du/Kconfig +9 −2 Original line number Diff line number Diff line Loading @@ -11,10 +11,17 @@ 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 depends on OF help Enable support for external HDMI encoders. config DRM_RCAR_LVDS bool "R-Car DU LVDS Encoder Support" depends on DRM_RCAR_DU depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST help Enable support the R-Car Display Unit embedded LVDS encoders (currently only on R8A7790). Enable support for the R-Car Display Unit embedded LVDS encoders (currently only on R8A7790 and R8A7791). drivers/gpu/drm/rcar-du/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ rcar-du-drm-y := rcar_du_crtc.o \ rcar_du_plane.o \ rcar_du_vgacon.o rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI) += rcar_du_hdmicon.o \ rcar_du_hdmienc.o rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_lvdsenc.o obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o drivers/gpu/drm/rcar-du/rcar_du_encoder.c +25 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include "rcar_du_drv.h" #include "rcar_du_encoder.h" #include "rcar_du_hdmicon.h" #include "rcar_du_hdmienc.h" #include "rcar_du_kms.h" #include "rcar_du_lvdscon.h" #include "rcar_du_lvdsenc.h" Loading Loading @@ -177,6 +179,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, case RCAR_DU_ENCODER_LVDS: encoder_type = DRM_MODE_ENCODER_LVDS; break; case RCAR_DU_ENCODER_HDMI: encoder_type = DRM_MODE_ENCODER_TMDS; break; case RCAR_DU_ENCODER_NONE: default: /* No external encoder, use the internal encoder type. */ Loading @@ -184,12 +189,24 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, break; } if (type == RCAR_DU_ENCODER_HDMI) { if (renc->lvds) { dev_err(rcdu->dev, "Chaining LVDS and HDMI encoders not supported\n"); return -EINVAL; } ret = rcar_du_hdmienc_init(rcdu, renc, enc_node); if (ret < 0) return ret; } else { ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, encoder_type); if (ret < 0) return ret; drm_encoder_helper_add(encoder, &encoder_helper_funcs); } switch (encoder_type) { case DRM_MODE_ENCODER_LVDS: Loading @@ -198,6 +215,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, case DRM_MODE_ENCODER_DAC: return rcar_du_vga_connector_init(rcdu, renc); case DRM_MODE_ENCODER_TMDS: return rcar_du_hdmi_connector_init(rcdu, renc); default: return -EINVAL; } Loading drivers/gpu/drm/rcar-du/rcar_du_encoder.h +3 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <drm/drm_encoder_slave.h> struct rcar_du_device; struct rcar_du_hdmienc; struct rcar_du_lvdsenc; enum rcar_du_encoder_type { Loading @@ -25,11 +26,13 @@ enum rcar_du_encoder_type { RCAR_DU_ENCODER_NONE, RCAR_DU_ENCODER_VGA, RCAR_DU_ENCODER_LVDS, RCAR_DU_ENCODER_HDMI, }; struct rcar_du_encoder { struct drm_encoder_slave slave; enum rcar_du_output output; struct rcar_du_hdmienc *hdmi; struct rcar_du_lvdsenc *lvds; }; Loading drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * R-Car Display Unit HDMI Connector * * 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 <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_encoder_slave.h> #include "rcar_du_drv.h" #include "rcar_du_encoder.h" #include "rcar_du_hdmicon.h" #include "rcar_du_kms.h" #define to_slave_funcs(e) (to_rcar_encoder(e)->slave.slave_funcs) static int rcar_du_hdmi_connector_get_modes(struct drm_connector *connector) { struct drm_encoder *encoder = connector->encoder; struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder); if (sfuncs->get_modes == NULL) return 0; return sfuncs->get_modes(encoder, connector); } static int rcar_du_hdmi_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_encoder *encoder = connector->encoder; struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder); if (sfuncs->mode_valid == NULL) return MODE_OK; return sfuncs->mode_valid(encoder, mode); } static const struct drm_connector_helper_funcs connector_helper_funcs = { .get_modes = rcar_du_hdmi_connector_get_modes, .mode_valid = rcar_du_hdmi_connector_mode_valid, .best_encoder = rcar_du_connector_best_encoder, }; static void rcar_du_hdmi_connector_destroy(struct drm_connector *connector) { drm_connector_unregister(connector); drm_connector_cleanup(connector); } static enum drm_connector_status rcar_du_hdmi_connector_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder = connector->encoder; struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder); if (sfuncs->detect == NULL) return connector_status_unknown; return sfuncs->detect(encoder, connector); } static const struct drm_connector_funcs connector_funcs = { .dpms = drm_helper_connector_dpms, .detect = rcar_du_hdmi_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = rcar_du_hdmi_connector_destroy, }; int rcar_du_hdmi_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; ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, DRM_MODE_CONNECTOR_HDMIA); if (ret < 0) return ret; drm_connector_helper_add(connector, &connector_helper_funcs); ret = drm_connector_register(connector); if (ret < 0) return ret; drm_helper_connector_dpms(connector, 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; connector->encoder = encoder; rcon->encoder = renc; return 0; } Loading
drivers/gpu/drm/rcar-du/Kconfig +9 −2 Original line number Diff line number Diff line Loading @@ -11,10 +11,17 @@ 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 depends on OF help Enable support for external HDMI encoders. config DRM_RCAR_LVDS bool "R-Car DU LVDS Encoder Support" depends on DRM_RCAR_DU depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST help Enable support the R-Car Display Unit embedded LVDS encoders (currently only on R8A7790). Enable support for the R-Car Display Unit embedded LVDS encoders (currently only on R8A7790 and R8A7791).
drivers/gpu/drm/rcar-du/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ rcar-du-drm-y := rcar_du_crtc.o \ rcar_du_plane.o \ rcar_du_vgacon.o rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI) += rcar_du_hdmicon.o \ rcar_du_hdmienc.o rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_lvdsenc.o obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
drivers/gpu/drm/rcar-du/rcar_du_encoder.c +25 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include "rcar_du_drv.h" #include "rcar_du_encoder.h" #include "rcar_du_hdmicon.h" #include "rcar_du_hdmienc.h" #include "rcar_du_kms.h" #include "rcar_du_lvdscon.h" #include "rcar_du_lvdsenc.h" Loading Loading @@ -177,6 +179,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, case RCAR_DU_ENCODER_LVDS: encoder_type = DRM_MODE_ENCODER_LVDS; break; case RCAR_DU_ENCODER_HDMI: encoder_type = DRM_MODE_ENCODER_TMDS; break; case RCAR_DU_ENCODER_NONE: default: /* No external encoder, use the internal encoder type. */ Loading @@ -184,12 +189,24 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, break; } if (type == RCAR_DU_ENCODER_HDMI) { if (renc->lvds) { dev_err(rcdu->dev, "Chaining LVDS and HDMI encoders not supported\n"); return -EINVAL; } ret = rcar_du_hdmienc_init(rcdu, renc, enc_node); if (ret < 0) return ret; } else { ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, encoder_type); if (ret < 0) return ret; drm_encoder_helper_add(encoder, &encoder_helper_funcs); } switch (encoder_type) { case DRM_MODE_ENCODER_LVDS: Loading @@ -198,6 +215,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, case DRM_MODE_ENCODER_DAC: return rcar_du_vga_connector_init(rcdu, renc); case DRM_MODE_ENCODER_TMDS: return rcar_du_hdmi_connector_init(rcdu, renc); default: return -EINVAL; } Loading
drivers/gpu/drm/rcar-du/rcar_du_encoder.h +3 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <drm/drm_encoder_slave.h> struct rcar_du_device; struct rcar_du_hdmienc; struct rcar_du_lvdsenc; enum rcar_du_encoder_type { Loading @@ -25,11 +26,13 @@ enum rcar_du_encoder_type { RCAR_DU_ENCODER_NONE, RCAR_DU_ENCODER_VGA, RCAR_DU_ENCODER_LVDS, RCAR_DU_ENCODER_HDMI, }; struct rcar_du_encoder { struct drm_encoder_slave slave; enum rcar_du_output output; struct rcar_du_hdmienc *hdmi; struct rcar_du_lvdsenc *lvds; }; Loading
drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * R-Car Display Unit HDMI Connector * * 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 <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_encoder_slave.h> #include "rcar_du_drv.h" #include "rcar_du_encoder.h" #include "rcar_du_hdmicon.h" #include "rcar_du_kms.h" #define to_slave_funcs(e) (to_rcar_encoder(e)->slave.slave_funcs) static int rcar_du_hdmi_connector_get_modes(struct drm_connector *connector) { struct drm_encoder *encoder = connector->encoder; struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder); if (sfuncs->get_modes == NULL) return 0; return sfuncs->get_modes(encoder, connector); } static int rcar_du_hdmi_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_encoder *encoder = connector->encoder; struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder); if (sfuncs->mode_valid == NULL) return MODE_OK; return sfuncs->mode_valid(encoder, mode); } static const struct drm_connector_helper_funcs connector_helper_funcs = { .get_modes = rcar_du_hdmi_connector_get_modes, .mode_valid = rcar_du_hdmi_connector_mode_valid, .best_encoder = rcar_du_connector_best_encoder, }; static void rcar_du_hdmi_connector_destroy(struct drm_connector *connector) { drm_connector_unregister(connector); drm_connector_cleanup(connector); } static enum drm_connector_status rcar_du_hdmi_connector_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder = connector->encoder; struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder); if (sfuncs->detect == NULL) return connector_status_unknown; return sfuncs->detect(encoder, connector); } static const struct drm_connector_funcs connector_funcs = { .dpms = drm_helper_connector_dpms, .detect = rcar_du_hdmi_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = rcar_du_hdmi_connector_destroy, }; int rcar_du_hdmi_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; ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, DRM_MODE_CONNECTOR_HDMIA); if (ret < 0) return ret; drm_connector_helper_add(connector, &connector_helper_funcs); ret = drm_connector_register(connector); if (ret < 0) return ret; drm_helper_connector_dpms(connector, 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; connector->encoder = encoder; rcon->encoder = renc; return 0; }