devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: devicetree@vger.kernel.org,
	Mike Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	dri-devel@lists.freedesktop.org, Chen-Yu Tsai <wens@csie.org>,
	Rob Herring <robh+dt@kernel.org>,
	Daniel Vetter <daniel.vetter@intel.com>,
	linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 13/20] drm/bridge: Add RGB to VGA bridge support
Date: Mon, 16 May 2016 16:24:15 +0300	[thread overview]
Message-ID: <1773896.kpi58ilqqm@avalon> (raw)
In-Reply-To: <1463402840-17062-14-git-send-email-maxime.ripard@free-electrons.com>

Hi Maxime,

Thank you for the patch.

On Monday 16 May 2016 14:47:13 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.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  .../bindings/display/bridge/dumb-vga.txt           |  40 +++++
>  drivers/gpu/drm/bridge/Kconfig                     |   6 +
>  drivers/gpu/drm/bridge/Makefile                    |   1 +
>  drivers/gpu/drm/bridge/dumb-vga.c                  | 186 ++++++++++++++++++
>  4 files changed, 233 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/display/bridge/dumb-vga.txt create mode
> 100644 drivers/gpu/drm/bridge/dumb-vga.c
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/dumb-vga.txt
> b/Documentation/devicetree/bindings/display/bridge/dumb-vga.txt new file
> mode 100644
> index 000000000000..757f04de97f3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga.txt
> @@ -0,0 +1,40 @@
> +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: Should be "dumb-vga-bridge"
> +
> +Optional properties:
> +
> +- ddc-i2c-bus: phandle to the i2c bus used to communicate with the monitor
> +
> +Required nodes:
> +
> +This device has one video port. Its connection is modelled using the OF
> +graph bindings specified in Documentation/devicetree/bindings/graph.txt.
> This +connection is meant to be the RGB input bus.

Should the bridge have two ports, one input port connected to a display engine 
and one output port connected to a VGA connector ?

> +
> +
> +Example
> +-------
> +
> +bridge {
> +        compatible = "dumb-vga-bridge";
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        port@0 {
> +                reg = <0>;
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +
> +                vga_input: endpoint@0 {
> +                        reg = <0>;
> +                        remote-endpoint = <&tcon0_out_vga>;
> +               };
> +        };
> +};
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 8f7423f18da5..cf279956cbec 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_DUMB_VGA
> +	tristate "Dumb RGB to VGA Bridge support"
> +	select DRM_KMS_HELPER
> +	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 96b13b30e6ab..63f21120e8f8 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_DUMB_VGA) += dumb-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/dumb-vga.c
> b/drivers/gpu/drm/bridge/dumb-vga.c new file mode 100644
> index 000000000000..2864fa535bf8
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dumb-vga.c
> @@ -0,0 +1,186 @@
> +
> +#include <linux/module.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 (!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);

The DRM core adds modes up to 1024x768 in 
drm_helper_probe_single_connector_modes(). I wonder if it really makes sense 
to override that in drivers, compared to increasing the maximum resolution in 
the core. What we can reasonable expect from a VGA monitor doesn't really 
depend on which display engine it is connected to.

> +	/* 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)
> +{
> +	return connector_status_connected;

Shouldn't that be connector_status_unknown if you have no information about 
the connection status ?

Would it make sense to add an optional GPIO-based connection detection to this 
driver ?

> +}
> +
> +static void
> +dumb_vga_connector_destroy(struct drm_connector *connector)
> +{
> +	drm_connector_cleanup(connector);
> +}
> +
> +static struct drm_connector_funcs dumb_vga_con_funcs = {
> +	.dpms			= drm_atomic_helper_connector_dpms,
> +	.detect			= dumb_vga_connector_detect,
> +	.fill_modes		= drm_helper_probe_single_connector_modes,
> +	.destroy		= dumb_vga_connector_destroy,
> +	.reset			= drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static int dumb_vga_attach(struct drm_bridge *bridge)
> +{
> +	struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
> +	int ret;
> +
> +	if (!bridge->encoder) {
> +		DRM_ERROR("Missing encoder\n");
> +		return -ENODEV;
> +	}
> +
> +	drm_connector_helper_add(&vga->connector,
> +				 &dumb_vga_con_helper_funcs);
> +	ret = drm_connector_init(bridge->dev, &vga->connector,
> +				 &dumb_vga_con_funcs, DRM_MODE_CONNECTOR_VGA);
> +	if (ret) {
> +		DRM_ERROR("Failed to initialize connector\n");
> +		return ret;
> +	}
> +
> +	drm_mode_connector_attach_encoder(&vga->connector,
> +					  bridge->encoder);
> +
> +	return 0;
> +}
> +
> +static void dumb_vga_nop(struct drm_bridge *bridge) {};
> +
> +static struct drm_bridge_funcs dumb_vga_bridge_funcs = {
> +	.attach		= dumb_vga_attach,
> +	.enable		= dumb_vga_nop,
> +	.disable	= dumb_vga_nop,
> +	.pre_enable	= dumb_vga_nop,
> +	.post_disable	= dumb_vga_nop,
> +};
> +
> +static int dumb_vga_probe(struct platform_device *pdev)
> +{
> +	struct dumb_vga *vga;
> +	struct device_node *ddc;
> +
> +	vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
> +	if (!vga)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, vga);
> +
> +	ddc = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
> +	if (ddc) {
> +		vga->ddc = of_find_i2c_adapter_by_node(ddc);

You're leaking the reference to the I2C adapter.

Also, shouldn't you use of_get_i2c_adapter_by_node() ? Otherwise you won't 
take a reference to the adapter module.

> +		of_node_put(ddc);
> +
> +		if (!vga->ddc) {
> +			dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n");
> +			return -EPROBE_DEFER;
> +		}
> +	} else {
> +		dev_info(&pdev->dev,
> +			 "No i2c bus specified... Disabling EDID readout\n");
> +	}
> +
> +	vga->bridge.funcs = &dumb_vga_bridge_funcs;
> +	vga->bridge.of_node = pdev->dev.of_node;
> +
> +	return drm_bridge_add(&vga->bridge);
> +}
> +
> +static int dumb_vga_remove(struct platform_device *pdev)
> +{
> +	struct dumb_vga *vga = platform_get_drvdata(pdev);
> +
> +	drm_bridge_remove(&vga->bridge);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id dumb_vga_match[] = {
> +	{ .compatible = "dumb-vga-bridge" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, dumb_vga_match);
> +
> +struct platform_driver dumb_vga_driver = {
> +	.probe	= dumb_vga_probe,
> +	.remove	= dumb_vga_remove,
> +	.driver		= {
> +		.name		= "dumb-vga-bridge",
> +		.of_match_table	= dumb_vga_match,
> +	},
> +};
> +module_platform_driver(dumb_vga_driver);
> +
> +MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
> +MODULE_DESCRIPTION("Dumb RGB to VGA bridge driver");
> +MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2016-05-16 13:24 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-16 12:47 [PATCH 00/20] drm: Add Support for Passive RGB to VGA bridges Maxime Ripard
2016-05-16 12:47 ` [PATCH 01/20] clk: fixed-factor: Pass clk rates change to the parent Maxime Ripard
2016-06-10 12:30   ` Maxime Ripard
     [not found]   ` <1463402840-17062-2-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-06-17 23:05     ` Michael Turquette
2016-06-20  8:54       ` Maxime Ripard
2016-06-20 19:57         ` Michael Turquette
2016-05-16 12:47 ` [PATCH 03/20] clk: sunxi: tcon-ch1: Do not return a negative error in get_parent Maxime Ripard
2016-05-16 16:05   ` Chen-Yu Tsai
2016-06-10  9:50     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 04/20] clk: sunxi: display: Add per-clock flags Maxime Ripard
2016-05-16 15:21   ` Chen-Yu Tsai
2016-06-10  9:50     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 05/20] drm/sun4i: request exact rates to our parents Maxime Ripard
2016-05-16 12:47 ` [PATCH 06/20] drm/sun4i: allow dclk to modify its parent rate Maxime Ripard
2016-05-16 17:18   ` Chen-Yu Tsai
2016-05-25 12:01     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 07/20] drm/sun4i: rgb: Validate the clock rate Maxime Ripard
2016-05-16 12:47 ` [PATCH 08/20] drm/sun4i: rgb: panel is an error pointer Maxime Ripard
2016-05-17  3:51   ` Chen-Yu Tsai
2016-05-25 12:06     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 09/20] drm/sun4i: defer only if we didn't find our panel Maxime Ripard
     [not found]   ` <1463402840-17062-10-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-05-17  3:52     ` Chen-Yu Tsai
2016-05-25 12:09       ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 10/20] drm/sun4i: remove simplefb at probe Maxime Ripard
2016-05-16 12:47 ` [PATCH 11/20] drm/sun4i: Convert to connector register helpers Maxime Ripard
2016-05-16 12:47 ` [PATCH 12/20] drm/sun4i: Add bridge support Maxime Ripard
2016-05-16 13:12   ` Daniel Vetter
2016-05-25 16:29     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 13/20] drm/bridge: Add RGB to VGA " Maxime Ripard
2016-05-16 13:24   ` Laurent Pinchart [this message]
2016-05-26  8:53     ` Maxime Ripard
2016-05-26  9:16       ` Russell King - ARM Linux
2016-05-16 14:07   ` Rob Herring
2016-05-26  9:38     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 14/20] ARM: sun5i: a13: Add LCD pins Maxime Ripard
2016-05-16 17:13   ` Chen-Yu Tsai
2016-05-25 12:33     ` Maxime Ripard
2016-05-16 12:47 ` [PATCH 16/20] ARM: sun5i: a13-olinuxino: Enable VGA bridge Maxime Ripard
2016-05-16 12:47 ` [PATCH 17/20] ARM: multi_v7: Enable sun4i DRM driver Maxime Ripard
2016-05-17  3:36   ` Chen-Yu Tsai
2016-05-16 12:47 ` [PATCH 18/20] ARM: multi_v7: enable VGA bridge Maxime Ripard
     [not found] ` <1463402840-17062-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-05-16 12:47   ` [PATCH 02/20] clk: multiplier: Prevent the multiplier from under / over flowing Maxime Ripard
2016-06-10 12:31     ` Maxime Ripard
2016-06-20 20:50     ` Michael Turquette
2016-06-21  9:20       ` Maxime Ripard
2016-05-16 12:47   ` [PATCH 15/20] ARM: sun5i: Move display blocks to A13 Maxime Ripard
2016-05-16 12:47   ` [PATCH 19/20] ARM: sunxi: Enable sun4i DRM driver Maxime Ripard
2016-05-16 15:01     ` Chen-Yu Tsai
2016-05-16 12:47   ` [PATCH 20/20] ARM: sunxi: Enable VGA bridge Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1773896.kpi58ilqqm@avalon \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=daniel.vetter@intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=maxime.ripard@free-electrons.com \
    --cc=mturquette@baylibre.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@codeaurora.org \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).