[Freedreno] [RFC PATCH v2 12/13] drm/msm/dpu: add support for virtual planes
Abhinav Kumar
quic_abhinavk at quicinc.com
Sat Jun 10 00:00:08 UTC 2023
On 6/8/2023 12:51 PM, Abhinav Kumar wrote:
>
>
> On 6/7/2023 2:56 PM, Dmitry Baryshkov wrote:
>> On 08/06/2023 00:05, Abhinav Kumar wrote:
>>>
>>>
>>> On 3/20/2023 6:18 PM, Dmitry Baryshkov wrote:
>>>> Only several SSPP blocks support such features as YUV output or
>>>> scaling,
>>>> thus different DRM planes have different features. Properly utilizing
>>>> all planes requires the attention of the compositor, who should
>>>> prefer simpler planes to YUV-supporting ones. Otherwise it is very easy
>>>> to end up in a situation when all featureful planes are already
>>>> allocated for simple windows, leaving no spare plane for YUV playback.
>>>>
>>>> To solve this problem make all planes virtual. Each plane is registered
>>>> as if it supports all possible features, but then at the runtime during
>>>> the atomic_check phase the driver selects backing SSPP block for each
>>>> plane.
>>>>
>>>> Note, this does not provide support for using two different SSPP blocks
>>>> for a single plane or using two rectangles of an SSPP to drive two
>>>> planes. Each plane still gets its own SSPP and can utilize either a
>>>> solo
>>>> rectangle or both multirect rectangles depending on the resolution.
>>>>
>>>> Note #2: By default support for virtual planes is turned off and the
>>>> driver still uses old code path with preallocated SSPP block for each
>>>> plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=1'
>>>> kernel parameter.
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>>> ---
>>>
>>> There will be some rebase needed to switch back to encoder based
>>> allocation so I am not going to comment on those parts and will let
>>> you handle that when you post v3.
>>>
>>> But my questions/comments below are for other things.
>>>
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 59 +++++--
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 120 ++++++++++----
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 +
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 187
>>>> ++++++++++++++++++----
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 24 ++-
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 65 ++++++++
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 24 +++
>>>> 7 files changed, 413 insertions(+), 70 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> index 8ef191fd002d..cdece21b81c9 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> @@ -1273,6 +1273,29 @@ static int dpu_crtc_assign_resources(struct
>>>> drm_crtc *crtc, struct drm_crtc_stat
>>>> return 0;
>>>> }
>>>> +static int dpu_crtc_assign_plane_resources(struct drm_crtc *crtc,
>>>> struct drm_crtc_state *crtc_state)
>>>> +{
>>>> + struct dpu_global_state *global_state;
>>>> + struct drm_plane *plane;
>>>> + int rc;
>>>> +
>>>> + global_state = dpu_kms_get_global_state(crtc_state->state);
>>>> + if (IS_ERR(global_state))
>>>> + return PTR_ERR(global_state);
>>>> +
>>>> + dpu_rm_release_all_sspp(global_state, crtc);
>>>> +
>>>> + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
>>>> + rc = dpu_plane_virtual_assign_resources(plane, crtc,
>>>> + global_state,
>>>> + crtc_state->state);
>>>> + if (rc)
>>>> + return rc;
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>>>> struct drm_atomic_state *state)
>>>> {
>>>> @@ -1281,7 +1304,6 @@ static int dpu_crtc_atomic_check(struct
>>>> drm_crtc *crtc,
>>>> struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>>>> struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
>>>> - const struct drm_plane_state *pstate;
>>>> struct drm_plane *plane;
>>>> int rc = 0;
>>>> @@ -1294,6 +1316,13 @@ static int dpu_crtc_atomic_check(struct
>>>> drm_crtc *crtc,
>>>> return rc;
>>>> }
>>>> + if (dpu_use_virtual_planes &&
>>>> + crtc_state->planes_changed) {
>>>> + rc = dpu_crtc_assign_plane_resources(crtc, crtc_state);
>>>> + if (rc < 0)
>>>> + return rc;
>>>> + }
>>>
>>> Can you please explain a bit more about the planes_changed condition?
>>>
>>> 1) Are we doing this because the plane's atomic check happens before
>>> the CRTC atomic check?
>>
>> Yes. Another alternative would be to stop using
>> drm_atomic_helper_check() and implement our own code instead,
>> inverting the plane / CRTC check order.
>>
>
> I am fine with that too but as you noted in (3), if planes_changed will
> be set by those functions and you can drop explicit assignment of it in
> this patch, that will be the best option for me.
>
>>>
>>> 2) So the DRM core sets this to true already when plane is switching
>>> CRTCs or being connected to a CRTC for the first time, we need to
>>> handle the conditions additional to that right?
>>
>> Nit: it is not possible to switch CRTCs. Plane first has to be
>> disconnected and then to be connected to another CRTC.
>>
>>>
>>> 3) If (2) is correct, arent there other conditions then to be handled
>>> for setting planes_changed to true?
>>>
>>> Some examples include, switching from a scaling to non-scaling
>>> scenario, needing rotation vs not needing etc.
>>
>> Setting the plane_changed is not required. Both
>> drm_atomic_helper_disable_plane() and drm_atomic_helper_update_plane()
>> will add the plane to the state. Then drm_atomic_helper_check_planes()
>> will call drm_atomic_helper_plane_changed(), setting
>> {old_,new_}crtc_state->planes_changed.
>>
>> I should check if the format check below is required or not. It looks
>> like I can drop that clause too.
>>
>
> Yes, please do. From the above explanation, it seems like we dont need
> to explicity set it again ourselves for format change.
>
>>
I have a basic doubt about the split between dpu_plane_atomic_check Vs
dpu_crtc_atomic_check() because the next patch is also relying heavily
on the fact that plane's atomic check comes first and then crtc.
Please help me understand this better.
-> dpu_plane_virtual_atomic_check() is called and today that doesnt seem
to do much :
- marks visible as false if there is no fb
(wouldnt the DRM core already do this?)
- caches the format
(this part is used in the dpu_crtc_atomic_check())
-> dpu_crtc_atomic_check() gets called which calls
dpu_crtc_assign_plane_resources() which finally reserves the SSPPs to
back the planes
-> perform dpu_plane_atomic_check() on each of the planes on the CRTC by
checking the planes attached to CRTC state
1) What would be wrong to continue using dpu_plane_atomic_check()
instead of the newly created dpu_plane_virtual_atomic_check() to get the
backing SSPPs because it seems we need to maintain lot of information in
the dpu_plane_state to manage co-ordination between the two atomic
checks? A big portion of even the next patch does that.
2) Even dpu_plane_atomic_check() / dpu_plane_virtual_atomic_check() is
called only for each plane in the CRTC state, so why all the movement to
crtc's atomic_check()? I am missing the link here. Was it done only to
move all resource allocation to CRTC ID?
More information about the Freedreno
mailing list