diff options
author | Zhao Yakui <yakui.zhao@intel.com> | 2010-03-30 03:11:33 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-04-12 12:24:11 -0400 |
commit | 461ed3caee9b615393eb5beb9a8148d230354b41 (patch) | |
tree | 33fb06d5c9b021f8a10fae0c61a094d655778eaa /drivers/gpu/drm/i915 | |
parent | cfecde435dda78248d6fcdc424bed68d5db6be0b (diff) |
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 <yakui.zhao@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 5 | ||||
-rw-r--r-- | 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 8de8194a5e7d..b4ff81527389 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2629,6 +2629,9 @@ | |||
2629 | #define HSYNC_ACTIVE_HIGH (1 << 3) | 2629 | #define HSYNC_ACTIVE_HIGH (1 << 3) |
2630 | #define PORT_DETECTED (1 << 2) | 2630 | #define PORT_DETECTED (1 << 2) |
2631 | 2631 | ||
2632 | /* PCH SDVOB multiplex with HDMIB */ | ||
2633 | #define PCH_SDVOB HDMIB | ||
2634 | |||
2632 | #define HDMIC 0xe1150 | 2635 | #define HDMIC 0xe1150 |
2633 | #define HDMID 0xe1160 | 2636 | #define HDMID 0xe1160 |
2634 | 2637 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 243dfb80cd92..32a248987867 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4670,9 +4670,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
4670 | intel_dp_init(dev, DP_A); | 4670 | intel_dp_init(dev, DP_A); |
4671 | 4671 | ||
4672 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 4672 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
4673 | /* check SDVOB */ | 4673 | /* PCH SDVOB multiplex with HDMIB */ |
4674 | /* found = intel_sdvo_init(dev, HDMIB); */ | 4674 | found = intel_sdvo_init(dev, PCH_SDVOB); |
4675 | found = 0; | ||
4676 | if (!found) | 4675 | if (!found) |
4677 | intel_hdmi_init(dev, HDMIB); | 4676 | intel_hdmi_init(dev, HDMIB); |
4678 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | 4677 | 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 1f4e9e9eac90..ea9cf4c689f6 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) | |||
193 | u32 bval = val, cval = val; | 193 | u32 bval = val, cval = val; |
194 | int i; | 194 | int i; |
195 | 195 | ||
196 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | ||
197 | I915_WRITE(sdvo_priv->sdvo_reg, val); | ||
198 | I915_READ(sdvo_priv->sdvo_reg); | ||
199 | return; | ||
200 | } | ||
201 | |||
196 | if (sdvo_priv->sdvo_reg == SDVOB) { | 202 | if (sdvo_priv->sdvo_reg == SDVOB) { |
197 | cval = I915_READ(SDVOC); | 203 | cval = I915_READ(SDVOC); |
198 | } else { | 204 | } else { |
@@ -369,7 +375,8 @@ static const struct _sdvo_cmd_name { | |||
369 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), | 375 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
370 | }; | 376 | }; |
371 | 377 | ||
372 | #define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") | 378 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
379 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | ||
373 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | 380 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) |
374 | 381 | ||
375 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 382 | 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) | |||
2147 | struct drm_i915_private *dev_priv = dev->dev_private; | 2154 | struct drm_i915_private *dev_priv = dev->dev_private; |
2148 | struct sdvo_device_mapping *my_mapping, *other_mapping; | 2155 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
2149 | 2156 | ||
2150 | if (sdvo_reg == SDVOB) { | 2157 | if (IS_SDVOB(sdvo_reg)) { |
2151 | my_mapping = &dev_priv->sdvo_mappings[0]; | 2158 | my_mapping = &dev_priv->sdvo_mappings[0]; |
2152 | other_mapping = &dev_priv->sdvo_mappings[1]; | 2159 | other_mapping = &dev_priv->sdvo_mappings[1]; |
2153 | } else { | 2160 | } else { |
@@ -2172,7 +2179,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2172 | /* No SDVO device info is found for another DVO port, | 2179 | /* No SDVO device info is found for another DVO port, |
2173 | * so use mapping assumption we had before BIOS parsing. | 2180 | * so use mapping assumption we had before BIOS parsing. |
2174 | */ | 2181 | */ |
2175 | if (sdvo_reg == SDVOB) | 2182 | if (IS_SDVOB(sdvo_reg)) |
2176 | return 0x70; | 2183 | return 0x70; |
2177 | else | 2184 | else |
2178 | return 0x72; | 2185 | return 0x72; |
@@ -2777,6 +2784,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2777 | struct intel_sdvo_priv *sdvo_priv; | 2784 | struct intel_sdvo_priv *sdvo_priv; |
2778 | u8 ch[0x40]; | 2785 | u8 ch[0x40]; |
2779 | int i; | 2786 | int i; |
2787 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | ||
2780 | 2788 | ||
2781 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2789 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
2782 | if (!intel_encoder) { | 2790 | if (!intel_encoder) { |
@@ -2789,11 +2797,21 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2789 | intel_encoder->dev_priv = sdvo_priv; | 2797 | intel_encoder->dev_priv = sdvo_priv; |
2790 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2798 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2791 | 2799 | ||
2800 | if (HAS_PCH_SPLIT(dev)) { | ||
2801 | i2c_reg = PCH_GPIOE; | ||
2802 | ddc_reg = PCH_GPIOE; | ||
2803 | analog_ddc_reg = PCH_GPIOA; | ||
2804 | } else { | ||
2805 | i2c_reg = GPIOE; | ||
2806 | ddc_reg = GPIOE; | ||
2807 | analog_ddc_reg = GPIOA; | ||
2808 | } | ||
2809 | |||
2792 | /* setup the DDC bus. */ | 2810 | /* setup the DDC bus. */ |
2793 | if (sdvo_reg == SDVOB) | 2811 | if (IS_SDVOB(sdvo_reg)) |
2794 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 2812 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB"); |
2795 | else | 2813 | else |
2796 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 2814 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC"); |
2797 | 2815 | ||
2798 | if (!intel_encoder->i2c_bus) | 2816 | if (!intel_encoder->i2c_bus) |
2799 | goto err_inteloutput; | 2817 | goto err_inteloutput; |
@@ -2807,20 +2825,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2807 | for (i = 0; i < 0x40; i++) { | 2825 | for (i = 0; i < 0x40; i++) { |
2808 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2826 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { |
2809 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2827 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2810 | sdvo_reg == SDVOB ? 'B' : 'C'); | 2828 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2811 | goto err_i2c; | 2829 | goto err_i2c; |
2812 | } | 2830 | } |
2813 | } | 2831 | } |
2814 | 2832 | ||
2815 | /* setup the DDC bus. */ | 2833 | /* setup the DDC bus. */ |
2816 | if (sdvo_reg == SDVOB) { | 2834 | if (IS_SDVOB(sdvo_reg)) { |
2817 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2835 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
2818 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2836 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2819 | "SDVOB/VGA DDC BUS"); | 2837 | "SDVOB/VGA DDC BUS"); |
2820 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2838 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2821 | } else { | 2839 | } else { |
2822 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2840 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
2823 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2841 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2824 | "SDVOC/VGA DDC BUS"); | 2842 | "SDVOC/VGA DDC BUS"); |
2825 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2843 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2826 | } | 2844 | } |
@@ -2841,7 +2859,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2841 | if (intel_sdvo_output_setup(intel_encoder, | 2859 | if (intel_sdvo_output_setup(intel_encoder, |
2842 | sdvo_priv->caps.output_flags) != true) { | 2860 | sdvo_priv->caps.output_flags) != true) { |
2843 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2861 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2844 | sdvo_reg == SDVOB ? 'B' : 'C'); | 2862 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2845 | goto err_i2c; | 2863 | goto err_i2c; |
2846 | } | 2864 | } |
2847 | 2865 | ||