[Intel-gfx] [RFC][PATCH 2/2] drm/i915: dynamically re-register real sdvo output based on detected result
Ma Ling
ling.ma at intel.com
Fri Apr 17 06:15:57 CEST 2009
If sdvo have multiple outputs available, chose the real one and modify corresponding connector type.
Signed-off-by: Ma Ling <ling.ma at intel.com>
---
because we could call
drivers/gpu/drm/i915/intel_sdvo.c | 63 +++++++++++++++++++++++++++++++++---
1 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 96e9012..01be590 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -57,6 +57,12 @@ struct intel_sdvo_priv {
/* Pixel clock limitations reported by the SDVO device, in kHz */
int pixel_clock_min, pixel_clock_max;
+ /*
+ * For multiple function SDVO device,
+ * this is for current attached outputs.
+ */
+ uint16_t attached_output;
+
/**
* This is set if we're going to treat the device as TV-out.
*
@@ -102,6 +108,8 @@ struct intel_sdvo_priv {
};
static struct edid *intel_sdvo_get_ddc_edid(struct intel_output *intel_output);
+static bool
+intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
/**
* Writes the SDVOB or SDVOC with the given value, but always writes both
@@ -1377,25 +1385,68 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
}
}
+static bool
+intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+{
+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ int caps = 0;
+
+ if (sdvo_priv->caps.output_flags &
+ (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
+ caps++;
+ if (sdvo_priv->caps.output_flags &
+ (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1))
+ caps++;
+ if (sdvo_priv->caps.output_flags & (SDVO_OUTPUT_CVBS0 |
+ SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0 |
+ SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_CVBS1 |
+ SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_YPRPB1 |
+ SDVO_OUTPUT_SCART1))
+ caps++;
+ if (sdvo_priv->caps.output_flags & (SDVO_OUTPUT_LVDS0 |
+ SDVO_OUTPUT_LVDS1))
+ caps++;
+
+ return (caps > 1);
+}
+
static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
{
- u8 response[2];
+ uint16_t response;
u8 status;
struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
status = intel_sdvo_read_response(intel_output, &response, 2);
- DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
+ DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8);
if (status != SDVO_CMD_STATUS_SUCCESS)
return connector_status_unknown;
- if ((response[0] != 0) || (response[1] != 0)) {
- intel_sdvo_hdmi_sink_detect(connector);
- return connector_status_connected;
- } else
+ if (response == 0)
return connector_status_disconnected;
+
+ if (intel_sdvo_multifunc_encoder(intel_output) &&
+ sdvo_priv->attached_output != response) {
+ if (intel_sdvo_output_setup(intel_output, response) != true)
+ return connector_status_unknown;
+ sdvo_priv->attached_output = response;
+ }
+
+ if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
+ /* Check EDID in DVI-I case */
+ struct edid *edid = intel_sdvo_get_ddc_edid(intel_output);
+ if (edid != NULL) {
+ int digital = edid->digital;
+ kfree(edid);
+ if (digital == 0)
+ return connector_status_disconnected;
+ }
+ }
+
+ return connector_status_connected;
}
#define MAX_EDID_EXT_NUM 4
--
1.5.4.4
More information about the Intel-gfx
mailing list