[PATCH 2/3] drm/radeon: workaround a hw bug on some radeon chipsets with all-0 EDIDs.
Alex Deucher
alexdeucher at gmail.com
Mon Jun 13 23:31:55 PDT 2011
On Tue, Jun 14, 2011 at 2:13 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at linux.ie>
>
> Some RS690 chipsets seem to end up with floating connectors, either
> a DVI connector isn't actually populated, or an add-in HDMI card
> is available but not installed. In this case we seem to get a NULL byte
> response for each byte of the i2c transaction, so we detect this
> case and if we see it we don't do anymore DDC transactions on this
> connector.
>
> I've tested this on my RS690 without the HDMI card installed and
> it seems to work fine.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
Just one comment below, but other than that:
Reviewed-by: Alex Deucher <alexdeucher at gmail.com>
> ---
> drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++
> drivers/gpu/drm/radeon/radeon_connectors.c | 7 +++++++
> include/drm/drm_crtc.h | 2 ++
> 3 files changed, 24 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 3618d29..0929219 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -258,6 +258,17 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
> return ret == 2 ? 0 : -1;
> }
>
> +static bool drm_edid_is_zero(u8 *in_edid, int length)
> +{
> + int i;
> + u32 *raw_edid = (u32 *)in_edid;
> +
> + for (i = 0; i < length / 4; i++)
> + if (*(raw_edid + i) != 0)
> + return false;
> + return true;
> +}
> +
> static u8 *
> drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
> {
> @@ -273,6 +284,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
> goto out;
> if (drm_edid_block_valid(block))
> break;
> + if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
> + connector->null_edid_counter++;
> + goto carp;
> + }
> }
> if (i == 4)
> goto carp;
> diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
> index 9c2929c..5c3393f 100644
> --- a/drivers/gpu/drm/radeon/radeon_connectors.c
> +++ b/drivers/gpu/drm/radeon/radeon_connectors.c
> @@ -836,6 +836,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
> if (!radeon_connector->edid) {
> DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
> drm_get_connector_name(connector));
> + /* rs690 seems to have a problem with connectors not existing and always
> + * return a block of 0's. If we see this just stop polling on this output */
> + if ((rdev->family == CHIP_RS690) && radeon_connector->base.null_edid_counter) {
You may want to extend this to RS740 as well since IIRC they were pin
compatible with RS690 and showed up in a lot of similar setups.
> + ret = connector_status_disconnected;
> + DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
> + radeon_connector->ddc_bus = NULL;
> + }
> } else {
> radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
>
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 9573e0c..33d12f8 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -520,6 +520,8 @@ struct drm_connector {
> uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
> uint32_t force_encoder_id;
> struct drm_encoder *encoder; /* currently active encoder */
> +
> + int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
> };
>
> /**
> --
> 1.7.5.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
More information about the dri-devel
mailing list