aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-06-16 09:45:17 -0400
committerDave Airlie <airlied@redhat.com>2012-06-16 09:45:17 -0400
commitc4af5c4597a7a5d64e058703e1328f315a59794e (patch)
treeb03d40d2be5d6c71c50988c2b99f8145880cc2d8 /drivers/gpu
parent7c77bf2a1a8bf67d580a3b189b37fded0a13ab78 (diff)
parentd6f24d0fa6cdf3431a2fe3330a74bc6c5871f496 (diff)
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes
* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel: drm/i915: cache the EDID for eDP panels Revert "drm/i915/dp: Use auxch precharge value of 5 everywhere" drm/i915: eDP aux needs vdd drm/i915: don't enumerate HDMID if an eDP panel is already active on the port
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c2
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c60
2 files changed, 54 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e0aa064def31..a7c727d0c105 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6558,7 +6558,7 @@ static void intel_setup_outputs(struct drm_device *dev)
6558 if (I915_READ(HDMIC) & PORT_DETECTED) 6558 if (I915_READ(HDMIC) & PORT_DETECTED)
6559 intel_hdmi_init(dev, HDMIC); 6559 intel_hdmi_init(dev, HDMIC);
6560 6560
6561 if (I915_READ(HDMID) & PORT_DETECTED) 6561 if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED)
6562 intel_hdmi_init(dev, HDMID); 6562 intel_hdmi_init(dev, HDMID);
6563 6563
6564 if (I915_READ(PCH_DP_C) & DP_DETECTED) 6564 if (I915_READ(PCH_DP_C) & DP_DETECTED)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 296cfc201a81..c0449324143c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -32,6 +32,7 @@
32#include "drm.h" 32#include "drm.h"
33#include "drm_crtc.h" 33#include "drm_crtc.h"
34#include "drm_crtc_helper.h" 34#include "drm_crtc_helper.h"
35#include "drm_edid.h"
35#include "intel_drv.h" 36#include "intel_drv.h"
36#include "i915_drm.h" 37#include "i915_drm.h"
37#include "i915_drv.h" 38#include "i915_drv.h"
@@ -67,6 +68,8 @@ struct intel_dp {
67 struct drm_display_mode *panel_fixed_mode; /* for eDP */ 68 struct drm_display_mode *panel_fixed_mode; /* for eDP */
68 struct delayed_work panel_vdd_work; 69 struct delayed_work panel_vdd_work;
69 bool want_panel_vdd; 70 bool want_panel_vdd;
71 struct edid *edid; /* cached EDID for eDP */
72 int edid_mode_count;
70}; 73};
71 74
72/** 75/**
@@ -371,7 +374,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
371 int recv_bytes; 374 int recv_bytes;
372 uint32_t status; 375 uint32_t status;
373 uint32_t aux_clock_divider; 376 uint32_t aux_clock_divider;
374 int try, precharge = 5; 377 int try, precharge;
375 378
376 intel_dp_check_edp(intel_dp); 379 intel_dp_check_edp(intel_dp);
377 /* The clock divider is based off the hrawclk, 380 /* The clock divider is based off the hrawclk,
@@ -391,6 +394,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
391 else 394 else
392 aux_clock_divider = intel_hrawclk(dev) / 2; 395 aux_clock_divider = intel_hrawclk(dev) / 2;
393 396
397 if (IS_GEN6(dev))
398 precharge = 3;
399 else
400 precharge = 5;
401
394 /* Try to wait for any previous AUX channel activity */ 402 /* Try to wait for any previous AUX channel activity */
395 for (try = 0; try < 3; try++) { 403 for (try = 0; try < 3; try++) {
396 status = I915_READ(ch_ctl); 404 status = I915_READ(ch_ctl);
@@ -1973,6 +1981,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
1973 if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) 1981 if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
1974 return; 1982 return;
1975 1983
1984 ironlake_edp_panel_vdd_on(intel_dp);
1985
1976 if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3)) 1986 if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
1977 DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", 1987 DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
1978 buf[0], buf[1], buf[2]); 1988 buf[0], buf[1], buf[2]);
@@ -1980,6 +1990,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
1980 if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3)) 1990 if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3))
1981 DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", 1991 DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
1982 buf[0], buf[1], buf[2]); 1992 buf[0], buf[1], buf[2]);
1993
1994 ironlake_edp_panel_vdd_off(intel_dp, false);
1983} 1995}
1984 1996
1985static bool 1997static bool
@@ -2116,10 +2128,22 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
2116{ 2128{
2117 struct intel_dp *intel_dp = intel_attached_dp(connector); 2129 struct intel_dp *intel_dp = intel_attached_dp(connector);
2118 struct edid *edid; 2130 struct edid *edid;
2131 int size;
2132
2133 if (is_edp(intel_dp)) {
2134 if (!intel_dp->edid)
2135 return NULL;
2136
2137 size = (intel_dp->edid->extensions + 1) * EDID_LENGTH;
2138 edid = kmalloc(size, GFP_KERNEL);
2139 if (!edid)
2140 return NULL;
2141
2142 memcpy(edid, intel_dp->edid, size);
2143 return edid;
2144 }
2119 2145
2120 ironlake_edp_panel_vdd_on(intel_dp);
2121 edid = drm_get_edid(connector, adapter); 2146 edid = drm_get_edid(connector, adapter);
2122 ironlake_edp_panel_vdd_off(intel_dp, false);
2123 return edid; 2147 return edid;
2124} 2148}
2125 2149
@@ -2129,9 +2153,17 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada
2129 struct intel_dp *intel_dp = intel_attached_dp(connector); 2153 struct intel_dp *intel_dp = intel_attached_dp(connector);
2130 int ret; 2154 int ret;
2131 2155
2132 ironlake_edp_panel_vdd_on(intel_dp); 2156 if (is_edp(intel_dp)) {
2157 drm_mode_connector_update_edid_property(connector,
2158 intel_dp->edid);
2159 ret = drm_add_edid_modes(connector, intel_dp->edid);
2160 drm_edid_to_eld(connector,
2161 intel_dp->edid);
2162 connector->display_info.raw_edid = NULL;
2163 return intel_dp->edid_mode_count;
2164 }
2165
2133 ret = intel_ddc_get_modes(connector, adapter); 2166 ret = intel_ddc_get_modes(connector, adapter);
2134 ironlake_edp_panel_vdd_off(intel_dp, false);
2135 return ret; 2167 return ret;
2136} 2168}
2137 2169
@@ -2321,6 +2353,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
2321 i2c_del_adapter(&intel_dp->adapter); 2353 i2c_del_adapter(&intel_dp->adapter);
2322 drm_encoder_cleanup(encoder); 2354 drm_encoder_cleanup(encoder);
2323 if (is_edp(intel_dp)) { 2355 if (is_edp(intel_dp)) {
2356 kfree(intel_dp->edid);
2324 cancel_delayed_work_sync(&intel_dp->panel_vdd_work); 2357 cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
2325 ironlake_panel_vdd_off_sync(intel_dp); 2358 ironlake_panel_vdd_off_sync(intel_dp);
2326 } 2359 }
@@ -2504,11 +2537,14 @@ intel_dp_init(struct drm_device *dev, int output_reg)
2504 break; 2537 break;
2505 } 2538 }
2506 2539
2540 intel_dp_i2c_init(intel_dp, intel_connector, name);
2541
2507 /* Cache some DPCD data in the eDP case */ 2542 /* Cache some DPCD data in the eDP case */
2508 if (is_edp(intel_dp)) { 2543 if (is_edp(intel_dp)) {
2509 bool ret; 2544 bool ret;
2510 struct edp_power_seq cur, vbt; 2545 struct edp_power_seq cur, vbt;
2511 u32 pp_on, pp_off, pp_div; 2546 u32 pp_on, pp_off, pp_div;
2547 struct edid *edid;
2512 2548
2513 pp_on = I915_READ(PCH_PP_ON_DELAYS); 2549 pp_on = I915_READ(PCH_PP_ON_DELAYS);
2514 pp_off = I915_READ(PCH_PP_OFF_DELAYS); 2550 pp_off = I915_READ(PCH_PP_OFF_DELAYS);
@@ -2576,9 +2612,19 @@ intel_dp_init(struct drm_device *dev, int output_reg)
2576 intel_dp_destroy(&intel_connector->base); 2612 intel_dp_destroy(&intel_connector->base);
2577 return; 2613 return;
2578 } 2614 }
2579 }
2580 2615
2581 intel_dp_i2c_init(intel_dp, intel_connector, name); 2616 ironlake_edp_panel_vdd_on(intel_dp);
2617 edid = drm_get_edid(connector, &intel_dp->adapter);
2618 if (edid) {
2619 drm_mode_connector_update_edid_property(connector,
2620 edid);
2621 intel_dp->edid_mode_count =
2622 drm_add_edid_modes(connector, edid);
2623 drm_edid_to_eld(connector, edid);
2624 intel_dp->edid = edid;
2625 }
2626 ironlake_edp_panel_vdd_off(intel_dp, false);
2627 }
2582 2628
2583 intel_encoder->hot_plug = intel_dp_hot_plug; 2629 intel_encoder->hot_plug = intel_dp_hot_plug;
2584 2630