drm/i915: Add support of SDVO on Ibexpeak PCH
authorZhao Yakui <yakui.zhao@intel.com>
Tue, 30 Mar 2010 07:11:33 +0000 (15:11 +0800)
committerEric Anholt <eric@anholt.net>
Mon, 12 Apr 2010 16:24:11 +0000 (09:24 -0700)
SDVO on Ibexpeak PCH with Ironlake is multiplexed with
HDMIB port, and only has SDVOB port.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_sdvo.c

index 8de8194a5e7d376b81d3b59866bf11f26cd8fb01..b4ff815273899cc4e722914f26343af4eb203b7f 100644 (file)
 #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
 
index 243dfb80cd92b0564fc2e922f49fc74e218ded2d..32a248987867e8869fa63e5ffaf7112140966698 100644 (file)
@@ -4670,9 +4670,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))
index 1f4e9e9eac904a540f740993cc354765d973361b..ea9cf4c689f6aff124972275682165e17537739a 100644 (file)
@@ -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,
@@ -2147,7 +2154,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 {
@@ -2172,7 +2179,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;
@@ -2777,6 +2784,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) {
@@ -2789,11 +2797,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;
@@ -2807,20 +2825,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;
        }
@@ -2841,7 +2859,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;
        }