From 93c472a33c59276a942900255b5a8ebe023938e8 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 30 Mar 2010 15:11:33 +0800 Subject: drm/i915: Add support of SDVO on Ibexpeak PCH SDVO on Ibexpeak PCH with Ironlake is multiplexed with HDMIB port, and only has SDVOB port. Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_display.c | 5 ++-- drivers/gpu/drm/i915/intel_sdvo.c | 44 +++++++++++++++++++++++++----------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cbbf59f56df..c8a3dff089c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2585,6 +2585,9 @@ #define HSYNC_ACTIVE_HIGH (1 << 3) #define PORT_DETECTED (1 << 2) +/* PCH SDVOB multiplex with HDMIB */ +#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 eb0f0ec439f..bffe1fc455a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4411,9 +4411,8 @@ 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; + /* PCH SDVOB multiplex with HDMIB */ + 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 b2ad62151ad..13638a038ef 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -193,6 +193,12 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) u32 bval = val, cval = val; int i; + if (sdvo_priv->sdvo_reg == PCH_SDVOB) { + I915_WRITE(sdvo_priv->sdvo_reg, val); + I915_READ(sdvo_priv->sdvo_reg); + return; + } + if (sdvo_priv->sdvo_reg == SDVOB) { cval = I915_READ(SDVOC); } else { @@ -369,7 +375,8 @@ static const struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), }; -#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") +#define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) +#define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, @@ -2209,7 +2216,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) struct drm_i915_private *dev_priv = dev->dev_private; struct sdvo_device_mapping *my_mapping, *other_mapping; - if (sdvo_reg == SDVOB) { + if (IS_SDVOB(sdvo_reg)) { my_mapping = &dev_priv->sdvo_mappings[0]; other_mapping = &dev_priv->sdvo_mappings[1]; } else { @@ -2234,7 +2241,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) /* No SDVO device info is found for another DVO port, * so use mapping assumption we had before BIOS parsing. */ - if (sdvo_reg == SDVOB) + if (IS_SDVOB(sdvo_reg)) return 0x70; else return 0x72; @@ -2839,6 +2846,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) struct intel_sdvo_priv *sdvo_priv; u8 ch[0x40]; int i; + u32 i2c_reg, ddc_reg, analog_ddc_reg; intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); if (!intel_encoder) { @@ -2851,11 +2859,21 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) intel_encoder->dev_priv = sdvo_priv; intel_encoder->type = INTEL_OUTPUT_SDVO; + if (HAS_PCH_SPLIT(dev)) { + i2c_reg = PCH_GPIOE; + ddc_reg = PCH_GPIOE; + analog_ddc_reg = PCH_GPIOA; + } else { + i2c_reg = GPIOE; + ddc_reg = GPIOE; + analog_ddc_reg = GPIOA; + } + /* setup the DDC bus. */ - if (sdvo_reg == SDVOB) - intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); + if (IS_SDVOB(sdvo_reg)) + intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB"); else - intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); + intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC"); if (!intel_encoder->i2c_bus) goto err_inteloutput; @@ -2869,20 +2887,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) 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", - sdvo_reg == SDVOB ? 'B' : 'C'); + IS_SDVOB(sdvo_reg) ? 'B' : 'C'); goto err_i2c; } } /* setup the DDC bus. */ - if (sdvo_reg == SDVOB) { - intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); - sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, + if (IS_SDVOB(sdvo_reg)) { + intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); + sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, "SDVOB/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; } else { - intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); - sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, + intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); + sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, "SDVOC/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; } @@ -2903,7 +2921,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) if (intel_sdvo_output_setup(intel_encoder, sdvo_priv->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", - sdvo_reg == SDVOB ? 'B' : 'C'); + IS_SDVOB(sdvo_reg) ? 'B' : 'C'); goto err_i2c; } -- cgit v1.2.3