[PATCH 2/2] drm: bridge: Add THS8134A/B support to dumb VGA DAC

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Sep 12 17:06:40 PDT 2017


Hi Linus,

Thank you for the patch.

On Friday, 1 September 2017 12:40:58 EEST Linus Walleij wrote:
> This extends the dumb VGA DAC bridge to handle the THS8134A
> and THS8134B VGA DACs in addition to those already handled.
> 
> The THS8134A, THS8134B and as it turns out also THS8135 need to
> have data clocked out at the negative edge of the clock pulse,
> since they clock it into the DAC at the positive edge (so by
> then it needs to be stable) so we need some extra logic to flag
> this on the connector to the driver.
> 
> The semantics of the flag DRM_BUS_FLAG_PIXDATA_NEGEDGE in
> <drm/drm_connector.h> clearly indicates that this flag tells
> when to *drive* the data, not when the receiver *reads* it,
> so the TI variants needs to be handled like this.
> 
> Introduce a variant struct and contain the information there,
> and add a bit of helpful comments about how this works so
> people will get it right when adding new DACs or connectiong
> new display drivers to DACs.
> 
> The fact that THS8135 might be working on some systems today
> is probably due to the fact that the display driver cannot
> configure when the data is clocked out and the electronics
> have simply been designed around it so it works anyways.
> 
> The phenomenon is very real on the ARM reference designs using
> PL111 where the hardware can control which edge to push out
> the data.
> 
> Cc: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
> Cc: Bartosz Golaszewski <bgolaszewski at baylibre.com>
> Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
>  drivers/gpu/drm/bridge/dumb-vga-dac.c | 62 ++++++++++++++++++++++++++++++--
>  1 file changed, 59 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c
> b/drivers/gpu/drm/bridge/dumb-vga-dac.c index 831a606c4706..6c2fdcb4fde1
> 100644
> --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
> +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
> @@ -12,6 +12,7 @@
> 
>  #include <linux/module.h>
>  #include <linux/of_graph.h>
> +#include <linux/of_device.h>

Nitpicking, could you keep header files alphabetically sorted ?

>  #include <linux/regulator/consumer.h>
> 
>  #include <drm/drmP.h>
> @@ -19,9 +20,20 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_crtc_helper.h>
> 
> +/**
> + * struct vga_dac_variant - characteristics of the DAC

Nitpicking again, I'd call that vga_dac_info, but it's up to you.

> + * @posedge_clk: this DAC latches data into the DAC on the positive
> + *	edge of the clock pulse, which means that display controllers
> + *	need to clock it out on the negative edge
> + */
> +struct vga_dac_variant {
> +	bool posedge_clk;

How about using DRM_BUS_FLAG_PIXDATA_NEGEDGE and DRM_BUS_FLAG_PIXDATA_POSEDGE 
explicitly instead of a bool ? For additional readability you could also 
rename the field to clk_edge_latch (or something similar), to remove the 
drive/latch ambiguity.

> +};
> +
>  struct dumb_vga {
>  	struct drm_bridge	bridge;
>  	struct drm_connector	connector;
> +	struct vga_dac_variant const *variant;
> 
>  	struct i2c_adapter	*ddc;
>  	struct regulator	*vdd;
> @@ -67,6 +79,18 @@ static int dumb_vga_get_modes(struct drm_connector
> *connector) /* And prefer a mode pretty much anyone can handle */
>  	drm_set_preferred_mode(connector, 1024, 768);
> 
> +	if (vga->variant->posedge_clk)
> +		/*
> +		 * If the DAC latches the data into its registers on the
> +		 * positive edge of the clock, the display driver needs to
> +		 * drive the data out on the negative edge so it is
> +		 * stable at the positive edge, so as to avoid flicker.

That's only true if there's no inverter on the board :-) I wonder how that 
could be modelled though.

> +		 * Tell the driver that we want data on the negative edge
> +		 */
> +		connector->display_info.bus_flags |=
> +			DRM_BUS_FLAG_PIXDATA_NEGEDGE;
> +
>  	return ret;
>  }
> 
> @@ -183,6 +207,7 @@ static int dumb_vga_probe(struct platform_device *pdev)
>  	if (!vga)
>  		return -ENOMEM;
>  	platform_set_drvdata(pdev, vga);
> +	vga->variant = of_device_get_match_data(&pdev->dev);
> 
>  	vga->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
>  	if (IS_ERR(vga->vdd)) {
> @@ -226,10 +251,41 @@ static int dumb_vga_remove(struct platform_device
> *pdev) return 0;
>  }
> 
> +static const struct vga_dac_variant default_dac_variant = {
> +	/*
> +	 * These DACs read data on the negative edge. For example in the
> +	 * ADV7123 datasheet (revision D, page 8) there is a timing diagram
> +	 * making this clear.
> +	 */
> +	.posedge_clk = false,
> +};
> +
> +static const struct vga_dac_variant ti_ths_dac_variant = {
> +	/* The TI DACs read the data on the positive edge of the CLK */
> +	.posedge_clk = true,
> +};
> +
>  static const struct of_device_id dumb_vga_match[] = {
> -	{ .compatible = "dumb-vga-dac" },
> -	{ .compatible = "adi,adv7123" },
> -	{ .compatible = "ti,ths8135" },
> +	{
> +		.compatible = "dumb-vga-dac",
> +		.data = &default_dac_variant,
> +	},
> +	{
> +		.compatible = "adi,adv7123",
> +		.data = &default_dac_variant,
> +	},
> +	{
> +		.compatible = "ti,ths8134a",
> +		.data = &ti_ths_dac_variant,
> +	},
> +	{
> +		.compatible = "ti,ths8134b",
> +		.data = &ti_ths_dac_variant,
> +	},
> +	{
> +		.compatible = "ti,ths8135",
> +		.data = &ti_ths_dac_variant,
> +	},

I wonder whether a generic compatible string for the TI THS813x would make 
sense. I haven't checked the datasheets, but if they're compatible from a 
software point of view, it would be nice not to patch the driver for every 
model (especially if there's more than those three).

>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, dumb_vga_match);

-- 
Regards,

Laurent Pinchart




More information about the linux-arm-kernel mailing list