diff options
author | Zhenyu Wang <zhenyuw@linux.intel.com> | 2009-07-23 13:00:31 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-07-29 18:16:11 -0400 |
commit | 5eb08b69f510fadaba77eb9a1bda0f7299c4ebcc (patch) | |
tree | 107cb7647464fe2f8db7e7fdd652b90494cb2815 /drivers/gpu/drm/i915/intel_display.c | |
parent | eebc863e469cd91d96c4e3636450596ae29f0502 (diff) |
drm/i915: enable DisplayPort support on IGDNG
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 15a8c3908acb..34c50460eaa7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -268,6 +268,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
268 | static bool | 268 | static bool |
269 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, | 269 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
270 | int target, int refclk, intel_clock_t *best_clock); | 270 | int target, int refclk, intel_clock_t *best_clock); |
271 | static bool | ||
272 | intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc, | ||
273 | int target, int refclk, intel_clock_t *best_clock); | ||
271 | 274 | ||
272 | static const intel_limit_t intel_limits_i8xx_dvo = { | 275 | static const intel_limit_t intel_limits_i8xx_dvo = { |
273 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 276 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
@@ -752,6 +755,30 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
752 | } | 755 | } |
753 | 756 | ||
754 | static bool | 757 | static bool |
758 | intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
759 | int target, int refclk, intel_clock_t *best_clock) | ||
760 | { | ||
761 | struct drm_device *dev = crtc->dev; | ||
762 | intel_clock_t clock; | ||
763 | if (target < 200000) { | ||
764 | clock.n = 1; | ||
765 | clock.p1 = 2; | ||
766 | clock.p2 = 10; | ||
767 | clock.m1 = 12; | ||
768 | clock.m2 = 9; | ||
769 | } else { | ||
770 | clock.n = 2; | ||
771 | clock.p1 = 1; | ||
772 | clock.p2 = 10; | ||
773 | clock.m1 = 14; | ||
774 | clock.m2 = 8; | ||
775 | } | ||
776 | intel_clock(dev, refclk, &clock); | ||
777 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
778 | return true; | ||
779 | } | ||
780 | |||
781 | static bool | ||
755 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 782 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
756 | int target, int refclk, intel_clock_t *best_clock) | 783 | int target, int refclk, intel_clock_t *best_clock) |
757 | { | 784 | { |
@@ -763,6 +790,10 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
763 | int err_most = 47; | 790 | int err_most = 47; |
764 | found = false; | 791 | found = false; |
765 | 792 | ||
793 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | ||
794 | return intel_find_pll_igdng_dp(limit, crtc, target, | ||
795 | refclk, best_clock); | ||
796 | |||
766 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 797 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
767 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 798 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
768 | LVDS_CLKB_POWER_UP) | 799 | LVDS_CLKB_POWER_UP) |
@@ -2136,6 +2167,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2136 | int lvds_reg = LVDS; | 2167 | int lvds_reg = LVDS; |
2137 | u32 temp; | 2168 | u32 temp; |
2138 | int sdvo_pixel_multiply; | 2169 | int sdvo_pixel_multiply; |
2170 | int target_clock; | ||
2139 | 2171 | ||
2140 | drm_vblank_pre_modeset(dev, pipe); | 2172 | drm_vblank_pre_modeset(dev, pipe); |
2141 | 2173 | ||
@@ -2218,11 +2250,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2218 | } | 2250 | } |
2219 | 2251 | ||
2220 | /* FDI link */ | 2252 | /* FDI link */ |
2221 | if (IS_IGDNG(dev)) | 2253 | if (IS_IGDNG(dev)) { |
2254 | /* DP over FDI requires target mode clock | ||
2255 | instead of link clock */ | ||
2256 | if (is_dp) | ||
2257 | target_clock = mode->clock; | ||
2258 | else | ||
2259 | target_clock = adjusted_mode->clock; | ||
2222 | igdng_compute_m_n(3, 4, /* lane num 4 */ | 2260 | igdng_compute_m_n(3, 4, /* lane num 4 */ |
2223 | adjusted_mode->clock, | 2261 | target_clock, |
2224 | 270000, /* lane clock */ | 2262 | 270000, /* lane clock */ |
2225 | &m_n); | 2263 | &m_n); |
2264 | } | ||
2226 | 2265 | ||
2227 | if (IS_IGD(dev)) | 2266 | if (IS_IGD(dev)) |
2228 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 2267 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
@@ -3050,6 +3089,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3050 | found = 0; | 3089 | found = 0; |
3051 | if (!found) | 3090 | if (!found) |
3052 | intel_hdmi_init(dev, HDMIB); | 3091 | intel_hdmi_init(dev, HDMIB); |
3092 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | ||
3093 | intel_dp_init(dev, PCH_DP_B); | ||
3053 | } | 3094 | } |
3054 | 3095 | ||
3055 | if (I915_READ(HDMIC) & PORT_DETECTED) | 3096 | if (I915_READ(HDMIC) & PORT_DETECTED) |
@@ -3058,6 +3099,12 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3058 | if (I915_READ(HDMID) & PORT_DETECTED) | 3099 | if (I915_READ(HDMID) & PORT_DETECTED) |
3059 | intel_hdmi_init(dev, HDMID); | 3100 | intel_hdmi_init(dev, HDMID); |
3060 | 3101 | ||
3102 | if (I915_READ(PCH_DP_C) & DP_DETECTED) | ||
3103 | intel_dp_init(dev, PCH_DP_C); | ||
3104 | |||
3105 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | ||
3106 | intel_dp_init(dev, PCH_DP_D); | ||
3107 | |||
3061 | } else if (IS_I9XX(dev)) { | 3108 | } else if (IS_I9XX(dev)) { |
3062 | int found; | 3109 | int found; |
3063 | u32 reg; | 3110 | u32 reg; |