[PATCH v5 11/20] drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus

Damon Ding posted 20 patches 11 months, 2 weeks ago
There is a newer version of this series
[PATCH v5 11/20] drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus
Posted by Damon Ding 11 months, 2 weeks ago
The main modification is moving the DP AUX initialization from function
analogix_dp_bind() to analogix_dp_probe(). In order to get the EDID of
eDP panel during probing, it is also needed to advance PM operaions to
ensure that eDP controller and phy are prepared for AUX transmission.

Signed-off-by: Damon Ding <damon.ding@rock-chips.com>

---

Changes in v4:
- Use done_probing() to call drm_of_find_panel_or_bridge() and
  component_add() when getting panel from the DP AUX bus

Changes in v5:
- Advance PM operations to make eDP AUX work well
---
 .../drm/bridge/analogix/analogix_dp_core.c    | 62 ++++++++++---------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 8251adfce2f9..78e78fb474d3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1548,6 +1548,18 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
 	return ret;
 }
 
+static void analogix_dp_runtime_disable(void *data)
+{
+	struct analogix_dp_device *dp = (struct analogix_dp_device *)data;
+
+	if (IS_ENABLED(CONFIG_PM)) {
+		pm_runtime_dont_use_autosuspend(dp->dev);
+		pm_runtime_disable(dp->dev);
+	} else {
+		analogix_dp_suspend(dp);
+	}
+}
+
 struct analogix_dp_device *
 analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
 {
@@ -1658,8 +1670,29 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
 	}
 	disable_irq(dp->irq);
 
+	dp->aux.name = "DP-AUX";
+	dp->aux.transfer = analogix_dpaux_transfer;
+	dp->aux.dev = dp->dev;
+	drm_dp_aux_init(&dp->aux);
+
+	if (IS_ENABLED(CONFIG_PM)) {
+		pm_runtime_use_autosuspend(dp->dev);
+		pm_runtime_set_autosuspend_delay(dp->dev, 100);
+		pm_runtime_enable(dp->dev);
+	} else {
+		ret = analogix_dp_resume(dp);
+		if (ret)
+			goto err_disable_clk;
+	}
+
+	ret = devm_add_action_or_reset(dev, analogix_dp_runtime_disable, dp);
+	if (ret)
+		goto err_disable_pm_runtime;
+
 	return dp;
 
+err_disable_pm_runtime:
+	analogix_dp_runtime_disable((void *)dp);
 err_disable_clk:
 	clk_disable_unprepare(dp->clock);
 	return ERR_PTR(ret);
@@ -1708,25 +1741,12 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
 	dp->drm_dev = drm_dev;
 	dp->encoder = dp->plat_data->encoder;
 
-	if (IS_ENABLED(CONFIG_PM)) {
-		pm_runtime_use_autosuspend(dp->dev);
-		pm_runtime_set_autosuspend_delay(dp->dev, 100);
-		pm_runtime_enable(dp->dev);
-	} else {
-		ret = analogix_dp_resume(dp);
-		if (ret)
-			return ret;
-	}
-
-	dp->aux.name = "DP-AUX";
-	dp->aux.transfer = analogix_dpaux_transfer;
-	dp->aux.dev = dp->dev;
 	dp->aux.drm_dev = drm_dev;
 
 	ret = drm_dp_aux_register(&dp->aux);
 	if (ret) {
 		DRM_ERROR("failed to register AUX (%d)\n", ret);
-		goto err_disable_pm_runtime;
+		return ret;
 	}
 
 	ret = analogix_dp_create_bridge(drm_dev, dp);
@@ -1739,13 +1759,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
 
 err_unregister_aux:
 	drm_dp_aux_unregister(&dp->aux);
-err_disable_pm_runtime:
-	if (IS_ENABLED(CONFIG_PM)) {
-		pm_runtime_dont_use_autosuspend(dp->dev);
-		pm_runtime_disable(dp->dev);
-	} else {
-		analogix_dp_suspend(dp);
-	}
 
 	return ret;
 }
@@ -1762,13 +1775,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
 	}
 
 	drm_dp_aux_unregister(&dp->aux);
-
-	if (IS_ENABLED(CONFIG_PM)) {
-		pm_runtime_dont_use_autosuspend(dp->dev);
-		pm_runtime_disable(dp->dev);
-	} else {
-		analogix_dp_suspend(dp);
-	}
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
 
-- 
2.34.1
Re: [PATCH v5 11/20] drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus
Posted by Dmitry Baryshkov 11 months, 2 weeks ago
On Thu, Jan 09, 2025 at 11:27:16AM +0800, Damon Ding wrote:
> The main modification is moving the DP AUX initialization from function
> analogix_dp_bind() to analogix_dp_probe(). In order to get the EDID of
> eDP panel during probing, it is also needed to advance PM operaions to
> ensure that eDP controller and phy are prepared for AUX transmission.
> 
> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
> 
> ---
> 
> Changes in v4:
> - Use done_probing() to call drm_of_find_panel_or_bridge() and
>   component_add() when getting panel from the DP AUX bus
> 
> Changes in v5:
> - Advance PM operations to make eDP AUX work well
> ---
>  .../drm/bridge/analogix/analogix_dp_core.c    | 62 ++++++++++---------
>  1 file changed, 34 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 8251adfce2f9..78e78fb474d3 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -1548,6 +1548,18 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
>  	return ret;
>  }
>  
> +static void analogix_dp_runtime_disable(void *data)
> +{
> +	struct analogix_dp_device *dp = (struct analogix_dp_device *)data;
> +
> +	if (IS_ENABLED(CONFIG_PM)) {
> +		pm_runtime_dont_use_autosuspend(dp->dev);
> +		pm_runtime_disable(dp->dev);
> +	} else {
> +		analogix_dp_suspend(dp);
> +	}
> +}
> +
>  struct analogix_dp_device *
>  analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
>  {
> @@ -1658,8 +1670,29 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
>  	}
>  	disable_irq(dp->irq);
>  
> +	dp->aux.name = "DP-AUX";
> +	dp->aux.transfer = analogix_dpaux_transfer;
> +	dp->aux.dev = dp->dev;
> +	drm_dp_aux_init(&dp->aux);
> +
> +	if (IS_ENABLED(CONFIG_PM)) {
> +		pm_runtime_use_autosuspend(dp->dev);
> +		pm_runtime_set_autosuspend_delay(dp->dev, 100);
> +		pm_runtime_enable(dp->dev);
> +	} else {
> +		ret = analogix_dp_resume(dp);
> +		if (ret)
> +			goto err_disable_clk;
> +	}
> +
> +	ret = devm_add_action_or_reset(dev, analogix_dp_runtime_disable, dp);

This looks like a local version of devm_pm_runtime_enable()

> +	if (ret)
> +		goto err_disable_pm_runtime;
> +
>  	return dp;
>  
> +err_disable_pm_runtime:
> +	analogix_dp_runtime_disable((void *)dp);
>  err_disable_clk:
>  	clk_disable_unprepare(dp->clock);
>  	return ERR_PTR(ret);
> @@ -1708,25 +1741,12 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
>  	dp->drm_dev = drm_dev;
>  	dp->encoder = dp->plat_data->encoder;
>  
> -	if (IS_ENABLED(CONFIG_PM)) {
> -		pm_runtime_use_autosuspend(dp->dev);
> -		pm_runtime_set_autosuspend_delay(dp->dev, 100);
> -		pm_runtime_enable(dp->dev);
> -	} else {
> -		ret = analogix_dp_resume(dp);
> -		if (ret)
> -			return ret;
> -	}
> -
> -	dp->aux.name = "DP-AUX";
> -	dp->aux.transfer = analogix_dpaux_transfer;
> -	dp->aux.dev = dp->dev;
>  	dp->aux.drm_dev = drm_dev;
>  
>  	ret = drm_dp_aux_register(&dp->aux);
>  	if (ret) {
>  		DRM_ERROR("failed to register AUX (%d)\n", ret);
> -		goto err_disable_pm_runtime;
> +		return ret;
>  	}
>  
>  	ret = analogix_dp_create_bridge(drm_dev, dp);
> @@ -1739,13 +1759,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
>  
>  err_unregister_aux:
>  	drm_dp_aux_unregister(&dp->aux);
> -err_disable_pm_runtime:
> -	if (IS_ENABLED(CONFIG_PM)) {
> -		pm_runtime_dont_use_autosuspend(dp->dev);
> -		pm_runtime_disable(dp->dev);
> -	} else {
> -		analogix_dp_suspend(dp);
> -	}
>  
>  	return ret;
>  }
> @@ -1762,13 +1775,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
>  	}
>  
>  	drm_dp_aux_unregister(&dp->aux);
> -
> -	if (IS_ENABLED(CONFIG_PM)) {
> -		pm_runtime_dont_use_autosuspend(dp->dev);
> -		pm_runtime_disable(dp->dev);
> -	} else {
> -		analogix_dp_suspend(dp);
> -	}
>  }
>  EXPORT_SYMBOL_GPL(analogix_dp_unbind);
>  
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry
Re: [PATCH v5 11/20] drm/bridge: analogix_dp: Add support to get panel from the DP AUX bus
Posted by Damon Ding 11 months ago
Hi Dmitry,

On 2025/1/9 20:45, Dmitry Baryshkov wrote:
> On Thu, Jan 09, 2025 at 11:27:16AM +0800, Damon Ding wrote:
>> The main modification is moving the DP AUX initialization from function
>> analogix_dp_bind() to analogix_dp_probe(). In order to get the EDID of
>> eDP panel during probing, it is also needed to advance PM operaions to
>> ensure that eDP controller and phy are prepared for AUX transmission.
>>
>> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>>
>> ---
>>
>> Changes in v4:
>> - Use done_probing() to call drm_of_find_panel_or_bridge() and
>>    component_add() when getting panel from the DP AUX bus
>>
>> Changes in v5:
>> - Advance PM operations to make eDP AUX work well
>> ---
>>   .../drm/bridge/analogix/analogix_dp_core.c    | 62 ++++++++++---------
>>   1 file changed, 34 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> index 8251adfce2f9..78e78fb474d3 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> @@ -1548,6 +1548,18 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
>>   	return ret;
>>   }
>>   
>> +static void analogix_dp_runtime_disable(void *data)
>> +{
>> +	struct analogix_dp_device *dp = (struct analogix_dp_device *)data;
>> +
>> +	if (IS_ENABLED(CONFIG_PM)) {
>> +		pm_runtime_dont_use_autosuspend(dp->dev);
>> +		pm_runtime_disable(dp->dev);
>> +	} else {
>> +		analogix_dp_suspend(dp);
>> +	}
>> +}
>> +
>>   struct analogix_dp_device *
>>   analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
>>   {
>> @@ -1658,8 +1670,29 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
>>   	}
>>   	disable_irq(dp->irq);
>>   
>> +	dp->aux.name = "DP-AUX";
>> +	dp->aux.transfer = analogix_dpaux_transfer;
>> +	dp->aux.dev = dp->dev;
>> +	drm_dp_aux_init(&dp->aux);
>> +
>> +	if (IS_ENABLED(CONFIG_PM)) {
>> +		pm_runtime_use_autosuspend(dp->dev);
>> +		pm_runtime_set_autosuspend_delay(dp->dev, 100);
>> +		pm_runtime_enable(dp->dev);
>> +	} else {
>> +		ret = analogix_dp_resume(dp);
>> +		if (ret)
>> +			goto err_disable_clk;
>> +	}
>> +
>> +	ret = devm_add_action_or_reset(dev, analogix_dp_runtime_disable, dp);
> 
> This looks like a local version of devm_pm_runtime_enable()
> 

Indeed, it is better to use devm_pm_runtime_enable() instead.

>> +	if (ret)
>> +		goto err_disable_pm_runtime;
>> +
>>   	return dp;
>>   
>> +err_disable_pm_runtime:
>> +	analogix_dp_runtime_disable((void *)dp);
>>   err_disable_clk:
>>   	clk_disable_unprepare(dp->clock);
>>   	return ERR_PTR(ret);
>> @@ -1708,25 +1741,12 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
>>   	dp->drm_dev = drm_dev;
>>   	dp->encoder = dp->plat_data->encoder;
>>   
>> -	if (IS_ENABLED(CONFIG_PM)) {
>> -		pm_runtime_use_autosuspend(dp->dev);
>> -		pm_runtime_set_autosuspend_delay(dp->dev, 100);
>> -		pm_runtime_enable(dp->dev);
>> -	} else {
>> -		ret = analogix_dp_resume(dp);
>> -		if (ret)
>> -			return ret;
>> -	}
>> -
>> -	dp->aux.name = "DP-AUX";
>> -	dp->aux.transfer = analogix_dpaux_transfer;
>> -	dp->aux.dev = dp->dev;
>>   	dp->aux.drm_dev = drm_dev;
>>   
>>   	ret = drm_dp_aux_register(&dp->aux);
>>   	if (ret) {
>>   		DRM_ERROR("failed to register AUX (%d)\n", ret);
>> -		goto err_disable_pm_runtime;
>> +		return ret;
>>   	}
>>   
>>   	ret = analogix_dp_create_bridge(drm_dev, dp);
>> @@ -1739,13 +1759,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
>>   
>>   err_unregister_aux:
>>   	drm_dp_aux_unregister(&dp->aux);
>> -err_disable_pm_runtime:
>> -	if (IS_ENABLED(CONFIG_PM)) {
>> -		pm_runtime_dont_use_autosuspend(dp->dev);
>> -		pm_runtime_disable(dp->dev);
>> -	} else {
>> -		analogix_dp_suspend(dp);
>> -	}
>>   
>>   	return ret;
>>   }
>> @@ -1762,13 +1775,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp)
>>   	}
>>   
>>   	drm_dp_aux_unregister(&dp->aux);
>> -
>> -	if (IS_ENABLED(CONFIG_PM)) {
>> -		pm_runtime_dont_use_autosuspend(dp->dev);
>> -		pm_runtime_disable(dp->dev);
>> -	} else {
>> -		analogix_dp_suspend(dp);
>> -	}
>>   }
>>   EXPORT_SYMBOL_GPL(analogix_dp_unbind);
>>   
>> -- 
>> 2.34.1
>>
> 

Best regards,
Damon