Re: [Intel-gfx] [PATCH] drm/i915/dp: move edp init to work queue

2015-03-19 Thread shuang . he
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: 
shuang...@intel.com)
Task id: 5997
-Summary-
Platform  Delta  drm-intel-nightly  Series Applied
PNV -2  272/272  270/272
ILK  301/301  301/301
SNB  303/303  303/303
IVB  342/342  342/342
BYT  287/287  287/287
HSW  362/362  362/362
BDW  308/308  308/308
-Detailed-
Platform  Testdrm-intel-nightly  Series 
Applied
*PNV  igt_gem_userptr_blits_minor-unsync-interruptible  PASS(1)  
DMESG_WARN(1)PASS(1)
*PNV  igt_gem_userptr_blits_minor-unsync-normal  PASS(1)  
DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915/dp: move edp init to work queue

2015-03-18 Thread Jesse Barnes
This helps speed up driver init time, and puts off the eDP stuff until
we actually need it.

Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org
---
 drivers/gpu/drm/i915/intel_dp.c  | 103 ++-
 drivers/gpu/drm/i915/intel_drv.h |   3 ++
 2 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5256c06..2abd339 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3768,6 +3768,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
 
DRM_DEBUG_KMS(DPCD: %*ph\n, (int) sizeof(intel_dp-dpcd), 
intel_dp-dpcd);
 
+   if (intel_dp-dpcd_valid)
+   return true;
+
if (intel_dp-dpcd[DP_DPCD_REV] == 0)
return false; /* DPCD not present */
 
@@ -4012,6 +4015,25 @@ go_again:
return -EINVAL;
 }
 
+static void intel_flush_edp_cache_work(struct intel_dp *intel_dp)
+{
+   struct drm_device *dev = intel_dp-attached_connector-base.dev;
+
+   WARN_ON(!mutex_is_locked(dev-mode_config.mutex));
+
+   if (!is_edp(intel_dp))
+   return;
+
+   /*
+* FIXME: we need to synchronize this at a higher level, like the
+* first mode set or other display I/O activity.  Maybe re-use
+* async mode setting entry points?
+*/
+   mutex_unlock(dev-mode_config.mutex);
+   flush_work(intel_dp-edp_cache_work);
+   mutex_lock(dev-mode_config.mutex);
+}
+
 /*
  * According to DP spec
  * 5.1.2:
@@ -4044,6 +4066,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
return;
}
 
+   intel_flush_edp_cache_work(intel_dp);
+
/* Now read the DPCD to see if it's actually running */
if (!intel_dp_get_dpcd(intel_dp)) {
return;
@@ -4079,6 +4103,8 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
uint8_t *dpcd = intel_dp-dpcd;
uint8_t type;
 
+   intel_flush_edp_cache_work(intel_dp);
+
if (!intel_dp_get_dpcd(intel_dp))
return connector_status_disconnected;
 
@@ -4215,13 +4241,23 @@ g4x_dp_detect(struct intel_dp *intel_dp)
return intel_dp_detect_dpcd(intel_dp);
 }
 
+static bool intel_connector_has_edid(struct intel_connector *intel_connector)
+{
+   struct intel_dp *intel_dp = intel_attached_dp(intel_connector-base);
+   struct drm_device *dev = intel_dp_to_dev(intel_dp);
+
+   intel_flush_edp_cache_work(intel_dp);
+
+   return intel_connector-edid != NULL;
+}
+
 static struct edid *
 intel_dp_get_edid(struct intel_dp *intel_dp)
 {
struct intel_connector *intel_connector = intel_dp-attached_connector;
 
/* use cached edid if we have one */
-   if (intel_connector-edid) {
+   if (intel_connector_has_edid(intel_connector)) {
/* invalid edid */
if (IS_ERR(intel_connector-edid))
return NULL;
@@ -4516,6 +4552,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
intel_dp_mst_encoder_cleanup(intel_dig_port);
if (is_edp(intel_dp)) {
cancel_delayed_work_sync(intel_dp-panel_vdd_work);
+   cancel_work_sync(intel_dp-edp_cache_work);
/*
 * vdd might still be enabled do to the delayed vdd off.
 * Make sure vdd is actually turned off here.
@@ -5316,9 +5353,11 @@ intel_dp_drrs_init(struct intel_connector 
*intel_connector,
return downclock_mode;
 }
 
-static bool intel_edp_init_connector(struct intel_dp *intel_dp,
-struct intel_connector *intel_connector)
+static void intel_edp_cache_work(struct work_struct *work)
 {
+   struct intel_dp *intel_dp = container_of(work, struct intel_dp,
+edp_cache_work);
+   struct intel_connector *intel_connector = intel_dp-attached_connector;
struct drm_connector *connector = intel_connector-base;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *intel_encoder = intel_dig_port-base;
@@ -5329,12 +5368,10 @@ static bool intel_edp_init_connector(struct intel_dp 
*intel_dp,
bool has_dpcd;
struct drm_display_mode *scan;
struct edid *edid;
-   enum pipe pipe = INVALID_PIPE;
 
dev_priv-drrs.type = DRRS_NOT_SUPPORTED;
 
-   if (!is_edp(intel_dp))
-   return true;
+   mutex_lock(dev-mode_config.mutex);
 
pps_lock(intel_dp);
intel_edp_panel_vdd_sanitize(intel_dp);
@@ -5348,10 +5385,13 @@ static bool intel_edp_init_connector(struct intel_dp 
*intel_dp,
dev_priv-no_aux_handshake =
intel_dp-dpcd[DP_MAX_DOWNSPREAD] 
DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
+   intel_dp-dpcd_valid = true;
} else {
-   /* if this fails, presume the device