On 2018-12-05 9:30 a.m., Li, Sun peng (Leo) wrote:
> 
> 
> On 2018-12-05 8:40 a.m., Nicholas Kazlauskas wrote:
>> [Why]
>> When application flip-rate is below the minimum vrr refresh rate.
>>
>> Variable refresh rate monitors extend the front porch duration until
>> flip or timeout occurs. For cases where the application flip-rate is
> 
> Did something get cut off here? With that fixed,
> Acked-by: Leo Li <[email protected]>

Those top two paragraphs were supposed to be cut, I think I formatted 
the wrong patch for that.

The code itself is the correct version, however. Thanks.

Nicholas Kazlauskas

> 
>>
>> When the flip-rate is below the minimum supported variable refresh rate
>> range for the monitor the front porch wait will timeout and be
>> frequently misaligned resulting in stuttering and/or flickering.
>>
>> The FreeSync module can still maintain a smooth and flicker free
>> image when the monitor has a refresh rate range such that the maximum
>> refresh > 2 * minimum refresh by utilizing low framerate compensation,
>> "below the range".
>>
>> [How]
>> Hook up the pre-flip and post-flip handlers from the FreeSync module.
>> These adjust the minimum/maximum vrr range to duplicate frames
>> when appropriate by tracking flip timestamps.
>>
>> Cc: Leo Li <[email protected]>
>> Cc: Harry Wentland <[email protected]>
>> Signed-off-by: Nicholas Kazlauskas <[email protected]>
>> ---
>>    .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 79 ++++++++++++++-----
>>    .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
>>    2 files changed, 62 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index 23d61570df17..e2de064426fc 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -328,12 +328,29 @@ static void dm_crtc_high_irq(void *interrupt_params)
>>      struct common_irq_params *irq_params = interrupt_params;
>>      struct amdgpu_device *adev = irq_params->adev;
>>      struct amdgpu_crtc *acrtc;
>> +    struct dm_crtc_state *acrtc_state;
>>    
>>      acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - 
>> IRQ_TYPE_VBLANK);
>>    
>>      if (acrtc) {
>>              drm_crtc_handle_vblank(&acrtc->base);
>>              amdgpu_dm_crtc_handle_crc_irq(&acrtc->base);
>> +
>> +            acrtc_state = to_dm_crtc_state(acrtc->base.state);
>> +
>> +            if (acrtc_state->stream &&
>> +                acrtc_state->vrr_params.supported &&
>> +                acrtc_state->freesync_config.state == 
>> VRR_STATE_ACTIVE_VARIABLE) {
>> +                    mod_freesync_handle_v_update(
>> +                            adev->dm.freesync_module,
>> +                            acrtc_state->stream,
>> +                            &acrtc_state->vrr_params);
>> +
>> +                    dc_stream_adjust_vmin_vmax(
>> +                            adev->dm.dc,
>> +                            acrtc_state->stream,
>> +                            &acrtc_state->vrr_params.adjust);
>> +            }
>>      }
>>    }
>>    
>> @@ -3001,7 +3018,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
>>              dc_stream_retain(state->stream);
>>      }
>>    
>> -    state->adjust = cur->adjust;
>> +    state->vrr_params = cur->vrr_params;
>>      state->vrr_infopacket = cur->vrr_infopacket;
>>      state->abm_level = cur->abm_level;
>>      state->vrr_supported = cur->vrr_supported;
>> @@ -4396,9 +4413,11 @@ struct dc_stream_status *dc_state_get_stream_status(
>>    static void update_freesync_state_on_stream(
>>      struct amdgpu_display_manager *dm,
>>      struct dm_crtc_state *new_crtc_state,
>> -    struct dc_stream_state *new_stream)
>> +    struct dc_stream_state *new_stream,
>> +    struct dc_plane_state *surface,
>> +    u32 flip_timestamp_in_us)
>>    {
>> -    struct mod_vrr_params vrr = {0};
>> +    struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
>>      struct dc_info_packet vrr_infopacket = {0};
>>      struct mod_freesync_config config = new_crtc_state->freesync_config;
>>    
>> @@ -4425,43 +4444,52 @@ static void update_freesync_state_on_stream(
>>    
>>      mod_freesync_build_vrr_params(dm->freesync_module,
>>                                    new_stream,
>> -                                  &config, &vrr);
>> +                                  &config, &vrr_params);
>> +
>> +    if (surface) {
>> +            mod_freesync_handle_preflip(
>> +                    dm->freesync_module,
>> +                    surface,
>> +                    new_stream,
>> +                    flip_timestamp_in_us,
>> +                    &vrr_params);
>> +    }
>>    
>>      mod_freesync_build_vrr_infopacket(
>>              dm->freesync_module,
>>              new_stream,
>> -            &vrr,
>> +            &vrr_params,
>>              PACKET_TYPE_VRR,
>>              TRANSFER_FUNC_UNKNOWN,
>>              &vrr_infopacket);
>>    
>>      new_crtc_state->freesync_timing_changed =
>> -            (memcmp(&new_crtc_state->adjust,
>> -                    &vrr.adjust,
>> -                    sizeof(vrr.adjust)) != 0);
>> +            (memcmp(&new_crtc_state->vrr_params.adjust,
>> +                    &vrr_params.adjust,
>> +                    sizeof(vrr_params.adjust)) != 0);
>>    
>>      new_crtc_state->freesync_vrr_info_changed =
>>              (memcmp(&new_crtc_state->vrr_infopacket,
>>                      &vrr_infopacket,
>>                      sizeof(vrr_infopacket)) != 0);
>>    
>> -    new_crtc_state->adjust = vrr.adjust;
>> +    new_crtc_state->vrr_params = vrr_params;
>>      new_crtc_state->vrr_infopacket = vrr_infopacket;
>>    
>> -    new_stream->adjust = new_crtc_state->adjust;
>> +    new_stream->adjust = new_crtc_state->vrr_params.adjust;
>>      new_stream->vrr_infopacket = vrr_infopacket;
>>    
>>      if (new_crtc_state->freesync_vrr_info_changed)
>>              DRM_DEBUG_KMS("VRR packet update: crtc=%u enabled=%d state=%d",
>>                            new_crtc_state->base.crtc->base.id,
>>                            (int)new_crtc_state->base.vrr_enabled,
>> -                          (int)vrr.state);
>> +                          (int)vrr_params.state);
>>    
>>      if (new_crtc_state->freesync_timing_changed)
>>              DRM_DEBUG_KMS("VRR timing update: crtc=%u min=%u max=%u\n",
>>                            new_crtc_state->base.crtc->base.id,
>> -                          vrr.adjust.v_total_min,
>> -                          vrr.adjust.v_total_max);
>> +                              vrr_params.adjust.v_total_min,
>> +                              vrr_params.adjust.v_total_max);
>>    }
>>    
>>    /*
>> @@ -4488,6 +4516,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
>>      struct dc_stream_update stream_update = {0};
>>      struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
>>      struct dc_stream_status *stream_status;
>> +    struct dc_plane_state *surface;
>>    
>>    
>>      /* Prepare wait for target vblank early - before the fence-waits */
>> @@ -4536,6 +4565,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
>>      addr.address.grph.addr.low_part = lower_32_bits(afb->address);
>>      addr.address.grph.addr.high_part = upper_32_bits(afb->address);
>>      addr.flip_immediate = async_flip;
>> +    addr.flip_timestamp_in_us = ktime_get_ns() / 1000;
>>    
>>    
>>      if (acrtc->base.state->event)
>> @@ -4550,8 +4580,10 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
>>              return;
>>      }
>>    
>> -    surface_updates->surface = stream_status->plane_states[0];
>> -    if (!surface_updates->surface) {
>> +    surface = stream_status->plane_states[0];
>> +    surface_updates->surface = surface;
>> +
>> +    if (!surface) {
>>              DRM_ERROR("No surface for CRTC: id=%d\n",
>>                      acrtc->crtc_id);
>>              return;
>> @@ -4562,7 +4594,9 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
>>              update_freesync_state_on_stream(
>>                      &adev->dm,
>>                      acrtc_state,
>> -                    acrtc_state->stream);
>> +                    acrtc_state->stream,
>> +                    surface,
>> +                    addr.flip_timestamp_in_us);
>>    
>>              if (acrtc_state->freesync_timing_changed)
>>                      stream_update.adjust =
>> @@ -4573,6 +4607,14 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
>>                              &acrtc_state->stream->vrr_infopacket;
>>      }
>>    
>> +    /* Update surface timing information. */
>> +    surface->time.time_elapsed_in_us[surface->time.index] =
>> +            addr.flip_timestamp_in_us - 
>> surface->time.prev_update_time_in_us;
>> +    surface->time.prev_update_time_in_us = addr.flip_timestamp_in_us;
>> +    surface->time.index++;
>> +    if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
>> +            surface->time.index = 0;
>> +
>>      dc_commit_updates_for_stream(adev->dm.dc,
>>                                           surface_updates,
>>                                           1,
>> @@ -5256,6 +5298,7 @@ static void get_freesync_config_for_crtc(
>>              config.max_refresh_in_uhz =
>>                              aconnector->max_vfreq * 1000000;
>>              config.vsif_supported = true;
>> +            config.btr = true;
>>      }
>>    
>>      new_crtc_state->freesync_config = config;
>> @@ -5266,8 +5309,8 @@ static void reset_freesync_config_for_crtc(
>>    {
>>      new_crtc_state->vrr_supported = false;
>>    
>> -    memset(&new_crtc_state->adjust, 0,
>> -           sizeof(new_crtc_state->adjust));
>> +    memset(&new_crtc_state->vrr_params, 0,
>> +           sizeof(new_crtc_state->vrr_params));
>>      memset(&new_crtc_state->vrr_infopacket, 0,
>>             sizeof(new_crtc_state->vrr_infopacket));
>>    }
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>> index 4326dc256491..59d20781dfdb 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>> @@ -260,7 +260,7 @@ struct dm_crtc_state {
>>    
>>      bool vrr_supported;
>>      struct mod_freesync_config freesync_config;
>> -    struct dc_crtc_timing_adjust adjust;
>> +    struct mod_vrr_params vrr_params;
>>      struct dc_info_packet vrr_infopacket;
>>    
>>      int abm_level;
>>

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to