diff mbox

[v5,5/5] drm/i915: Add lspcon resume function

Message ID 1476437067-13237-6-git-send-email-shashank.sharma@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sharma, Shashank Oct. 14, 2016, 9:24 a.m. UTC
As per the software design, we are driving lspcon in
PCON mode. But while resuming from suspend, lspcon can go
in LS mode (which is its default operating mode on power on)

This patch adds a resume function for lspcon, which makes sure
its operating in PCON mode, post resume.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c     |  2 ++
 drivers/gpu/drm/i915/intel_drv.h    |  1 +
 drivers/gpu/drm/i915/intel_lspcon.c | 38 +++++++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

Comments

Imre Deak Oct. 14, 2016, 9:26 a.m. UTC | #1
On pe, 2016-10-14 at 14:54 +0530, Shashank Sharma wrote:
> As per the software design, we are driving lspcon in
> PCON mode. But while resuming from suspend, lspcon can go
> in LS mode (which is its default operating mode on power on)
> 
> This patch adds a resume function for lspcon, which makes sure
> its operating in PCON mode, post resume.
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c     |  2 ++
>  drivers/gpu/drm/i915/intel_drv.h    |  1 +
>  drivers/gpu/drm/i915/intel_lspcon.c | 38 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 41 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index e9b3bfc..d87281d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1574,6 +1574,8 @@ static int i915_drm_resume(struct drm_device *dev)
>  		dev_priv->display.hpd_irq_setup(dev_priv);
>  	spin_unlock_irq(&dev_priv->irq_lock);
>  
> +	lspcon_resume(dev);
> +

This should go to the encoder reset hook.

>  	intel_dp_mst_resume(dev);
>  
>  	intel_display_resume(dev);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 27837b0..e8760a4 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1850,4 +1850,5 @@ void intel_color_load_luts(struct drm_crtc_state *crtc_state);
>  
>  /* intel_lspcon.c */
>  bool lspcon_init(struct intel_digital_port *intel_dig_port);
> +void lspcon_resume(struct drm_device *dev);
>  #endif /* __INTEL_DRV_H__ */
> diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
> index aa74b1f..ba660ecb 100644
> --- a/drivers/gpu/drm/i915/intel_lspcon.c
> +++ b/drivers/gpu/drm/i915/intel_lspcon.c
> @@ -27,6 +27,29 @@
>  #include 
>  #include "intel_drv.h"
>  
> +/*
> + * This function assumes only one LSPCON port on the device,
> + * and returns the first active LSPCON port.
> + */
> +static struct intel_lspcon *find_active_lspcon(struct drm_device *dev)
> +{
> +	struct intel_lspcon *lspcon = NULL;
> +	struct intel_encoder *intel_encoder;
> +
> +	for_each_intel_encoder(dev, intel_encoder) {
> +		struct intel_digital_port *intel_dig_port;
> +
> +		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
> +		lspcon = &intel_dig_port->lspcon;
> +		if (lspcon->active) {
> +			DRM_DEBUG_KMS("LSPCON active : port %c\n",
> +					port_name(intel_dig_port->port));
> +			break;
> +		}
> +	}
> +	return lspcon;
> +}
> +
>  enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
>  {
>  	enum drm_lspcon_mode current_mode = DRM_LSPCON_MODE_INVALID;
> @@ -89,6 +112,21 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
>  	return true;
>  }
>  
> +void lspcon_resume(struct drm_device *dev)
> +{
> +	if (IS_GEN9(dev)) {
> +		struct intel_lspcon *lspcon = find_active_lspcon(dev);
> +
> +		if (lspcon) {
> +			if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON,
> +						true))
> +				DRM_ERROR("LSPCON resume failed\n");
> +			else
> +				DRM_DEBUG_KMS("LSPCON resume success\n");
> +		}
> +	}
> +}

Nitpick: you could reduce indentation above by using early returns.


> +
>  bool lspcon_init(struct intel_digital_port *intel_dig_port)
>  {
>  	struct intel_dp *dp = &intel_dig_port->dp;
Sharma, Shashank Oct. 14, 2016, 12:35 p.m. UTC | #2
Regards

Shashak


On 10/14/2016 2:56 PM, Imre Deak wrote:
> On pe, 2016-10-14 at 14:54 +0530, Shashank Sharma wrote:
>> As per the software design, we are driving lspcon in
>> PCON mode. But while resuming from suspend, lspcon can go
>> in LS mode (which is its default operating mode on power on)
>>
>> This patch adds a resume function for lspcon, which makes sure
>> its operating in PCON mode, post resume.
>>
>> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_drv.c     |  2 ++
>>   drivers/gpu/drm/i915/intel_drv.h    |  1 +
>>   drivers/gpu/drm/i915/intel_lspcon.c | 38 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
>> index e9b3bfc..d87281d 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -1574,6 +1574,8 @@ static int i915_drm_resume(struct drm_device *dev)
>>   		dev_priv->display.hpd_irq_setup(dev_priv);
>>   	spin_unlock_irq(&dev_priv->irq_lock);
>>   
>> +	lspcon_resume(dev);
>> +
> This should go to the encoder reset hook.
Oh, sorry, I forgot about this suggestion.
Will move it.
>>   	intel_dp_mst_resume(dev);
>>   
>>   	intel_display_resume(dev);
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index 27837b0..e8760a4 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -1850,4 +1850,5 @@ void intel_color_load_luts(struct drm_crtc_state *crtc_state);
>>   
>>   /* intel_lspcon.c */
>>   bool lspcon_init(struct intel_digital_port *intel_dig_port);
>> +void lspcon_resume(struct drm_device *dev);
>>   #endif /* __INTEL_DRV_H__ */
>> diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
>> index aa74b1f..ba660ecb 100644
>> --- a/drivers/gpu/drm/i915/intel_lspcon.c
>> +++ b/drivers/gpu/drm/i915/intel_lspcon.c
>> @@ -27,6 +27,29 @@
>>   #include
>>   #include "intel_drv.h"
>>   
>> +/*
>> + * This function assumes only one LSPCON port on the device,
>> + * and returns the first active LSPCON port.
>> + */
>> +static struct intel_lspcon *find_active_lspcon(struct drm_device *dev)
>> +{
>> +	struct intel_lspcon *lspcon = NULL;
>> +	struct intel_encoder *intel_encoder;
>> +
>> +	for_each_intel_encoder(dev, intel_encoder) {
>> +		struct intel_digital_port *intel_dig_port;
>> +
>> +		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
>> +		lspcon = &intel_dig_port->lspcon;
>> +		if (lspcon->active) {
>> +			DRM_DEBUG_KMS("LSPCON active : port %c\n",
>> +					port_name(intel_dig_port->port));
>> +			break;
>> +		}
>> +	}
>> +	return lspcon;
>> +}
>> +
>>   enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
>>   {
>>   	enum drm_lspcon_mode current_mode = DRM_LSPCON_MODE_INVALID;
>> @@ -89,6 +112,21 @@ static bool lspcon_probe(struct intel_lspcon *lspcon)
>>   	return true;
>>   }
>>   
>> +void lspcon_resume(struct drm_device *dev)
>> +{
>> +	if (IS_GEN9(dev)) {
>> +		struct intel_lspcon *lspcon = find_active_lspcon(dev);
>> +
>> +		if (lspcon) {
>> +			if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON,
>> +						true))
>> +				DRM_ERROR("LSPCON resume failed\n");
>> +			else
>> +				DRM_DEBUG_KMS("LSPCON resume success\n");
>> +		}
>> +	}
>> +}
> Nitpick: you could reduce indentation above by using early returns.
Sure.
- Shashank
>
>
>> +
>>   bool lspcon_init(struct intel_digital_port *intel_dig_port)
>>   {
>>   	struct intel_dp *dp = &intel_dig_port->dp;
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e9b3bfc..d87281d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1574,6 +1574,8 @@  static int i915_drm_resume(struct drm_device *dev)
 		dev_priv->display.hpd_irq_setup(dev_priv);
 	spin_unlock_irq(&dev_priv->irq_lock);
 
+	lspcon_resume(dev);
+
 	intel_dp_mst_resume(dev);
 
 	intel_display_resume(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 27837b0..e8760a4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1850,4 +1850,5 @@  void intel_color_load_luts(struct drm_crtc_state *crtc_state);
 
 /* intel_lspcon.c */
 bool lspcon_init(struct intel_digital_port *intel_dig_port);
+void lspcon_resume(struct drm_device *dev);
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
index aa74b1f..ba660ecb 100644
--- a/drivers/gpu/drm/i915/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/intel_lspcon.c
@@ -27,6 +27,29 @@ 
 #include <drm/drm_dp_dual_mode_helper.h>
 #include "intel_drv.h"
 
+/*
+ * This function assumes only one LSPCON port on the device,
+ * and returns the first active LSPCON port.
+ */
+static struct intel_lspcon *find_active_lspcon(struct drm_device *dev)
+{
+	struct intel_lspcon *lspcon = NULL;
+	struct intel_encoder *intel_encoder;
+
+	for_each_intel_encoder(dev, intel_encoder) {
+		struct intel_digital_port *intel_dig_port;
+
+		intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+		lspcon = &intel_dig_port->lspcon;
+		if (lspcon->active) {
+			DRM_DEBUG_KMS("LSPCON active : port %c\n",
+					port_name(intel_dig_port->port));
+			break;
+		}
+	}
+	return lspcon;
+}
+
 enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
 {
 	enum drm_lspcon_mode current_mode = DRM_LSPCON_MODE_INVALID;
@@ -89,6 +112,21 @@  static bool lspcon_probe(struct intel_lspcon *lspcon)
 	return true;
 }
 
+void lspcon_resume(struct drm_device *dev)
+{
+	if (IS_GEN9(dev)) {
+		struct intel_lspcon *lspcon = find_active_lspcon(dev);
+
+		if (lspcon) {
+			if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON,
+						true))
+				DRM_ERROR("LSPCON resume failed\n");
+			else
+				DRM_DEBUG_KMS("LSPCON resume success\n");
+		}
+	}
+}
+
 bool lspcon_init(struct intel_digital_port *intel_dig_port)
 {
 	struct intel_dp *dp = &intel_dig_port->dp;