From patchwork Tue Jul 20 22:44:17 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barnes X-Patchwork-Id: 113124 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6KMiMvT013889 for ; Tue, 20 Jul 2010 22:44:57 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 156AA9E808 for ; Tue, 20 Jul 2010 15:44:22 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from cpoproxy2-pub.bluehost.com (cpoproxy2-pub.bluehost.com [67.222.39.38]) by gabe.freedesktop.org (Postfix) with SMTP id 758AF9E7DB for ; Tue, 20 Jul 2010 15:44:09 -0700 (PDT) Received: (qmail 19962 invoked by uid 0); 20 Jul 2010 22:44:08 -0000 Received: from unknown (HELO box514.bluehost.com) (74.220.219.114) by cpoproxy2.bluehost.com with SMTP; 20 Jul 2010 22:44:08 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=virtuousgeek.org; h=Received:Date:From:To:Subject:Message-ID:X-Mailer:Mime-Version:Content-Type:Content-Transfer-Encoding:X-Identified-User; b=nQxnHG7qniXX/PTMx6b06o5CxCIkMUiBpABvRDONOlOExL1cJehbYiI8aH2HRbPj6AQT53tIfJtv01B6pV3QJYyy2oWOo23G+/sqUhBo4Ft6P0XbLTWY4ecJSswNnaQp; Received: from [75.110.194.140] (helo=localhost) by box514.bluehost.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.69) (envelope-from ) id 1ObLXk-0004FC-Ag; Tue, 20 Jul 2010 16:44:08 -0600 Date: Tue, 20 Jul 2010 15:44:17 -0700 From: Jesse Barnes To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Message-ID: <20100720154417.32091370@virtuousgeek.org> X-Mailer: Claws Mail 3.7.6 (GTK+ 2.18.9; x86_64-redhat-linux-gnu) Mime-Version: 1.0 X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 75.110.194.140 authed with jbarnes@virtuousgeek.org} Subject: [Intel-gfx] [PATCH 1/2] drm: allow drivers to provide their own EDID fetching routine X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 20 Jul 2010 22:44:57 +0000 (UTC) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 83d8072..fb720e2 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -214,10 +214,10 @@ EXPORT_SYMBOL(drm_edid_is_valid); * * Try to fetch EDID information by calling i2c driver function. */ -static int -drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, - int block, int len) +int +drm_ddc_i2c_edid_read(void *data, unsigned char *buf, int block, int len) { + struct i2c_adapter *adapter = data; unsigned char start = block * EDID_LENGTH; struct i2c_msg msgs[] = { { @@ -238,9 +238,13 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, return -1; } +EXPORT_SYMBOL(drm_ddc_i2c_edid_read); static u8 * -drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) +drm_do_get_edid(struct drm_connector *connector, + int (*edid_read)(void *data, unsigned char *buf, int block, + int len), + void *data) { int i, j = 0; u8 *block, *new; @@ -250,7 +254,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 (edid_read(data, block, 0, EDID_LENGTH)) goto out; if (drm_edid_block_valid(block)) break; @@ -269,8 +273,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, block, j, - EDID_LENGTH)) + if (edid_read(data, block, j, EDID_LENGTH)) goto out; if (drm_edid_block_valid(block + j * EDID_LENGTH)) break; @@ -291,20 +294,6 @@ out: } /** - * Probe DDC presence. - * - * \param adapter : i2c device adaptor - * \return 1 on success - */ -static bool -drm_probe_ddc(struct i2c_adapter *adapter) -{ - unsigned char out; - - return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0); -} - -/** * drm_get_edid - get EDID data, if available * @connector: connector we're probing * @adapter: i2c adapter to use for DDC @@ -315,12 +304,17 @@ drm_probe_ddc(struct i2c_adapter *adapter) * Return edid data or NULL if we couldn't find any. */ struct edid *drm_get_edid(struct drm_connector *connector, - struct i2c_adapter *adapter) + int (*edid_read)(void *data, unsigned char *buf, + int block, int len), + void *data) { struct edid *edid = NULL; + unsigned char out; - if (drm_probe_ddc(adapter)) - edid = (struct edid *)drm_do_get_edid(connector, adapter); + /* Check for presence first */ + if (edid_read(data, &out, 0, 1) == 0) + edid = (struct edid *)drm_do_get_edid(connector, edid_read, + data); connector->display_info.raw_edid = (char *)edid; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3fbedd8..75c7161 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -167,6 +167,7 @@ int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); void intel_i2c_quirk_set(struct drm_device *dev, bool enable); void intel_i2c_reset_gmbus(struct drm_device *dev); +int intel_gmbus_get_modes(struct drm_connector *c, int pin); extern void intel_crt_init(struct drm_device *dev); extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 83bd764..f1c8b30 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -143,7 +143,7 @@ intel_hdmi_detect(struct drm_connector *connector) enum drm_connector_status status = connector_status_disconnected; hdmi_priv->has_hdmi_sink = false; - edid = drm_get_edid(connector, + edid = drm_get_edid(connector, drm_ddc_i2c_edid_read, intel_encoder->ddc_bus); if (edid) { diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 4b1fd3d..35d15f8 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "drmP.h" #include "intel_drv.h" #include "i915_drv.h" @@ -77,7 +78,7 @@ int intel_ddc_get_modes(struct drm_connector *connector, int ret = 0; intel_i2c_quirk_set(connector->dev, true); - edid = drm_get_edid(connector, adapter); + edid = drm_get_edid(connector, drm_ddc_i2c_edid_read, adapter); intel_i2c_quirk_set(connector->dev, false); if (edid) { drm_mode_connector_update_edid_property(connector, edid); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 76993ac..0bdb860 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1514,7 +1514,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) enum drm_connector_status status = connector_status_connected; struct edid *edid = NULL; - edid = drm_get_edid(connector, intel_encoder->ddc_bus); + edid = drm_get_edid(connector, drm_ddc_i2c_edid_read, + intel_encoder->ddc_bus); /* This is only applied to SDVO cards with multiple outputs */ if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { @@ -1527,7 +1528,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) */ while(temp_ddc > 1) { sdvo_priv->ddc_bus = temp_ddc; - edid = drm_get_edid(connector, intel_encoder->ddc_bus); + edid = drm_get_edid(connector, drm_ddc_i2c_edid_read, + intel_encoder->ddc_bus); if (edid) { /* * When we can get the EDID, maybe it is the @@ -1546,7 +1548,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) */ if (edid == NULL && sdvo_priv->analog_ddc_bus && !intel_analog_is_connected(connector->dev)) - edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); + edid = drm_get_edid(connector, drm_ddc_i2c_edid_read, + sdvo_priv->analog_ddc_bus); if (edid != NULL) { bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 149ed22..69c86e7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -260,7 +260,9 @@ nouveau_connector_detect(struct drm_connector *connector) i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); if (i2c) { nouveau_connector_ddc_prepare(connector, &flags); - nv_connector->edid = drm_get_edid(connector, &i2c->adapter); + nv_connector->edid = drm_get_edid(connector, + drm_ddc_i2c_edid_read, + &i2c->adapter); nouveau_connector_ddc_finish(connector, flags); drm_mode_connector_update_edid_property(connector, nv_connector->edid); @@ -693,7 +695,9 @@ nouveau_connector_create_lvds(struct drm_device *dev, if (i2c) { nouveau_connector_ddc_prepare(connector, &flags); - nv_connector->edid = drm_get_edid(connector, &i2c->adapter); + nv_connector->edid = drm_get_edid(connector, + drm_ddc_i2c_edid_read, + &i2c->adapter); nouveau_connector_ddc_finish(connector, flags); } diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index f58f8bd..8e129c2 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -489,6 +489,7 @@ static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connec else { if (radeon_connector->ddc_bus) { radeon_connector->edid = drm_get_edid(&radeon_connector->base, + drm_ddc_i2c_edid_read, &radeon_connector->ddc_bus->adapter); if (radeon_connector->edid) ret = connector_status_connected; @@ -601,7 +602,7 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect kfree(radeon_connector->edid); radeon_connector->edid = NULL; } - radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); + radeon_connector->edid = drm_get_edid(&radeon_connector->base, drm_ddc_i2c_edid_read, &radeon_connector->ddc_bus->adapter); if (!radeon_connector->edid) { DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", @@ -753,7 +754,7 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect kfree(radeon_connector->edid); radeon_connector->edid = NULL; } - radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); + radeon_connector->edid = drm_get_edid(&radeon_connector->base, drm_ddc_i2c_edid_read, &radeon_connector->ddc_bus->adapter); if (!radeon_connector->edid) { DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8154cdf..0f40c93 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -400,12 +400,12 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) - radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); + radeon_connector->edid = drm_get_edid(&radeon_connector->base, drm_ddc_i2c_edid_read, &dig->dp_i2c_bus->adapter); } if (!radeon_connector->ddc_bus) return -1; if (!radeon_connector->edid) { - radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); + radeon_connector->edid = drm_get_edid(&radeon_connector->base, drm_ddc_i2c_edid_read, &radeon_connector->ddc_bus->adapter); } /* some servers provide a hardcoded edid in rom for KVMs */ if (!radeon_connector->edid) @@ -427,7 +427,7 @@ static int radeon_ddc_dump(struct drm_connector *connector) if (!radeon_connector->ddc_bus) return -1; - edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); + edid = drm_get_edid(connector, drm_ddc_i2c_edid_read, &radeon_connector->ddc_bus->adapter); if (edid) { kfree(edid); } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 93a1a31..027286e 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -664,7 +664,10 @@ extern char *drm_get_tv_select_name(int val); extern void drm_fb_release(struct drm_file *file_priv); extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); extern struct edid *drm_get_edid(struct drm_connector *connector, - struct i2c_adapter *adapter); + int (*edid_read)(void *data, + unsigned char *buf, + int block, int len), + void *data); extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode); diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 39e2cc5..af6ccfa 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -201,4 +201,7 @@ struct edid { #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) +extern int drm_ddc_i2c_edid_read(void *data, unsigned char *buf, int block, + int len); + #endif /* __DRM_EDID_H__ */