dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Cc: linux-sh@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v4 6/9] drm: Decouple EDID parsing from I2C adapter
Date: Wed, 26 Nov 2014 08:28:34 +0100	[thread overview]
Message-ID: <20141126072834.GA32117@phenom.ffwll.local> (raw)
In-Reply-To: <1416959247-23132-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

On Wed, Nov 26, 2014 at 01:47:27AM +0200, Laurent Pinchart wrote:
> From: Lars-Peter Clausen <lars@metafoo.de>
> 
> The drm_get_edid() function performs direct I2C accesses to read EDID
> blocks, assuming that the monitor DDC interface is directly connected to
> the I2C bus. It can't thus be used with HDMI encoders that control the
> DDC bus and expose EDID blocks through a different interface.
> 
> Refactor drm_do_get_edid() to take a block read callback function
> instead of an I2C adapter, and export it for direct use by drivers.
> 
> As in the general case the DDC bus is accessible by the kernel at the
> I2C level, drivers must make all reasonable efforts to expose it as an
> I2C adapter and use drm_get_edid() instead of abusing this function.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/drm_edid.c | 43 ++++++++++++++++++++++++++++++-------------
>  include/drm/drm_edid.h     |  5 +++++
>  2 files changed, 35 insertions(+), 13 deletions(-)
> 
> Daniel, could you please review and hopefully ack this ? If this new version is
> acceptable I'd like to send an updated pull request for R-Car DU HDMI support
> for v3.19, so time is running short.
> 
> Changes since v3:
> 
> - Add kerneldoc for the new exported drm_do_get_edid function
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 3bf999134bcc..1a77a49d2695 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1125,9 +1125,9 @@ EXPORT_SYMBOL(drm_edid_is_valid);
>   * Return: 0 on success or -1 on failure.
>   */
>  static int
> -drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
> -		      int block, int len)
> +drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
>  {
> +	struct i2c_adapter *adapter = data;
>  	unsigned char start = block * EDID_LENGTH;
>  	unsigned char segment = block >> 1;
>  	unsigned char xfers = segment ? 3 : 2;
> @@ -1184,8 +1184,26 @@ static bool drm_edid_is_zero(u8 *in_edid, int length)
>  	return true;
>  }
>  
> -static u8 *
> -drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
> +/**
> + * drm_do_get_edid - get EDID data using a custom EDID block read function
> + * @connector: connector we're probing
> + * @get_edid_block: EDID block read function
> + * @data: private data passed to the block read function
> + *
> + * When the I2C adapter connected to the DDC bus is hidden behind a device that
> + * exposes a different interface to read EDID blocks this function can be used
> + * to get EDID data using a custom block read function.
> + *
> + * As in the general case the DDC bus is accessible by the kernel at the I2C
> + * level, drivers must make all reasonable efforts to expose it as an I2C
> + * adapter and use drm_get_edid() instead of abusing this function.
> + *
> + * Return: Pointer to valid EDID or NULL if we couldn't find any.
> + */
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +	int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
> +			      size_t len),
> +	void *data)
>  {
>  	int i, j = 0, valid_extensions = 0;
>  	u8 *block, *new;
> @@ -1196,7 +1214,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
>  
>  	/* base block fetch */
>  	for (i = 0; i < 4; i++) {
> -		if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
> +		if (get_edid_block(data, block, 0, EDID_LENGTH))
>  			goto out;
>  		if (drm_edid_block_valid(block, 0, print_bad_edid))
>  			break;
> @@ -1210,7 +1228,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
>  
>  	/* if there's no extensions, we're done */
>  	if (block[0x7e] == 0)
> -		return block;
> +		return (struct edid *)block;
>  
>  	new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
>  	if (!new)
> @@ -1219,7 +1237,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
>  
>  	for (j = 1; j <= block[0x7e]; j++) {
>  		for (i = 0; i < 4; i++) {
> -			if (drm_do_probe_ddc_edid(adapter,
> +			if (get_edid_block(data,
>  				  block + (valid_extensions + 1) * EDID_LENGTH,
>  				  j, EDID_LENGTH))
>  				goto out;
> @@ -1247,7 +1265,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
>  		block = new;
>  	}
>  
> -	return block;
> +	return (struct edid *)block;
>  
>  carp:
>  	if (print_bad_edid) {
> @@ -1260,6 +1278,7 @@ out:
>  	kfree(block);
>  	return NULL;
>  }
> +EXPORT_SYMBOL_GPL(drm_do_get_edid);
>  
>  /**
>   * drm_probe_ddc() - probe DDC presence
> @@ -1289,12 +1308,10 @@ EXPORT_SYMBOL(drm_probe_ddc);
>  struct edid *drm_get_edid(struct drm_connector *connector,
>  			  struct i2c_adapter *adapter)
>  {
> -	struct edid *edid = NULL;
> -
> -	if (drm_probe_ddc(adapter))
> -		edid = (struct edid *)drm_do_get_edid(connector, adapter);
> +	if (!drm_probe_ddc(adapter))
> +		return NULL;
>  
> -	return edid;
> +	return drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index c2f1bfa22010..d59240ffb1f7 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -381,4 +381,9 @@ static inline int drm_eld_size(const uint8_t *eld)
>  	return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
>  }
>  
> +struct edid *drm_do_get_edid(struct drm_connector *connector,
> +	int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
> +			      size_t len),
> +	void *data);
> +
>  #endif /* __DRM_EDID_H__ */
> -- 
> 2.0.4
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2014-11-26  7:28 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-26 15:24 [PATCH v3 0/9] Renesas R-Car DU HDMI support Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 1/9] drm: rcar-du: Remove platform data support Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 2/9] drm: rcar-du: Pass the encoder DT node to rcar_du_encoder_init() Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 3/9] drm: rcar-du: Replace direct DRM encoder access with cast macro Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 4/9] drm: rcar-du: Replace drm_encoder with drm_slave_encoder Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 5/9] drm: rcar-du: Add HDMI encoder and connector support Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 6/9] drm: Decouple EDID parsing from I2C adapter Laurent Pinchart
2014-11-25 23:47   ` [PATCH v4 " Laurent Pinchart
2014-11-26  0:38     ` Rob Clark
2014-11-26 19:06       ` Laurent Pinchart
2014-11-26  7:28     ` Daniel Vetter [this message]
2014-10-26 15:24 ` [PATCH v3 7/9] video: Add ADV751[13] DT bindings documentation Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 8/9] drm: Add adv7511 encoder driver Laurent Pinchart
2014-10-26 15:24 ` [PATCH v3 9/9] ARM: shmobile: koelsch: Add DU HDMI output support Laurent Pinchart
2014-10-28  5:30 ` [PATCH v3 0/9] Renesas R-Car DU HDMI support Dave Airlie
2014-10-30 11:05   ` Laurent Pinchart
2014-10-30 11:29     ` Simon Horman
2014-10-30 11:40       ` Laurent Pinchart
2014-10-31  8:18         ` Simon Horman

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=20141126072834.GA32117@phenom.ffwll.local \
    --to=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=linux-sh@vger.kernel.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