[Intel-gfx] [PATCH] drm/i915/skl: distribute DDB based on panel resolution

Kumar, Mahesh mahesh1.kumar at intel.com
Tue Jul 31 06:16:42 UTC 2018


Hi Chris,

Thanks for review.

On 7/30/2018 9:08 PM, Chris Wilson wrote:
> Quoting Mahesh Kumar (2018-07-30 15:12:02)
>> We distribute DDB equally among all pipes irrespective of display
>> buffer requirement of each pipe. This leads to a situation where high
>> resolution y-tiled display can not be enabled with 2 low resolution
>> displays.
>>
>> Main contributing factor for DDB requirement is width of the display.
>> This patch make changes to distribute ddb based on display width.
>> So display with higher width will get bigger chunk of DDB.
>>
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107113
>> Cc: raviraj.p.sitaram at intel.com
>> Signed-off-by: Mahesh Kumar <mahesh1.kumar at intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_pm.c | 55 +++++++++++++++++++++++++++++++----------
>>   1 file changed, 42 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index 7312ecb73415..e092f0deb93d 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -3814,8 +3814,14 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>>          struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>>          struct drm_i915_private *dev_priv = to_i915(dev);
>>          struct drm_crtc *for_crtc = cstate->base.crtc;
>> +       enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe;
>> +       const struct drm_crtc_state *crtc_state;
>> +       const struct drm_crtc *crtc;
>> +       u32 pipe_width[I915_MAX_PIPES] = {0};
>> +       u32 total_width = 0, width_before_pipe = 0;
>>          unsigned int pipe_size, ddb_size;
>> -       int nth_active_pipe;
>> +       u16 ddb_size_before_pipe;
>> +       u32 i;
>>   
>>          if (WARN_ON(!state) || !cstate->base.active) {
>>                  alloc->start = 0;
>> @@ -3833,14 +3839,14 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>>                                        *num_active, ddb);
>>   
>>          /*
>> -        * If the state doesn't change the active CRTC's, then there's
>> -        * no need to recalculate; the existing pipe allocation limits
>> -        * should remain unchanged.  Note that we're safe from racing
>> -        * commits since any racing commit that changes the active CRTC
>> -        * list would need to grab _all_ crtc locks, including the one
>> -        * we currently hold.
>> +        * If the state doesn't change the active CRTC's or there is no
>> +        * modeset request, then there's no need to recalculate;
>> +        * the existing pipe allocation limits should remain unchanged.
>> +        * Note that we're safe from racing commits since any racing commit
>> +        * that changes the active CRTC list or do modeset would need to
>> +        * grab _all_ crtc locks, including the one we currently hold.
>>           */
>> -       if (!intel_state->active_pipe_changes) {
>> +       if (!intel_state->active_pipe_changes && !intel_state->modeset) {
>>                  /*
>>                   * alloc may be cleared by clear_intel_crtc_state,
>>                   * copy from old state to be sure
>> @@ -3849,10 +3855,33 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>>                  return;
>>          }
>>   
>> -       nth_active_pipe = hweight32(intel_state->active_crtcs &
>> -                                   (drm_crtc_mask(for_crtc) - 1));
>> -       pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
>> -       alloc->start = nth_active_pipe * ddb_size / *num_active;
>> +       /*
>> +        * Watermark/ddb requirement highly depends upon width of the
>> +        * framebuffer, So instead of allocating DDB equally among pipes
>> +        * distribute DDB based on resolution/width of the display.
>> +        */
>> +       for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
>> +               const struct drm_display_mode *adjusted_mode;
>> +               int hdisplay, vdisplay;
>> +               enum pipe pipe;
>> +
>> +               if (!crtc_state->enable)
>> +                       continue;
>> +
>> +               pipe = to_intel_crtc(crtc)->pipe;
>> +               adjusted_mode = &crtc_state->adjusted_mode;
>> +               drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
>> +               pipe_width[pipe] = hdisplay;
>> +               total_width += pipe_width[pipe];
>> +
>> +               if (pipe < for_pipe)
>> +                       width_before_pipe += pipe_width[pipe];
>> +       }
>> +
>> +       ddb_size_before_pipe = div_u64(ddb_size * width_before_pipe,
>> +                                      total_width);
> ddb_size is unsigned int (u32)
> width_before_pipe is u32
> ddb_size_before_pipe is u16
>
> That mismash of types is itself perplexing, but u32*u16 is only u32, you
> need to cast it to u64 to avoid the overflow: i.e.
> 	div_u64(mul_u32_u32(ddb_size, width_before_pipe),
> 	        total_width);
>
> But ddb_size_before_pipe obviously need to be the same type as ddb_size,
> and if u16 is good enough, then you do not need a 64b divide!
hmm, ddb_size will not go beyond u16 as we have only 1024 blocks and in 
future also I'm not expecting it to overflow u16.
I don't wanted to change already used data-types , anyway will clean 
this part :)
>
>> +       pipe_size = div_u64(ddb_size * pipe_width[for_pipe], total_width);
> So why did you store all pipe_width?
hmm agree, we don't really need to store the width for each pipe.
>
> And are not all the previous pipes stored in their respective cstate? So
> alloc->start = &previous_cstate->wm.skl.ddb->end;
Actually this function may not get called in fixed sequence each time 
for each CRTC, It will be called first for the crtc which got added 
first in state.
I don't want to shuffle the DDB allocation during each modeset as in 
most of the cases we will be only changing refresh-rate of the panel not 
the resolution (dynamic media refresh rate switching kind of scenarios)

thanks,
-Mahesh
>
> Looking at the earlier results seems far more robust.
> -Chris



More information about the Intel-gfx mailing list