diff mbox series

[v2,7/8] drm/msm/dpu: support setting the TE source

Message ID 20240613-dpu-handle-te-signal-v2-7-67a0116b5366@linaro.org (mailing list archive)
State New, archived
Headers show
Series drm/msm/dpu: handle non-default TE source pins | expand

Commit Message

Dmitry Baryshkov June 13, 2024, 5:05 p.m. UTC
Make the DPU driver use the TE source specified in the DT. If none is
specified, the driver defaults to the first GPIO (mdp_vsync0).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 44 ++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

Comments

Marijn Suijten June 13, 2024, 6:14 p.m. UTC | #1
On 2024-06-13 20:05:10, Dmitry Baryshkov wrote:
> Make the DPU driver use the TE source specified in the DT. If none is
> specified, the driver defaults to the first GPIO (mdp_vsync0).

mdp_vsync_p?

> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 44 ++++++++++++++++++++++++++++++++-
>  1 file changed, 43 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index e9991f3756d4..6fcb3cf4a382 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -505,6 +505,44 @@ static void dpu_kms_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
>  		dpu_kms_wait_for_commit_done(kms, crtc);
>  }
>  
> +static const char *dpu_vsync_sources[] = {
> +	[DPU_VSYNC_SOURCE_GPIO_0] = "mdp_vsync_p",
> +	[DPU_VSYNC_SOURCE_GPIO_1] = "mdp_vsync_s",
> +	[DPU_VSYNC_SOURCE_GPIO_2] = "mdp_vsync_e",
> +	[DPU_VSYNC_SOURCE_INTF_0] = "mdp_intf0",
> +	[DPU_VSYNC_SOURCE_INTF_1] = "mdp_intf1",
> +	[DPU_VSYNC_SOURCE_INTF_2] = "mdp_intf2",
> +	[DPU_VSYNC_SOURCE_INTF_3] = "mdp_intf3",
> +	[DPU_VSYNC_SOURCE_WD_TIMER_0] = "timer0",
> +	[DPU_VSYNC_SOURCE_WD_TIMER_1] = "timer1",
> +	[DPU_VSYNC_SOURCE_WD_TIMER_2] = "timer2",
> +	[DPU_VSYNC_SOURCE_WD_TIMER_3] = "timer3",
> +	[DPU_VSYNC_SOURCE_WD_TIMER_4] = "timer4",
> +};
> +
> +static int dpu_kms_dsi_set_te_source(struct msm_display_info *info,
> +				     struct msm_dsi *dsi)
> +{
> +	const char *te_source = msm_dsi_get_te_source(dsi);

Just checking: if the TE source is different and one has dual-DSI, it must be
set on both controllers?

> +	int i;
> +
> +	if (!te_source) {
> +		info->vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
> +		return 0;
> +	}
> +
> +	/* we can not use match_string since dpu_vsync_sources is a sparse array */

Instead of having gaps in the array, you could also store both the vsync_source
and name as the array elements?

> +	for (i = 0; i < ARRAY_SIZE(dpu_vsync_sources); i++) {
> +		if (dpu_vsync_sources[i] &&
> +		    !strcmp(dpu_vsync_sources[i], te_source)) {
> +			info->vsync_source = i;
> +			return 0;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  static int _dpu_kms_initialize_dsi(struct drm_device *dev,
>  				    struct msm_drm_private *priv,
>  				    struct dpu_kms *dpu_kms)
> @@ -543,7 +581,11 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev,
>  
>  		info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
>  
> -		info.vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
> +		rc = dpu_kms_dsi_set_te_source(&info, priv->dsi[i]);
> +		if (rc) {
> +			DPU_ERROR("failed to identify TE source for dsi display\n");
> +			return rc;
> +		}
>  
>  		encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI, &info);
>  		if (IS_ERR(encoder)) {
> 
> -- 
> 2.39.2
>
Abhinav Kumar June 19, 2024, 6:59 p.m. UTC | #2
On 6/13/2024 10:05 AM, Dmitry Baryshkov wrote:
> Make the DPU driver use the TE source specified in the DT. If none is
> specified, the driver defaults to the first GPIO (mdp_vsync0).
> 

as marijn noted,

mdp_vsync0 ---> mdp_vsyncp

> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

With that addressed,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Abhinav Kumar June 19, 2024, 7:02 p.m. UTC | #3
On 6/13/2024 11:14 AM, Marijn Suijten wrote:
> On 2024-06-13 20:05:10, Dmitry Baryshkov wrote:
>> Make the DPU driver use the TE source specified in the DT. If none is
>> specified, the driver defaults to the first GPIO (mdp_vsync0).
> 
> mdp_vsync_p?
> 
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 44 ++++++++++++++++++++++++++++++++-
>>   1 file changed, 43 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> index e9991f3756d4..6fcb3cf4a382 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> @@ -505,6 +505,44 @@ static void dpu_kms_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
>>   		dpu_kms_wait_for_commit_done(kms, crtc);
>>   }
>>   
>> +static const char *dpu_vsync_sources[] = {
>> +	[DPU_VSYNC_SOURCE_GPIO_0] = "mdp_vsync_p",
>> +	[DPU_VSYNC_SOURCE_GPIO_1] = "mdp_vsync_s",
>> +	[DPU_VSYNC_SOURCE_GPIO_2] = "mdp_vsync_e",
>> +	[DPU_VSYNC_SOURCE_INTF_0] = "mdp_intf0",
>> +	[DPU_VSYNC_SOURCE_INTF_1] = "mdp_intf1",
>> +	[DPU_VSYNC_SOURCE_INTF_2] = "mdp_intf2",
>> +	[DPU_VSYNC_SOURCE_INTF_3] = "mdp_intf3",
>> +	[DPU_VSYNC_SOURCE_WD_TIMER_0] = "timer0",
>> +	[DPU_VSYNC_SOURCE_WD_TIMER_1] = "timer1",
>> +	[DPU_VSYNC_SOURCE_WD_TIMER_2] = "timer2",
>> +	[DPU_VSYNC_SOURCE_WD_TIMER_3] = "timer3",
>> +	[DPU_VSYNC_SOURCE_WD_TIMER_4] = "timer4",
>> +};
>> +
>> +static int dpu_kms_dsi_set_te_source(struct msm_display_info *info,
>> +				     struct msm_dsi *dsi)
>> +{
>> +	const char *te_source = msm_dsi_get_te_source(dsi);
> 
> Just checking: if the TE source is different and one has dual-DSI, it must be
> set on both controllers?
> 

If we use dual-dsi (in NON-bonded mode), then yes we will have two TE 
sources - one for each controller.

>> +	int i;
>> +
>> +	if (!te_source) {
>> +		info->vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
>> +		return 0;
>> +	}
>> +
>> +	/* we can not use match_string since dpu_vsync_sources is a sparse array */
> 
> Instead of having gaps in the array, you could also store both the vsync_source
> and name as the array elements?
> 

Yes, there is a gap because the DPU_VSYNC_* macros have a gap.

Can you pls explain your suggestion to remove the gap a little more?
I didnt follow this part very well.

>> +	for (i = 0; i < ARRAY_SIZE(dpu_vsync_sources); i++) {
>> +		if (dpu_vsync_sources[i] &&
>> +		    !strcmp(dpu_vsync_sources[i], te_source)) {
>> +			info->vsync_source = i;
>> +			return 0;
>> +		}
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>> +
>>   static int _dpu_kms_initialize_dsi(struct drm_device *dev,
>>   				    struct msm_drm_private *priv,
>>   				    struct dpu_kms *dpu_kms)
>> @@ -543,7 +581,11 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev,
>>   
>>   		info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
>>   
>> -		info.vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
>> +		rc = dpu_kms_dsi_set_te_source(&info, priv->dsi[i]);
>> +		if (rc) {
>> +			DPU_ERROR("failed to identify TE source for dsi display\n");
>> +			return rc;
>> +		}
>>   
>>   		encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI, &info);
>>   		if (IS_ERR(encoder)) {
>>
>> -- 
>> 2.39.2
>>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index e9991f3756d4..6fcb3cf4a382 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -505,6 +505,44 @@  static void dpu_kms_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
 		dpu_kms_wait_for_commit_done(kms, crtc);
 }
 
+static const char *dpu_vsync_sources[] = {
+	[DPU_VSYNC_SOURCE_GPIO_0] = "mdp_vsync_p",
+	[DPU_VSYNC_SOURCE_GPIO_1] = "mdp_vsync_s",
+	[DPU_VSYNC_SOURCE_GPIO_2] = "mdp_vsync_e",
+	[DPU_VSYNC_SOURCE_INTF_0] = "mdp_intf0",
+	[DPU_VSYNC_SOURCE_INTF_1] = "mdp_intf1",
+	[DPU_VSYNC_SOURCE_INTF_2] = "mdp_intf2",
+	[DPU_VSYNC_SOURCE_INTF_3] = "mdp_intf3",
+	[DPU_VSYNC_SOURCE_WD_TIMER_0] = "timer0",
+	[DPU_VSYNC_SOURCE_WD_TIMER_1] = "timer1",
+	[DPU_VSYNC_SOURCE_WD_TIMER_2] = "timer2",
+	[DPU_VSYNC_SOURCE_WD_TIMER_3] = "timer3",
+	[DPU_VSYNC_SOURCE_WD_TIMER_4] = "timer4",
+};
+
+static int dpu_kms_dsi_set_te_source(struct msm_display_info *info,
+				     struct msm_dsi *dsi)
+{
+	const char *te_source = msm_dsi_get_te_source(dsi);
+	int i;
+
+	if (!te_source) {
+		info->vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
+		return 0;
+	}
+
+	/* we can not use match_string since dpu_vsync_sources is a sparse array */
+	for (i = 0; i < ARRAY_SIZE(dpu_vsync_sources); i++) {
+		if (dpu_vsync_sources[i] &&
+		    !strcmp(dpu_vsync_sources[i], te_source)) {
+			info->vsync_source = i;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
 static int _dpu_kms_initialize_dsi(struct drm_device *dev,
 				    struct msm_drm_private *priv,
 				    struct dpu_kms *dpu_kms)
@@ -543,7 +581,11 @@  static int _dpu_kms_initialize_dsi(struct drm_device *dev,
 
 		info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
 
-		info.vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
+		rc = dpu_kms_dsi_set_te_source(&info, priv->dsi[i]);
+		if (rc) {
+			DPU_ERROR("failed to identify TE source for dsi display\n");
+			return rc;
+		}
 
 		encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI, &info);
 		if (IS_ERR(encoder)) {