diff mbox series

[19/22] drm/i915/vrr: Allow fixed_rr with pipe joiner

Message ID 20250304081948.3177034-20-ankit.k.nautiyal@intel.com (mailing list archive)
State New
Headers show
Series Use VRR timing generator for fixed refresh rate modes | expand

Commit Message

Ankit Nautiyal March 4, 2025, 8:19 a.m. UTC
VRR with joiner is currently disabled as it still needs some work to
correctly sequence the primary and secondary transcoders. However, we can
still use VRR Timing generator in fixed refresh rate for joiner and since
it just need to program vrr timings once and does not involve changing
timings on the fly. We still need to skip the VRR and LRR for joiner.

To achieve this set vrr.in_range to 0 for joiner case, so that we do not
try VRR and LRR for the joiner case.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 38 +++++++++++++++++++-----
 1 file changed, 31 insertions(+), 7 deletions(-)

Comments

Ville Syrjälä March 4, 2025, 7:07 p.m. UTC | #1
On Tue, Mar 04, 2025 at 01:49:45PM +0530, Ankit Nautiyal wrote:
> VRR with joiner is currently disabled as it still needs some work to
> correctly sequence the primary and secondary transcoders. However, we can
> still use VRR Timing generator in fixed refresh rate for joiner and since
> it just need to program vrr timings once and does not involve changing
> timings on the fly. We still need to skip the VRR and LRR for joiner.
> 
> To achieve this set vrr.in_range to 0 for joiner case, so that we do not
> try VRR and LRR for the joiner case.
> 
> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_vrr.c | 38 +++++++++++++++++++-----
>  1 file changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
> index 0dfe6220ff4a..2b6d022434d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_vrr.c
> +++ b/drivers/gpu/drm/i915/display/intel_vrr.c
> @@ -292,6 +292,9 @@ void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state)
>  	if (!intel_vrr_possible(crtc_state))
>  		return;
>  
> +	if (intel_crtc_is_joiner_secondary(crtc_state))
> +		return;

I don't think this gets called on the secondary crtc anyway.

> +
>  	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
>  		       intel_vrr_fixed_rr_vmin(crtc_state) - 1);
>  	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
> @@ -349,19 +352,23 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
>  	if (!HAS_VRR(display))
>  		return;
>  
> -	/*
> -	 * FIXME all joined pipes share the same transcoder.
> -	 * Need to account for that during VRR toggle/push/etc.
> -	 */
> -	if (crtc_state->joiner_pipes)
> -		return;
> -
>  	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
>  		return;
>  
>  	crtc_state->vrr.in_range =
>  		intel_vrr_is_in_range(connector, drm_mode_vrefresh(adjusted_mode));
>  
> +	/*
> +	 * Allow fixed refresh rate with VRR Timing Generator.
> +	 * For now set the vrr.in_range to 0, to allow fixed_rr but skip actual
> +	 * VRR and LRR.
> +	 * #TODO For actual VRR with joiner, we need to figure out how to
> +	 * correctly sequence transcoder level stuff vs. pipe level stuff
> +	 * in the commit.
> +	 */
> +	if (crtc_state->joiner_pipes)
> +		crtc_state->vrr.in_range = 0;
> +
>  	vmin = intel_vrr_compute_vmin(crtc_state);
>  
>  	if (crtc_state->vrr.in_range) {
> @@ -448,6 +455,8 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
>  	struct intel_display *display = to_intel_display(crtc_state);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  
> +	if (intel_crtc_is_joiner_secondary(crtc_state))
> +		return;

Also shouldn't get called on the secondary.

>  	/*
>  	 * This bit seems to have two meanings depending on the platform:
>  	 * TGL: generate VRR "safe window" for DSB vblank waits
> @@ -486,6 +495,9 @@ void intel_vrr_send_push(struct intel_dsb *dsb,
>  	if (!crtc_state->vrr.enable)
>  		return;
>  
> +	if (intel_crtc_is_joiner_secondary(crtc_state))
> +		return;
> +
>  	if (dsb)
>  		intel_dsb_nonpost_start(dsb);
>  
> @@ -560,6 +572,9 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
>  	if (!crtc_state->vrr.enable)
>  		return;
>  
> +	if (intel_crtc_is_joiner_secondary(crtc_state))
> +		return;
> +
>  	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
>  		       crtc_state->vrr.vmin - 1);
>  	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
> @@ -590,6 +605,9 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
>  	if (!old_crtc_state->vrr.enable)
>  		return;
>  
> +	if (intel_crtc_is_joiner_secondary(old_crtc_state))
> +		return;

All thosea three cases should be impossible on account of
vrr.enable==false.

> +
>  	if (!intel_vrr_always_use_vrr_tg(display)) {
>  		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
>  			       trans_vrr_ctl(old_crtc_state));
> @@ -613,6 +631,9 @@ void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state)
>  	if (!intel_vrr_possible(crtc_state))
>  		return;
>  
> +	if (intel_crtc_is_joiner_secondary(crtc_state))
> +		return;
> +
>  	if (!intel_vrr_always_use_vrr_tg(display)) {
>  		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
>  			       trans_vrr_ctl(crtc_state));
> @@ -637,6 +658,9 @@ void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state)
>  	if (!intel_vrr_possible(crtc_state))
>  		return;
>  
> +	if (intel_crtc_is_joiner_secondary(crtc_state))
> +		return;

And these two again shouldn't be called on the secondary crtc.

So I think you should be able to drop all the
intel_crtc_is_joiner_secondary() checks from this patch.

> +
>  	if (!intel_vrr_always_use_vrr_tg(display)) {
>  		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
>  			       trans_vrr_ctl(crtc_state));
> -- 
> 2.45.2
Ankit Nautiyal March 5, 2025, 9:35 a.m. UTC | #2
On 3/5/2025 12:37 AM, Ville Syrjälä wrote:
> On Tue, Mar 04, 2025 at 01:49:45PM +0530, Ankit Nautiyal wrote:
>> VRR with joiner is currently disabled as it still needs some work to
>> correctly sequence the primary and secondary transcoders. However, we can
>> still use VRR Timing generator in fixed refresh rate for joiner and since
>> it just need to program vrr timings once and does not involve changing
>> timings on the fly. We still need to skip the VRR and LRR for joiner.
>>
>> To achieve this set vrr.in_range to 0 for joiner case, so that we do not
>> try VRR and LRR for the joiner case.
>>
>> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/display/intel_vrr.c | 38 +++++++++++++++++++-----
>>   1 file changed, 31 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
>> index 0dfe6220ff4a..2b6d022434d2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_vrr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_vrr.c
>> @@ -292,6 +292,9 @@ void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state)
>>   	if (!intel_vrr_possible(crtc_state))
>>   		return;
>>   
>> +	if (intel_crtc_is_joiner_secondary(crtc_state))
>> +		return;
> I don't think this gets called on the secondary crtc anyway.
>
>> +
>>   	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
>>   		       intel_vrr_fixed_rr_vmin(crtc_state) - 1);
>>   	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
>> @@ -349,19 +352,23 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
>>   	if (!HAS_VRR(display))
>>   		return;
>>   
>> -	/*
>> -	 * FIXME all joined pipes share the same transcoder.
>> -	 * Need to account for that during VRR toggle/push/etc.
>> -	 */
>> -	if (crtc_state->joiner_pipes)
>> -		return;
>> -
>>   	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
>>   		return;
>>   
>>   	crtc_state->vrr.in_range =
>>   		intel_vrr_is_in_range(connector, drm_mode_vrefresh(adjusted_mode));
>>   
>> +	/*
>> +	 * Allow fixed refresh rate with VRR Timing Generator.
>> +	 * For now set the vrr.in_range to 0, to allow fixed_rr but skip actual
>> +	 * VRR and LRR.
>> +	 * #TODO For actual VRR with joiner, we need to figure out how to
>> +	 * correctly sequence transcoder level stuff vs. pipe level stuff
>> +	 * in the commit.
>> +	 */
>> +	if (crtc_state->joiner_pipes)
>> +		crtc_state->vrr.in_range = 0;
>> +
>>   	vmin = intel_vrr_compute_vmin(crtc_state);
>>   
>>   	if (crtc_state->vrr.in_range) {
>> @@ -448,6 +455,8 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
>>   	struct intel_display *display = to_intel_display(crtc_state);
>>   	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>   
>> +	if (intel_crtc_is_joiner_secondary(crtc_state))
>> +		return;
> Also shouldn't get called on the secondary.
>
>>   	/*
>>   	 * This bit seems to have two meanings depending on the platform:
>>   	 * TGL: generate VRR "safe window" for DSB vblank waits
>> @@ -486,6 +495,9 @@ void intel_vrr_send_push(struct intel_dsb *dsb,
>>   	if (!crtc_state->vrr.enable)
>>   		return;
>>   
>> +	if (intel_crtc_is_joiner_secondary(crtc_state))
>> +		return;
>> +
>>   	if (dsb)
>>   		intel_dsb_nonpost_start(dsb);
>>   
>> @@ -560,6 +572,9 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
>>   	if (!crtc_state->vrr.enable)
>>   		return;
>>   
>> +	if (intel_crtc_is_joiner_secondary(crtc_state))
>> +		return;
>> +
>>   	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
>>   		       crtc_state->vrr.vmin - 1);
>>   	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
>> @@ -590,6 +605,9 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
>>   	if (!old_crtc_state->vrr.enable)
>>   		return;
>>   
>> +	if (intel_crtc_is_joiner_secondary(old_crtc_state))
>> +		return;
> All thosea three cases should be impossible on account of
> vrr.enable==false.
>
>> +
>>   	if (!intel_vrr_always_use_vrr_tg(display)) {
>>   		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
>>   			       trans_vrr_ctl(old_crtc_state));
>> @@ -613,6 +631,9 @@ void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state)
>>   	if (!intel_vrr_possible(crtc_state))
>>   		return;
>>   
>> +	if (intel_crtc_is_joiner_secondary(crtc_state))
>> +		return;
>> +
>>   	if (!intel_vrr_always_use_vrr_tg(display)) {
>>   		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
>>   			       trans_vrr_ctl(crtc_state));
>> @@ -637,6 +658,9 @@ void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state)
>>   	if (!intel_vrr_possible(crtc_state))
>>   		return;
>>   
>> +	if (intel_crtc_is_joiner_secondary(crtc_state))
>> +		return;
> And these two again shouldn't be called on the secondary crtc.
>
> So I think you should be able to drop all the
> intel_crtc_is_joiner_secondary() checks from this patch.

Got it. Will drop the secondary check in the next version.


Thanks Ville for the catching the issues, review comments and suggestions.

Will figure out the fix for the warn on and do the suggested changes in 
next version.


Regards,

Ankit


>
>> +
>>   	if (!intel_vrr_always_use_vrr_tg(display)) {
>>   		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
>>   			       trans_vrr_ctl(crtc_state));
>> -- 
>> 2.45.2
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 0dfe6220ff4a..2b6d022434d2 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -292,6 +292,9 @@  void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state)
 	if (!intel_vrr_possible(crtc_state))
 		return;
 
+	if (intel_crtc_is_joiner_secondary(crtc_state))
+		return;
+
 	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
 		       intel_vrr_fixed_rr_vmin(crtc_state) - 1);
 	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
@@ -349,19 +352,23 @@  intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
 	if (!HAS_VRR(display))
 		return;
 
-	/*
-	 * FIXME all joined pipes share the same transcoder.
-	 * Need to account for that during VRR toggle/push/etc.
-	 */
-	if (crtc_state->joiner_pipes)
-		return;
-
 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
 		return;
 
 	crtc_state->vrr.in_range =
 		intel_vrr_is_in_range(connector, drm_mode_vrefresh(adjusted_mode));
 
+	/*
+	 * Allow fixed refresh rate with VRR Timing Generator.
+	 * For now set the vrr.in_range to 0, to allow fixed_rr but skip actual
+	 * VRR and LRR.
+	 * #TODO For actual VRR with joiner, we need to figure out how to
+	 * correctly sequence transcoder level stuff vs. pipe level stuff
+	 * in the commit.
+	 */
+	if (crtc_state->joiner_pipes)
+		crtc_state->vrr.in_range = 0;
+
 	vmin = intel_vrr_compute_vmin(crtc_state);
 
 	if (crtc_state->vrr.in_range) {
@@ -448,6 +455,8 @@  void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
 	struct intel_display *display = to_intel_display(crtc_state);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
+	if (intel_crtc_is_joiner_secondary(crtc_state))
+		return;
 	/*
 	 * This bit seems to have two meanings depending on the platform:
 	 * TGL: generate VRR "safe window" for DSB vblank waits
@@ -486,6 +495,9 @@  void intel_vrr_send_push(struct intel_dsb *dsb,
 	if (!crtc_state->vrr.enable)
 		return;
 
+	if (intel_crtc_is_joiner_secondary(crtc_state))
+		return;
+
 	if (dsb)
 		intel_dsb_nonpost_start(dsb);
 
@@ -560,6 +572,9 @@  void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
 	if (!crtc_state->vrr.enable)
 		return;
 
+	if (intel_crtc_is_joiner_secondary(crtc_state))
+		return;
+
 	intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder),
 		       crtc_state->vrr.vmin - 1);
 	intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder),
@@ -590,6 +605,9 @@  void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
 	if (!old_crtc_state->vrr.enable)
 		return;
 
+	if (intel_crtc_is_joiner_secondary(old_crtc_state))
+		return;
+
 	if (!intel_vrr_always_use_vrr_tg(display)) {
 		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
 			       trans_vrr_ctl(old_crtc_state));
@@ -613,6 +631,9 @@  void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state)
 	if (!intel_vrr_possible(crtc_state))
 		return;
 
+	if (intel_crtc_is_joiner_secondary(crtc_state))
+		return;
+
 	if (!intel_vrr_always_use_vrr_tg(display)) {
 		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
 			       trans_vrr_ctl(crtc_state));
@@ -637,6 +658,9 @@  void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state)
 	if (!intel_vrr_possible(crtc_state))
 		return;
 
+	if (intel_crtc_is_joiner_secondary(crtc_state))
+		return;
+
 	if (!intel_vrr_always_use_vrr_tg(display)) {
 		intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder),
 			       trans_vrr_ctl(crtc_state));