[Intel-gfx] [PATCH 4/4] drm/i915: Add the support of SDVO on Ibexpeak PCH

Zhenyu Wang zhenyuw at linux.intel.com
Tue Mar 9 03:21:59 CET 2010


From: Zhao Yakui <yakui.zhao at intel.com>

The Ironlake also supports the SDVO, which is multiplexed on the
HDMI port. But it has only SDVOB port.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |    2 +
 drivers/gpu/drm/i915/intel_display.c |    8 +++--
 drivers/gpu/drm/i915/intel_sdvo.c    |   54 +++++++++++++++++++++++++---------
 3 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1fcc4c9..8244080 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2573,6 +2573,8 @@
 #define  HSYNC_ACTIVE_HIGH      (1 << 3)
 #define  PORT_DETECTED          (1 << 2)
 
+#define PCH_SDVOB	HDMIB
+
 #define HDMIC   0xe1150
 #define HDMID   0xe1160
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 529c775..f9a32a4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4423,9 +4423,11 @@ static void intel_setup_outputs(struct drm_device *dev)
 			intel_dp_init(dev, DP_A);
 
 		if (I915_READ(HDMIB) & PORT_DETECTED) {
-			/* check SDVOB */
-			/* found = intel_sdvo_init(dev, HDMIB); */
-			found = 0;
+			/*
+			 * On Ironlake the HDMIB is also used as SDVOB port and
+			 * it is defined as PCH_SDVOB.
+			 */
+			found = intel_sdvo_init(dev, PCH_SDVOB);
 			if (!found)
 				intel_hdmi_init(dev, HDMIB);
 			if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 6181594..7ce369a 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -198,6 +198,12 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
 	u32 bval = val, cval = val;
 	int i;
 
+	if (sdvo_encoder->output_device == PCH_SDVOB) {
+		I915_WRITE(PCH_SDVOB, bval);
+		I915_READ(PCH_SDVOB);
+		return;
+	}
+
 	if (sdvo_encoder->output_device == SDVOB) {
 		cval = I915_READ(SDVOC);
 	} else {
@@ -374,7 +380,10 @@ static const struct _sdvo_cmd_name {
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
 };
 
-#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
+#define IS_SDVOB(output_device) ((output_device) == SDVOB ||\
+					(output_device) == PCH_SDVOB)
+#define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->output_device) ? "SDVOB"\
+				: "SDVOC")
 
 static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
 				   void *args, int args_len)
@@ -2317,7 +2326,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct sdvo_device_mapping *my_mapping, *other_mapping;
 
-	if (output_device == SDVOB) {
+	if (IS_SDVOB(output_device)) {
 		my_mapping = &dev_priv->sdvo_mappings[0];
 		other_mapping = &dev_priv->sdvo_mappings[1];
 	} else {
@@ -2342,7 +2351,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
 	/* No SDVO device info is found for another DVO port,
 	 * so use mapping assumption we had before BIOS parsing.
 	 */
-	if (output_device == SDVOB)
+	if (IS_SDVOB(output_device))
 		return 0x70;
 	else
 		return 0x72;
@@ -2354,6 +2363,7 @@ intel_sdvo_connector_alloc (struct drm_device *dev, struct intel_connector **ret
 	struct intel_connector *intel_connector;
 	struct intel_sdvo_connector *sdvo_connector;
 	struct drm_connector *connector;
+	u32 connector_ddc_reg, analog_ddc_reg;
 
 	*ret = kzalloc(sizeof(*intel_connector) +
 		       sizeof(*sdvo_connector), GFP_KERNEL);
@@ -2364,9 +2374,17 @@ intel_sdvo_connector_alloc (struct drm_device *dev, struct intel_connector **ret
 	sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1);
 	intel_connector->dev_priv = sdvo_connector;
 
-	intel_connector->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVO DDC BUS");
-	sdvo_connector->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
-						"SDVO/VGA DDC BUS");
+	if (HAS_PCH_SPLIT(dev)) {
+		connector_ddc_reg = PCH_GPIOE;
+		analog_ddc_reg = PCH_GPIOA;
+	} else {
+		connector_ddc_reg = GPIOE;
+		analog_ddc_reg = GPIOA;
+	}
+	intel_connector->ddc_bus = intel_i2c_create(dev,
+				connector_ddc_reg, "SDVO DDC BUS");
+	sdvo_connector->analog_ddc_bus = intel_i2c_create(dev,
+				analog_ddc_reg, "SDVO/VGA DDC BUS");
 	if (!intel_connector->ddc_bus || !sdvo_connector->analog_ddc_bus) {
 		kfree(intel_connector);
 		return false;
@@ -2960,6 +2978,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	struct drm_encoder *encoder;
 	struct intel_encoder *intel_encoder;
 	struct intel_sdvo_encoder *sdvo_encoder;
+	u32 sdvo_i2c_reg;
 	u8 ch[0x40];
 	int i;
 
@@ -2975,9 +2994,14 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	intel_encoder->type = INTEL_OUTPUT_SDVO;
 
 	/* setup the DDC bus. */
-	if (output_device == SDVOB)
-		intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
-	else
+	if (IS_SDVOB(output_device)) {
+		if (output_device == PCH_SDVOB)
+			sdvo_i2c_reg = PCH_GPIOE;
+		else
+			sdvo_i2c_reg = GPIOE;
+		intel_encoder->i2c_bus = intel_i2c_create(dev,
+				sdvo_i2c_reg, "SDVOCTRL_E for SDVOB");
+	} else
 		intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
 	if (!intel_encoder->i2c_bus)
@@ -2992,14 +3016,16 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	for (i = 0; i < 0x40; i++) {
 		if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
 			DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
-					output_device == SDVOB ? 'B' : 'C');
+					IS_SDVOB(output_device) ? 'B' : 'C');
 			goto err;
 		}
 	}
 
-	if (output_device == SDVOB)
-		dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
-	else
+	if (IS_SDVOB(output_device)) {
+		if (output_device == SDVOB)
+			dev_priv->hotplug_supported_mask |=
+						SDVOB_HOTPLUG_INT_STATUS;
+	} else
 		dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
 
 	encoder = &intel_encoder->base;
@@ -3012,7 +3038,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 
 	if (intel_sdvo_output_setup(intel_encoder) != true) {
 		DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
-			  output_device == SDVOB ? 'B' : 'C');
+			  IS_SDVOB(output_device) ? 'B' : 'C');
 		goto err;
 	}
 
-- 
1.7.0




More information about the Intel-gfx mailing list