Hi, On 09/08/2016 05:47 PM, Maxime Ripard wrote:
Some boards have an entirely passive RGB to VGA bridge, based on either DACs or resistor ladders. Those might or might not have an i2c bus routed to the VGA connector in order to access the screen EDIDs. Add a bridge that doesn't do anything but expose the modes available on the screen, either based on the EDIDs if available, or based on the XGA standards.
Some minor comments below, besides the ones by ChenYu.
Acked-by: Rob Herring <robh@xxxxxxxxxx> Signed-off-by: Maxime Ripard <maxime.ripard@xxxxxxxxxxxxxxxxxx> --- .../bindings/display/bridge/rgb-to-vga-bridge.txt | 52 +++++ drivers/gpu/drm/bridge/Kconfig | 6 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/rgb-to-vga.c | 232 +++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c diff --git a/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt new file mode 100644 index 000000000000..83a053fb51a0 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt @@ -0,0 +1,52 @@ +Passive RGB to VGA bridge +------------------------- + +This binding is aimed for entirely passive RGB to VGA bridges that do not +require any configuration. + +Required properties: + +- compatible: Must be "rgb-to-vga-bridge" + +Required nodes: + +This device has two video ports. Their connections are modeled using the OF +graph bindings specified in Documentation/devicetree/bindings/graph.txt. + +- Video port 0 for RGB input +- Video port 1 for VGA output + + +Example +------- + +bridge { + compatible = "rgb-to-vga-bridge"; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>;
The above 2 properties required for the individual port nodes, right?
+ reg = <0>; + + vga_bridge_in: endpoint { + remote-endpoint = <&tcon0_out_vga>; + }; + }; + + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + vga_bridge_out: endpoint { + remote-endpoint = <&vga_con_in>; + }; + }; + }; +}; diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index b590e678052d..42b95adf5091 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -17,6 +17,12 @@ config DRM_ANALOGIX_ANX78XX the HDMI output of an application processor to MyDP or DisplayPort. +config DRM_RGB_TO_VGA + tristate "Dumb RGB to VGA Bridge support" + select DRM_KMS_HELPER
In the current state of the driver, we need to rely on OF support for it to function properly. I guess we need to depend on CONFIG_OF here.
+ help + Support for passive RGB to VGA bridges + config DRM_DW_HDMI tristate select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index efdb07e878f5..3bb8cbe09fe9 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,6 +1,7 @@ ccflags-y := -Iinclude/drm obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o +obj-$(CONFIG_DRM_RGB_TO_VGA) += rgb-to-vga.o obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o diff --git a/drivers/gpu/drm/bridge/rgb-to-vga.c b/drivers/gpu/drm/bridge/rgb-to-vga.c new file mode 100644 index 000000000000..84b1b10198a4 --- /dev/null +++ b/drivers/gpu/drm/bridge/rgb-to-vga.c @@ -0,0 +1,232 @@ + +#include <linux/module.h> +#include <linux/of_graph.h> + +#include <drm/drmP.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_crtc.h> +#include <drm/drm_crtc_helper.h> + +struct dumb_vga { + struct drm_bridge bridge; + struct drm_connector connector; + + struct i2c_adapter *ddc; +}; + +static inline struct dumb_vga * +drm_bridge_to_dumb_vga(struct drm_bridge *bridge) +{ + return container_of(bridge, struct dumb_vga, bridge); +} + +static inline struct dumb_vga * +drm_connector_to_dumb_vga(struct drm_connector *connector) +{ + return container_of(connector, struct dumb_vga, connector); +} + +static int dumb_vga_get_modes(struct drm_connector *connector) +{ + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); + struct edid *edid; + int ret; + + if (IS_ERR(vga->ddc)) + goto fallback; + + edid = drm_get_edid(connector, vga->ddc); + if (!edid) { + DRM_INFO("EDID readout failed, falling back to standard modes\n"); + goto fallback; + } + + drm_mode_connector_update_edid_property(connector, edid); + return drm_add_edid_modes(connector, edid); + +fallback: + /* + * In case we cannot retrieve the EDIDs (broken or missing i2c + * bus), fallback on the XGA standards + */ + ret = drm_add_modes_noedid(connector, 1920, 1200); + + /* And prefer a mode pretty much anyone can handle */ + drm_set_preferred_mode(connector, 1024, 768); + + return ret; +} + +static struct drm_encoder * +dumb_vga_best_encoder(struct drm_connector *connector) +{ + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); + + return vga->bridge.encoder; +} + +static struct drm_connector_helper_funcs dumb_vga_con_helper_funcs = { + .get_modes = dumb_vga_get_modes, + .best_encoder = dumb_vga_best_encoder, +}; + +static enum drm_connector_status +dumb_vga_connector_detect(struct drm_connector *connector, bool force) +{ + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); + + /* + * Even if we have an I2C bus, we can't assume that the cable + * is disconnected if drm_probe_ddc. Some cables don't wire
s/if/in ?
+ * the DDC pins, or the I2C bus might be disfunctional.
s/disfunctional/not functional Looks good otherwise. Archit -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html