* [PATCH v2 01/22] drm: add clone mode check for CRTC
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:06 ` Dmitry Baryshkov
2024-09-25 8:12 ` Jani Nikula
2024-09-24 22:59 ` [PATCH v2 02/22] drm: Add valid clones check Jessica Zhang
` (20 subsequent siblings)
21 siblings, 2 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Add helper to check if the given CRTC state is in clone mode
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
include/drm/drm_crtc.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 8b48a1974da3..ecb93e2c4afc 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1323,5 +1323,12 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
unsigned int supported_filters);
+static inline bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)
+{
+ if (!crtc_state)
+ return false;
+
+ return hweight32(crtc_state->encoder_mask) > 1;
+}
#endif /* __DRM_CRTC_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 01/22] drm: add clone mode check for CRTC
2024-09-24 22:59 ` [PATCH v2 01/22] drm: add clone mode check for CRTC Jessica Zhang
@ 2024-09-24 23:06 ` Dmitry Baryshkov
2024-09-25 7:22 ` Maxime Ripard
2024-09-25 8:12 ` Jani Nikula
1 sibling, 1 reply; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:06 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:17PM GMT, Jessica Zhang wrote:
> Add helper to check if the given CRTC state is in clone mode
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> include/drm/drm_crtc.h | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 8b48a1974da3..ecb93e2c4afc 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1323,5 +1323,12 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
>
> int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
> unsigned int supported_filters);
Missing kerneldoc
> +static inline bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)
> +{
> + if (!crtc_state)
> + return false;
> +
> + return hweight32(crtc_state->encoder_mask) > 1;
> +}
>
> #endif /* __DRM_CRTC_H__ */
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 01/22] drm: add clone mode check for CRTC
2024-09-24 23:06 ` Dmitry Baryshkov
@ 2024-09-25 7:22 ` Maxime Ripard
0 siblings, 0 replies; 64+ messages in thread
From: Maxime Ripard @ 2024-09-25 7:22 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Jessica Zhang, Rob Clark, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
[-- Attachment #1: Type: text/plain, Size: 900 bytes --]
On Wed, Sep 25, 2024 at 02:06:35AM GMT, Dmitry Baryshkov wrote:
> On Tue, Sep 24, 2024 at 03:59:17PM GMT, Jessica Zhang wrote:
> > Add helper to check if the given CRTC state is in clone mode
> >
> > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > ---
> > include/drm/drm_crtc.h | 7 +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > index 8b48a1974da3..ecb93e2c4afc 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -1323,5 +1323,12 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
> >
> > int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
> > unsigned int supported_filters);
>
> Missing kerneldoc
Also, a proper commit log to describe what this will be used for, and
ideally some kunit tests.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v2 01/22] drm: add clone mode check for CRTC
2024-09-24 22:59 ` [PATCH v2 01/22] drm: add clone mode check for CRTC Jessica Zhang
2024-09-24 23:06 ` Dmitry Baryshkov
@ 2024-09-25 8:12 ` Jani Nikula
2024-09-25 20:47 ` Jessica Zhang
1 sibling, 1 reply; 64+ messages in thread
From: Jani Nikula @ 2024-09-25 8:12 UTC (permalink / raw)
To: Jessica Zhang, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
On Tue, 24 Sep 2024, Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> Add helper to check if the given CRTC state is in clone mode
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> include/drm/drm_crtc.h | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 8b48a1974da3..ecb93e2c4afc 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1323,5 +1323,12 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
>
> int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
> unsigned int supported_filters);
> +static inline bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)
> +{
> + if (!crtc_state)
> + return false;
> +
> + return hweight32(crtc_state->encoder_mask) > 1;
> +}
What's the benefit of this being static inline?
You're implicitly depending on hweight32() being available, basically
<linux/bitops.h> being included. Maybe it already is, but it's the
accumulation of small and innocent looking things like this that then
explode the header dependencies, and make them harder to reduce.
BR,
Jani.
>
> #endif /* __DRM_CRTC_H__ */
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 01/22] drm: add clone mode check for CRTC
2024-09-25 8:12 ` Jani Nikula
@ 2024-09-25 20:47 ` Jessica Zhang
0 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-25 20:47 UTC (permalink / raw)
To: Jani Nikula, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 9/25/2024 1:12 AM, Jani Nikula wrote:
> On Tue, 24 Sep 2024, Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>> Add helper to check if the given CRTC state is in clone mode
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> include/drm/drm_crtc.h | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
>> index 8b48a1974da3..ecb93e2c4afc 100644
>> --- a/include/drm/drm_crtc.h
>> +++ b/include/drm/drm_crtc.h
>> @@ -1323,5 +1323,12 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
>>
>> int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
>> unsigned int supported_filters);
>> +static inline bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state)
>> +{
>> + if (!crtc_state)
>> + return false;
>> +
>> + return hweight32(crtc_state->encoder_mask) > 1;
>> +}
>
> What's the benefit of this being static inline?
>
> You're implicitly depending on hweight32() being available, basically
> <linux/bitops.h> being included. Maybe it already is, but it's the
> accumulation of small and innocent looking things like this that then
> explode the header dependencies, and make them harder to reduce.
Hi Jani,
Good point, I'll move the implementation to drm_crtc.c.
Thanks,
Jessica Zhang
>
> BR,
> Jani.
>
>>
>> #endif /* __DRM_CRTC_H__ */
>
> --
> Jani Nikula, Intel
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 02/22] drm: Add valid clones check
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 01/22] drm: add clone mode check for CRTC Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-25 7:23 ` Maxime Ripard
2024-09-24 22:59 ` [PATCH v2 03/22] drm/msm/dpu: get rid of struct dpu_rm_requirements Jessica Zhang
` (19 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Check that all encoders attached to a given CRTC are valid
possible_clones of each other.
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 43cdf39019a4..cc4001804fdc 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
return 0;
}
+static int drm_atomic_check_valid_clones(struct drm_atomic_state *state,
+ struct drm_crtc *crtc)
+{
+ struct drm_encoder *drm_enc;
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
+ crtc);
+
+ drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
+ if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
+ crtc_state->encoder_mask) {
+ DRM_DEBUG("crtc%d failed valid clone check for mask 0x%x\n",
+ crtc->base.id, crtc_state->encoder_mask);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/**
* drm_atomic_helper_check_modeset - validate state object for modeset changes
* @dev: DRM device
@@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret != 0)
return ret;
+
+ ret = drm_atomic_check_valid_clones(state, crtc);
+ if (ret != 0)
+ return ret;
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-09-24 22:59 ` [PATCH v2 02/22] drm: Add valid clones check Jessica Zhang
@ 2024-09-25 7:23 ` Maxime Ripard
2024-12-07 0:48 ` Jessica Zhang
0 siblings, 1 reply; 64+ messages in thread
From: Maxime Ripard @ 2024-09-25 7:23 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
[-- Attachment #1: Type: text/plain, Size: 1761 bytes --]
On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
> Check that all encoders attached to a given CRTC are valid
> possible_clones of each other.
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 43cdf39019a4..cc4001804fdc 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
> return 0;
> }
>
> +static int drm_atomic_check_valid_clones(struct drm_atomic_state *state,
> + struct drm_crtc *crtc)
> +{
> + struct drm_encoder *drm_enc;
> + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
> + crtc);
> +
> + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
> + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
> + crtc_state->encoder_mask) {
> + DRM_DEBUG("crtc%d failed valid clone check for mask 0x%x\n",
> + crtc->base.id, crtc_state->encoder_mask);
> + return -EINVAL;
> + }
> + }
> +
> + return 0;
> +}
> +
> /**
> * drm_atomic_helper_check_modeset - validate state object for modeset changes
> * @dev: DRM device
> @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> ret = drm_atomic_add_affected_planes(state, crtc);
> if (ret != 0)
> return ret;
> +
> + ret = drm_atomic_check_valid_clones(state, crtc);
> + if (ret != 0)
> + return ret;
> }
Pretty much the same comment, we should have kunit tests for this.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-09-25 7:23 ` Maxime Ripard
@ 2024-12-07 0:48 ` Jessica Zhang
2024-12-16 2:19 ` Abhinav Kumar
2024-12-16 14:47 ` Maxime Ripard
0 siblings, 2 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-12-07 0:48 UTC (permalink / raw)
To: Maxime Ripard
Cc: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On 9/25/2024 12:23 AM, Maxime Ripard wrote:
> On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
>> Check that all encoders attached to a given CRTC are valid
>> possible_clones of each other.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
>> 1 file changed, 23 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>> index 43cdf39019a4..cc4001804fdc 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
>> return 0;
>> }
>>
>> +static int drm_atomic_check_valid_clones(struct drm_atomic_state *state,
>> + struct drm_crtc *crtc)
>> +{
>> + struct drm_encoder *drm_enc;
>> + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
>> + crtc);
>> +
>> + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
>> + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
>> + crtc_state->encoder_mask) {
>> + DRM_DEBUG("crtc%d failed valid clone check for mask 0x%x\n",
>> + crtc->base.id, crtc_state->encoder_mask);
>> + return -EINVAL;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> /**
>> * drm_atomic_helper_check_modeset - validate state object for modeset changes
>> * @dev: DRM device
>> @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>> ret = drm_atomic_add_affected_planes(state, crtc);
>> if (ret != 0)
>> return ret;
>> +
>> + ret = drm_atomic_check_valid_clones(state, crtc);
>> + if (ret != 0)
>> + return ret;
>> }
>
> Pretty much the same comment, we should have kunit tests for this.
Hey Maxime,
I'm working on the kunit test for this and had a question on the design
for the unit test:
Since this is a static helper that returns a pretty common error code,
how would you recommend going about making sure that
`drm_atomic_check_valid_clones()` specifically is returning the error
(and not a different part of check_modeset) when testing the
check_valid_clones() failure path?
Thanks,
Jessica Zhang
>
> Maxime
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-12-07 0:48 ` Jessica Zhang
@ 2024-12-16 2:19 ` Abhinav Kumar
2024-12-16 14:27 ` Simona Vetter
2024-12-16 14:47 ` Maxime Ripard
1 sibling, 1 reply; 64+ messages in thread
From: Abhinav Kumar @ 2024-12-16 2:19 UTC (permalink / raw)
To: Jessica Zhang, Maxime Ripard
Cc: Rob Clark, Dmitry Baryshkov, Sean Paul, Marijn Suijten,
David Airlie, Daniel Vetter, Maarten Lankhorst, Thomas Zimmermann,
quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
Hi Maxime
Gentle reminder on this one.
We are looking for some advice on how to go about KUnit for this static
function.
Please help with our question below.
Thanks
Abhinav
On 12/6/2024 4:48 PM, Jessica Zhang wrote:
>
>
> On 9/25/2024 12:23 AM, Maxime Ripard wrote:
>> On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
>>> Check that all encoders attached to a given CRTC are valid
>>> possible_clones of each other.
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>> drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
>>> 1 file changed, 23 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c
>>> b/drivers/gpu/drm/drm_atomic_helper.c
>>> index 43cdf39019a4..cc4001804fdc 100644
>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>> @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
>>> return 0;
>>> }
>>> +static int drm_atomic_check_valid_clones(struct drm_atomic_state
>>> *state,
>>> + struct drm_crtc *crtc)
>>> +{
>>> + struct drm_encoder *drm_enc;
>>> + struct drm_crtc_state *crtc_state =
>>> drm_atomic_get_new_crtc_state(state,
>>> + crtc);
>>> +
>>> + drm_for_each_encoder_mask(drm_enc, crtc->dev,
>>> crtc_state->encoder_mask) {
>>> + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
>>> + crtc_state->encoder_mask) {
>>> + DRM_DEBUG("crtc%d failed valid clone check for mask
>>> 0x%x\n",
>>> + crtc->base.id, crtc_state->encoder_mask);
>>> + return -EINVAL;
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> /**
>>> * drm_atomic_helper_check_modeset - validate state object for
>>> modeset changes
>>> * @dev: DRM device
>>> @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct
>>> drm_device *dev,
>>> ret = drm_atomic_add_affected_planes(state, crtc);
>>> if (ret != 0)
>>> return ret;
>>> +
>>> + ret = drm_atomic_check_valid_clones(state, crtc);
>>> + if (ret != 0)
>>> + return ret;
>>> }
>>
>> Pretty much the same comment, we should have kunit tests for this.
>
> Hey Maxime,
>
> I'm working on the kunit test for this and had a question on the design
> for the unit test:
>
> Since this is a static helper that returns a pretty common error code,
> how would you recommend going about making sure that
> `drm_atomic_check_valid_clones()` specifically is returning the error
> (and not a different part of check_modeset) when testing the
> check_valid_clones() failure path?
>
> Thanks,
>
> Jessica Zhang
>
>>
>> Maxime
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-12-16 2:19 ` Abhinav Kumar
@ 2024-12-16 14:27 ` Simona Vetter
2024-12-16 19:44 ` Jessica Zhang
0 siblings, 1 reply; 64+ messages in thread
From: Simona Vetter @ 2024-12-16 14:27 UTC (permalink / raw)
To: Abhinav Kumar
Cc: Jessica Zhang, Maxime Ripard, Rob Clark, Dmitry Baryshkov,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Thomas Zimmermann, quic_ebharadw,
linux-arm-msm, dri-devel, freedreno, linux-kernel, Rob Clark,
Ville Syrjälä
On Sun, Dec 15, 2024 at 06:19:08PM -0800, Abhinav Kumar wrote:
> Hi Maxime
>
> Gentle reminder on this one.
>
> We are looking for some advice on how to go about KUnit for this static
> function.
>
> Please help with our question below.
>
> Thanks
>
> Abhinav
>
> On 12/6/2024 4:48 PM, Jessica Zhang wrote:
> >
> >
> > On 9/25/2024 12:23 AM, Maxime Ripard wrote:
> > > On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
> > > > Check that all encoders attached to a given CRTC are valid
> > > > possible_clones of each other.
> > > >
> > > > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > > > ---
> > > > drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
> > > > 1 file changed, 23 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c
> > > > b/drivers/gpu/drm/drm_atomic_helper.c
> > > > index 43cdf39019a4..cc4001804fdc 100644
> > > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > > @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
> > > > return 0;
> > > > }
> > > > +static int drm_atomic_check_valid_clones(struct
> > > > drm_atomic_state *state,
> > > > + struct drm_crtc *crtc)
> > > > +{
> > > > + struct drm_encoder *drm_enc;
> > > > + struct drm_crtc_state *crtc_state =
> > > > drm_atomic_get_new_crtc_state(state,
> > > > + crtc);
> > > > +
> > > > + drm_for_each_encoder_mask(drm_enc, crtc->dev,
> > > > crtc_state->encoder_mask) {
> > > > + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
> > > > + crtc_state->encoder_mask) {
> > > > + DRM_DEBUG("crtc%d failed valid clone check for mask
> > > > 0x%x\n",
> > > > + crtc->base.id, crtc_state->encoder_mask);
> > > > + return -EINVAL;
> > > > + }
> > > > + }
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > /**
> > > > * drm_atomic_helper_check_modeset - validate state object for
> > > > modeset changes
> > > > * @dev: DRM device
> > > > @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct
> > > > drm_device *dev,
> > > > ret = drm_atomic_add_affected_planes(state, crtc);
> > > > if (ret != 0)
> > > > return ret;
> > > > +
> > > > + ret = drm_atomic_check_valid_clones(state, crtc);
> > > > + if (ret != 0)
> > > > + return ret;
> > > > }
> > >
> > > Pretty much the same comment, we should have kunit tests for this.
> >
> > Hey Maxime,
> >
> > I'm working on the kunit test for this and had a question on the design
> > for the unit test:
> >
> > Since this is a static helper that returns a pretty common error code,
> > how would you recommend going about making sure that
> > `drm_atomic_check_valid_clones()` specifically is returning the error
> > (and not a different part of check_modeset) when testing the
> > check_valid_clones() failure path?
So the usual way to test very specific things of a big function is to
first setup a driver and atomic request which does pass all checks. And
then do a minimal change which does not pass anymore.
So what you could do here is have 3 connectors 1 crtc, but only the first
two connectors can be cloned. Then do an atomic request with those two
connectors and the crtc. Then the 2nd request is with one of the
connectors replaced with the 3rd one (so it's still a clone config, but
not an invalid one), then have a failure.
Note: I didn't check all the details, I might be getting something wrong
here, but the idea should work.
Cheers, Sima
> >
> > Thanks,
> >
> > Jessica Zhang
> >
> > >
> > > Maxime
> >
--
Simona Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-12-16 14:27 ` Simona Vetter
@ 2024-12-16 19:44 ` Jessica Zhang
0 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-12-16 19:44 UTC (permalink / raw)
To: Abhinav Kumar, Maxime Ripard, Rob Clark, Dmitry Baryshkov,
Sean Paul, Marijn Suijten, David Airlie, Maarten Lankhorst,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On 12/16/2024 6:27 AM, Simona Vetter wrote:
> On Sun, Dec 15, 2024 at 06:19:08PM -0800, Abhinav Kumar wrote:
>> Hi Maxime
>>
>> Gentle reminder on this one.
>>
>> We are looking for some advice on how to go about KUnit for this static
>> function.
>>
>> Please help with our question below.
>>
>> Thanks
>>
>> Abhinav
>>
>> On 12/6/2024 4:48 PM, Jessica Zhang wrote:
>>>
>>>
>>> On 9/25/2024 12:23 AM, Maxime Ripard wrote:
>>>> On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
>>>>> Check that all encoders attached to a given CRTC are valid
>>>>> possible_clones of each other.
>>>>>
>>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>>> ---
>>>>> drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
>>>>> 1 file changed, 23 insertions(+)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c
>>>>> b/drivers/gpu/drm/drm_atomic_helper.c
>>>>> index 43cdf39019a4..cc4001804fdc 100644
>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>>>> @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
>>>>> return 0;
>>>>> }
>>>>> +static int drm_atomic_check_valid_clones(struct
>>>>> drm_atomic_state *state,
>>>>> + struct drm_crtc *crtc)
>>>>> +{
>>>>> + struct drm_encoder *drm_enc;
>>>>> + struct drm_crtc_state *crtc_state =
>>>>> drm_atomic_get_new_crtc_state(state,
>>>>> + crtc);
>>>>> +
>>>>> + drm_for_each_encoder_mask(drm_enc, crtc->dev,
>>>>> crtc_state->encoder_mask) {
>>>>> + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
>>>>> + crtc_state->encoder_mask) {
>>>>> + DRM_DEBUG("crtc%d failed valid clone check for mask
>>>>> 0x%x\n",
>>>>> + crtc->base.id, crtc_state->encoder_mask);
>>>>> + return -EINVAL;
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> /**
>>>>> * drm_atomic_helper_check_modeset - validate state object for
>>>>> modeset changes
>>>>> * @dev: DRM device
>>>>> @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct
>>>>> drm_device *dev,
>>>>> ret = drm_atomic_add_affected_planes(state, crtc);
>>>>> if (ret != 0)
>>>>> return ret;
>>>>> +
>>>>> + ret = drm_atomic_check_valid_clones(state, crtc);
>>>>> + if (ret != 0)
>>>>> + return ret;
>>>>> }
>>>>
>>>> Pretty much the same comment, we should have kunit tests for this.
>>>
>>> Hey Maxime,
>>>
>>> I'm working on the kunit test for this and had a question on the design
>>> for the unit test:
>>>
>>> Since this is a static helper that returns a pretty common error code,
>>> how would you recommend going about making sure that
>>> `drm_atomic_check_valid_clones()` specifically is returning the error
>>> (and not a different part of check_modeset) when testing the
>>> check_valid_clones() failure path?
>
> So the usual way to test very specific things of a big function is to
> first setup a driver and atomic request which does pass all checks. And
> then do a minimal change which does not pass anymore.
>
> So what you could do here is have 3 connectors 1 crtc, but only the first
> two connectors can be cloned. Then do an atomic request with those two
> connectors and the crtc. Then the 2nd request is with one of the
> connectors replaced with the 3rd one (so it's still a clone config, but
> not an invalid one), then have a failure.
>
> Note: I didn't check all the details, I might be getting something wrong
> here, but the idea should work.
Hey Sima,
Ack, FWIW this describes something very similar to my planned test cases
(my current kunit tests 3 cases -- valid clone, invalid clone, and no
clones). Will post the changes later today if there's no major
objections to this.
Thanks,
Jessica Zhang
>
> Cheers, Sima
>
>>>
>>> Thanks,
>>>
>>> Jessica Zhang
>>>
>>>>
>>>> Maxime
>>>
>
> --
> Simona Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-12-07 0:48 ` Jessica Zhang
2024-12-16 2:19 ` Abhinav Kumar
@ 2024-12-16 14:47 ` Maxime Ripard
2024-12-16 19:47 ` Jessica Zhang
1 sibling, 1 reply; 64+ messages in thread
From: Maxime Ripard @ 2024-12-16 14:47 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
[-- Attachment #1: Type: text/plain, Size: 3004 bytes --]
On Fri, Dec 06, 2024 at 04:48:43PM -0800, Jessica Zhang wrote:
> On 9/25/2024 12:23 AM, Maxime Ripard wrote:
> > On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
> > > Check that all encoders attached to a given CRTC are valid
> > > possible_clones of each other.
> > >
> > > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > > ---
> > > drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
> > > 1 file changed, 23 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > > index 43cdf39019a4..cc4001804fdc 100644
> > > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > > @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
> > > return 0;
> > > }
> > > +static int drm_atomic_check_valid_clones(struct drm_atomic_state *state,
> > > + struct drm_crtc *crtc)
> > > +{
> > > + struct drm_encoder *drm_enc;
> > > + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
> > > + crtc);
> > > +
> > > + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
> > > + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
> > > + crtc_state->encoder_mask) {
> > > + DRM_DEBUG("crtc%d failed valid clone check for mask 0x%x\n",
> > > + crtc->base.id, crtc_state->encoder_mask);
> > > + return -EINVAL;
> > > + }
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > /**
> > > * drm_atomic_helper_check_modeset - validate state object for modeset changes
> > > * @dev: DRM device
> > > @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> > > ret = drm_atomic_add_affected_planes(state, crtc);
> > > if (ret != 0)
> > > return ret;
> > > +
> > > + ret = drm_atomic_check_valid_clones(state, crtc);
> > > + if (ret != 0)
> > > + return ret;
> > > }
> >
> > Pretty much the same comment, we should have kunit tests for this.
>
> Hey Maxime,
>
> I'm working on the kunit test for this and had a question on the design for
> the unit test:
>
> Since this is a static helper that returns a pretty common error code, how
> would you recommend going about making sure that
> `drm_atomic_check_valid_clones()` specifically is returning the error (and
> not a different part of check_modeset) when testing the check_valid_clones()
> failure path?
There's two ways to go about it. Either you can unit test it, prepare a
series of custom states and use
EXPORT_SYMBOL_FOR_TESTS_ONLY/EXPORT_SYMBOL_IF_KUNIT, or you can go the
integration test way and just test that drm_atomic_check is rejected for
unsafe combinations.
I guess I'd prefer the former, but the latter also makes sense and
eventually, it checks what we want: to make sure that we reject such a
state. What part of the code does or with what error code is less
important imo.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 02/22] drm: Add valid clones check
2024-12-16 14:47 ` Maxime Ripard
@ 2024-12-16 19:47 ` Jessica Zhang
0 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-12-16 19:47 UTC (permalink / raw)
To: Maxime Ripard
Cc: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On 12/16/2024 6:47 AM, Maxime Ripard wrote:
> On Fri, Dec 06, 2024 at 04:48:43PM -0800, Jessica Zhang wrote:
>> On 9/25/2024 12:23 AM, Maxime Ripard wrote:
>>> On Tue, Sep 24, 2024 at 03:59:18PM GMT, Jessica Zhang wrote:
>>>> Check that all encoders attached to a given CRTC are valid
>>>> possible_clones of each other.
>>>>
>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>> ---
>>>> drivers/gpu/drm/drm_atomic_helper.c | 23 +++++++++++++++++++++++
>>>> 1 file changed, 23 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>>> index 43cdf39019a4..cc4001804fdc 100644
>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>>> @@ -574,6 +574,25 @@ mode_valid(struct drm_atomic_state *state)
>>>> return 0;
>>>> }
>>>> +static int drm_atomic_check_valid_clones(struct drm_atomic_state *state,
>>>> + struct drm_crtc *crtc)
>>>> +{
>>>> + struct drm_encoder *drm_enc;
>>>> + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
>>>> + crtc);
>>>> +
>>>> + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
>>>> + if ((crtc_state->encoder_mask & drm_enc->possible_clones) !=
>>>> + crtc_state->encoder_mask) {
>>>> + DRM_DEBUG("crtc%d failed valid clone check for mask 0x%x\n",
>>>> + crtc->base.id, crtc_state->encoder_mask);
>>>> + return -EINVAL;
>>>> + }
>>>> + }
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> /**
>>>> * drm_atomic_helper_check_modeset - validate state object for modeset changes
>>>> * @dev: DRM device
>>>> @@ -745,6 +764,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>>>> ret = drm_atomic_add_affected_planes(state, crtc);
>>>> if (ret != 0)
>>>> return ret;
>>>> +
>>>> + ret = drm_atomic_check_valid_clones(state, crtc);
>>>> + if (ret != 0)
>>>> + return ret;
>>>> }
>>>
>>> Pretty much the same comment, we should have kunit tests for this.
>>
>> Hey Maxime,
>>
>> I'm working on the kunit test for this and had a question on the design for
>> the unit test:
>>
>> Since this is a static helper that returns a pretty common error code, how
>> would you recommend going about making sure that
>> `drm_atomic_check_valid_clones()` specifically is returning the error (and
>> not a different part of check_modeset) when testing the check_valid_clones()
>> failure path?
>
> There's two ways to go about it. Either you can unit test it, prepare a
> series of custom states and use
> EXPORT_SYMBOL_FOR_TESTS_ONLY/EXPORT_SYMBOL_IF_KUNIT, or you can go the
> integration test way and just test that drm_atomic_check is rejected for
> unsafe combinations.
>
> I guess I'd prefer the former, but the latter also makes sense and
> eventually, it checks what we want: to make sure that we reject such a
> state. What part of the code does or with what error code is less
> important imo.
Thanks for confirming! The changes I made are based on the latter
approach. Will post the changes later today if you have no objections on
this
Thanks,
Jessica Zhang
>
> Maxime
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 03/22] drm/msm/dpu: get rid of struct dpu_rm_requirements
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 01/22] drm: add clone mode check for CRTC Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 02/22] drm: Add valid clones check Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 04/22] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation Jessica Zhang
` (18 subsequent siblings)
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
The struct dpu_rm_requirements was used to wrap display topology and
hw resources, which meant INTF indices. As of commit ef58e0ad3436
("drm/msm/dpu: get INTF blocks directly rather than through RM") the hw
resources struct was removed, leaving struct dpu_rm_requirements
containing a single field (topology). Remove the useless wrapper.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 71 ++++++++++-------------------
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 2 +-
3 files changed, 25 insertions(+), 50 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 3b171bf227d1..6293e716a1c3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -691,7 +691,7 @@ static int dpu_encoder_virt_atomic_check(
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
- drm_enc, crtc_state, topology);
+ drm_enc, crtc_state, &topology);
}
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 44938ba7a2b7..8193c3d579df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -4,6 +4,7 @@
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
+#include "msm_drv.h"
#define pr_fmt(fmt) "[drm:%s] " fmt, __func__
#include "dpu_kms.h"
#include "dpu_hw_lm.h"
@@ -26,14 +27,6 @@ static inline bool reserved_by_other(uint32_t *res_map, int idx,
return res_map[idx] && res_map[idx] != enc_id;
}
-/**
- * struct dpu_rm_requirements - Reservation requirements parameter bundle
- * @topology: selected topology for the display
- */
-struct dpu_rm_requirements {
- struct msm_display_topology topology;
-};
-
int dpu_rm_init(struct drm_device *dev,
struct dpu_rm *rm,
const struct dpu_mdss_cfg *cat,
@@ -231,14 +224,13 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
* mixer in rm->pingpong_blks[].
* @dspp_idx: output parameter, index of dspp block attached to the layer
* mixer in rm->dspp_blks[].
- * @reqs: input parameter, rm requirements for HW blocks needed in the
- * datapath.
+ * @topology: selected topology for the display
* Return: true if lm matches all requirements, false otherwise
*/
static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
struct dpu_global_state *global_state,
uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
- struct dpu_rm_requirements *reqs)
+ struct msm_display_topology *topology)
{
const struct dpu_lm_cfg *lm_cfg;
int idx;
@@ -263,7 +255,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
}
*pp_idx = idx;
- if (!reqs->topology.num_dspp)
+ if (!topology->num_dspp)
return true;
idx = lm_cfg->dspp - DSPP_0;
@@ -285,7 +277,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
struct dpu_global_state *global_state,
uint32_t enc_id,
- struct dpu_rm_requirements *reqs)
+ struct msm_display_topology *topology)
{
int lm_idx[MAX_BLOCKS];
@@ -293,14 +285,14 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
int dspp_idx[MAX_BLOCKS] = {0};
int i, lm_count = 0;
- if (!reqs->topology.num_lm) {
- DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm);
+ if (!topology->num_lm) {
+ DPU_ERROR("invalid number of lm: %d\n", topology->num_lm);
return -EINVAL;
}
/* Find a primary mixer */
for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) &&
- lm_count < reqs->topology.num_lm; i++) {
+ lm_count < topology->num_lm; i++) {
if (!rm->mixer_blks[i])
continue;
@@ -309,14 +301,14 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
enc_id, i, &pp_idx[lm_count],
- &dspp_idx[lm_count], reqs)) {
+ &dspp_idx[lm_count], topology)) {
continue;
}
++lm_count;
/* Valid primary mixer found, find matching peers */
- if (lm_count < reqs->topology.num_lm) {
+ if (lm_count < topology->num_lm) {
int j = _dpu_rm_get_lm_peer(rm, i);
/* ignore the peer if there is an error or if the peer was already processed */
@@ -329,7 +321,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
if (!_dpu_rm_check_lm_and_get_connected_blks(rm,
global_state, enc_id, j,
&pp_idx[lm_count], &dspp_idx[lm_count],
- reqs)) {
+ topology)) {
continue;
}
@@ -338,7 +330,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
}
}
- if (lm_count != reqs->topology.num_lm) {
+ if (lm_count != topology->num_lm) {
DPU_DEBUG("unable to find appropriate mixers\n");
return -ENAVAIL;
}
@@ -347,7 +339,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
global_state->mixer_to_enc_id[lm_idx[i]] = enc_id;
global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id;
global_state->dspp_to_enc_id[dspp_idx[i]] =
- reqs->topology.num_dspp ? enc_id : 0;
+ topology->num_dspp ? enc_id : 0;
trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
pp_idx[i] + PINGPONG_0);
@@ -584,28 +576,28 @@ static int _dpu_rm_make_reservation(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
struct drm_encoder *enc,
- struct dpu_rm_requirements *reqs)
+ struct msm_display_topology *topology)
{
int ret;
- ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, reqs);
+ ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, topology);
if (ret) {
DPU_ERROR("unable to find appropriate mixers\n");
return ret;
}
ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id,
- &reqs->topology);
+ topology);
if (ret) {
DPU_ERROR("unable to find appropriate CTL\n");
return ret;
}
- ret = _dpu_rm_reserve_dsc(rm, global_state, enc, &reqs->topology);
+ ret = _dpu_rm_reserve_dsc(rm, global_state, enc, topology);
if (ret)
return ret;
- if (reqs->topology.needs_cdm) {
+ if (topology->needs_cdm) {
ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
if (ret) {
DPU_ERROR("unable to find CDM blk\n");
@@ -616,20 +608,6 @@ static int _dpu_rm_make_reservation(
return ret;
}
-static int _dpu_rm_populate_requirements(
- struct drm_encoder *enc,
- struct dpu_rm_requirements *reqs,
- struct msm_display_topology req_topology)
-{
- reqs->topology = req_topology;
-
- DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d cdm: %d\n",
- reqs->topology.num_lm, reqs->topology.num_dsc,
- reqs->topology.num_intf, reqs->topology.needs_cdm);
-
- return 0;
-}
-
static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt,
uint32_t enc_id)
{
@@ -662,9 +640,8 @@ int dpu_rm_reserve(
struct dpu_global_state *global_state,
struct drm_encoder *enc,
struct drm_crtc_state *crtc_state,
- struct msm_display_topology topology)
+ struct msm_display_topology *topology)
{
- struct dpu_rm_requirements reqs;
int ret;
/* Check if this is just a page-flip */
@@ -679,13 +656,11 @@ int dpu_rm_reserve(
DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n",
enc->base.id, crtc_state->crtc->base.id);
- ret = _dpu_rm_populate_requirements(enc, &reqs, topology);
- if (ret) {
- DPU_ERROR("failed to populate hw requirements\n");
- return ret;
- }
+ DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
+ topology->num_lm, topology->num_dsc,
+ topology->num_intf);
- ret = _dpu_rm_make_reservation(rm, global_state, enc, &reqs);
+ ret = _dpu_rm_make_reservation(rm, global_state, enc, topology);
if (ret)
DPU_ERROR("failed to reserve hw resources: %d\n", ret);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index e63db8ace6b9..62cc2edd2ee0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -70,7 +70,7 @@ int dpu_rm_reserve(struct dpu_rm *rm,
struct dpu_global_state *global_state,
struct drm_encoder *drm_enc,
struct drm_crtc_state *crtc_state,
- struct msm_display_topology topology);
+ struct msm_display_topology *topology);
/**
* dpu_rm_reserve - Given the encoder for the display chain, release any
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 04/22] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (2 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 03/22] drm/msm/dpu: get rid of struct dpu_rm_requirements Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC Jessica Zhang
` (17 subsequent siblings)
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Up to now the driver has been using encoder to allocate hardware
resources. Switch it to use CRTC id in preparation for the next step.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 18 +--
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 12 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 182 ++++++++++++++--------------
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 12 +-
4 files changed, 108 insertions(+), 116 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 6293e716a1c3..4a9edcfbcaae 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -687,11 +687,11 @@ static int dpu_encoder_virt_atomic_check(
* Dont allocate when active is false.
*/
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
- dpu_rm_release(global_state, drm_enc);
+ dpu_rm_release(global_state, crtc_state->crtc);
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
- drm_enc, crtc_state, &topology);
+ crtc_state->crtc, &topology);
}
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1125,14 +1125,14 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
/* Query resource that have been reserved in atomic check step. */
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp,
+ drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
ARRAY_SIZE(hw_pp));
num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+ drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+ drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+ drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
@@ -1140,7 +1140,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
: NULL;
num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_DSC,
+ drm_enc->crtc, DPU_HW_BLK_DSC,
hw_dsc, ARRAY_SIZE(hw_dsc));
for (i = 0; i < num_dsc; i++) {
dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]);
@@ -1154,7 +1154,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_cdm = NULL;
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_CDM,
+ drm_enc->crtc, DPU_HW_BLK_CDM,
&hw_cdm, 1);
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
}
@@ -2021,7 +2021,7 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms);
num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, global_state,
- phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+ phys_enc->parent->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
for (i = 0; i < num_lm; i++) {
hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 935ff6fd172c..4fdc5f933261 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -122,12 +122,12 @@ struct dpu_global_state {
struct dpu_rm *rm;
- uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
- uint32_t mixer_to_enc_id[LM_MAX - LM_0];
- uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
- uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
- uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
- uint32_t cdm_to_enc_id;
+ uint32_t pingpong_to_crtc_id[PINGPONG_MAX - PINGPONG_0];
+ uint32_t mixer_to_crtc_id[LM_MAX - LM_0];
+ uint32_t ctl_to_crtc_id[CTL_MAX - CTL_0];
+ uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0];
+ uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0];
+ uint32_t cdm_to_crtc_id;
};
struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 8193c3d579df..bc99b04eae3a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -22,9 +22,9 @@
static inline bool reserved_by_other(uint32_t *res_map, int idx,
- uint32_t enc_id)
+ uint32_t crtc_id)
{
- return res_map[idx] && res_map[idx] != enc_id;
+ return res_map[idx] && res_map[idx] != crtc_id;
}
int dpu_rm_init(struct drm_device *dev,
@@ -216,7 +216,7 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
* pingpong
* @rm: dpu resource manager handle
* @global_state: resources shared across multiple kms objects
- * @enc_id: encoder id requesting for allocation
+ * @crtc_id: encoder id requesting for allocation
* @lm_idx: index of proposed layer mixer in rm->mixer_blks[], function checks
* if lm, and all other hardwired blocks connected to the lm (pp) is
* available and appropriate
@@ -229,14 +229,14 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
*/
static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
+ uint32_t crtc_id, int lm_idx, int *pp_idx, int *dspp_idx,
struct msm_display_topology *topology)
{
const struct dpu_lm_cfg *lm_cfg;
int idx;
/* Already reserved? */
- if (reserved_by_other(global_state->mixer_to_enc_id, lm_idx, enc_id)) {
+ if (reserved_by_other(global_state->mixer_to_crtc_id, lm_idx, crtc_id)) {
DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0);
return false;
}
@@ -248,7 +248,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
return false;
}
- if (reserved_by_other(global_state->pingpong_to_enc_id, idx, enc_id)) {
+ if (reserved_by_other(global_state->pingpong_to_crtc_id, idx, crtc_id)) {
DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id,
lm_cfg->pingpong);
return false;
@@ -264,7 +264,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
return false;
}
- if (reserved_by_other(global_state->dspp_to_enc_id, idx, enc_id)) {
+ if (reserved_by_other(global_state->dspp_to_crtc_id, idx, crtc_id)) {
DPU_DEBUG("lm %d dspp %d already reserved\n", lm_cfg->id,
lm_cfg->dspp);
return false;
@@ -276,7 +276,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
struct msm_display_topology *topology)
{
@@ -300,7 +300,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
lm_idx[lm_count] = i;
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
- enc_id, i, &pp_idx[lm_count],
+ crtc_id, i, &pp_idx[lm_count],
&dspp_idx[lm_count], topology)) {
continue;
}
@@ -319,7 +319,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
continue;
if (!_dpu_rm_check_lm_and_get_connected_blks(rm,
- global_state, enc_id, j,
+ global_state, crtc_id, j,
&pp_idx[lm_count], &dspp_idx[lm_count],
topology)) {
continue;
@@ -336,12 +336,12 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
}
for (i = 0; i < lm_count; i++) {
- global_state->mixer_to_enc_id[lm_idx[i]] = enc_id;
- global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id;
- global_state->dspp_to_enc_id[dspp_idx[i]] =
- topology->num_dspp ? enc_id : 0;
+ global_state->mixer_to_crtc_id[lm_idx[i]] = crtc_id;
+ global_state->pingpong_to_crtc_id[pp_idx[i]] = crtc_id;
+ global_state->dspp_to_crtc_id[dspp_idx[i]] =
+ topology->num_dspp ? crtc_id : 0;
- trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
+ trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, crtc_id,
pp_idx[i] + PINGPONG_0);
}
@@ -351,7 +351,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
static int _dpu_rm_reserve_ctls(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
int ctl_idx[MAX_BLOCKS];
@@ -370,7 +370,7 @@ static int _dpu_rm_reserve_ctls(
if (!rm->ctl_blks[j])
continue;
- if (reserved_by_other(global_state->ctl_to_enc_id, j, enc_id))
+ if (reserved_by_other(global_state->ctl_to_crtc_id, j, crtc_id))
continue;
ctl = to_dpu_hw_ctl(rm->ctl_blks[j]);
@@ -394,8 +394,8 @@ static int _dpu_rm_reserve_ctls(
return -ENAVAIL;
for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) {
- global_state->ctl_to_enc_id[ctl_idx[i]] = enc_id;
- trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id);
+ global_state->ctl_to_crtc_id[ctl_idx[i]] = crtc_id;
+ trace_dpu_rm_reserve_ctls(i + CTL_0, crtc_id);
}
return 0;
@@ -403,12 +403,12 @@ static int _dpu_rm_reserve_ctls(
static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state,
int start,
- uint32_t enc_id)
+ uint32_t crtc_id)
{
int i;
for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) {
- if (global_state->pingpong_to_enc_id[i] == enc_id)
+ if (global_state->pingpong_to_crtc_id[i] == crtc_id)
return i;
}
@@ -429,7 +429,7 @@ static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx)
static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
int num_dsc = 0;
@@ -442,10 +442,10 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
if (!rm->dsc_blks[dsc_idx])
continue;
- if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id))
+ if (reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx, crtc_id))
continue;
- pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id);
+ pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, crtc_id);
if (pp_idx < 0)
return -ENAVAIL;
@@ -453,7 +453,7 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
if (ret)
return -ENAVAIL;
- global_state->dsc_to_enc_id[dsc_idx] = enc_id;
+ global_state->dsc_to_crtc_id[dsc_idx] = crtc_id;
num_dsc++;
pp_idx++;
}
@@ -469,7 +469,7 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
int num_dsc = 0;
@@ -484,11 +484,11 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
continue;
/* consective dsc index to be paired */
- if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) ||
- reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id))
+ if (reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx, crtc_id) ||
+ reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx + 1, crtc_id))
continue;
- pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id);
+ pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, crtc_id);
if (pp_idx < 0)
return -ENAVAIL;
@@ -498,7 +498,7 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
continue;
}
- pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id);
+ pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, crtc_id);
if (pp_idx < 0)
return -ENAVAIL;
@@ -508,8 +508,8 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
continue;
}
- global_state->dsc_to_enc_id[dsc_idx] = enc_id;
- global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id;
+ global_state->dsc_to_crtc_id[dsc_idx] = crtc_id;
+ global_state->dsc_to_crtc_id[dsc_idx + 1] = crtc_id;
num_dsc += 2;
pp_idx++; /* start for next pair */
}
@@ -525,11 +525,9 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
- uint32_t enc_id = enc->base.id;
-
if (!top->num_dsc || !top->num_intf)
return 0;
@@ -545,16 +543,16 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
/* num_dsc should be either 1, 2 or 4 */
if (top->num_dsc > top->num_intf) /* merge mode */
- return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top);
+ return _dpu_rm_dsc_alloc_pair(rm, global_state, crtc_id, top);
else
- return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top);
+ return _dpu_rm_dsc_alloc(rm, global_state, crtc_id, top);
return 0;
}
static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc)
+ uint32_t crtc_id)
{
/* try allocating only one CDM block */
if (!rm->cdm_blk) {
@@ -562,12 +560,12 @@ static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
return -EIO;
}
- if (global_state->cdm_to_enc_id) {
+ if (global_state->cdm_to_crtc_id) {
DPU_ERROR("CDM_0 is already allocated\n");
return -EIO;
}
- global_state->cdm_to_enc_id = enc->base.id;
+ global_state->cdm_to_crtc_id = crtc_id;
return 0;
}
@@ -575,30 +573,31 @@ static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
static int _dpu_rm_make_reservation(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc,
+ uint32_t crtc_id,
struct msm_display_topology *topology)
{
int ret;
- ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, topology);
+ ret = _dpu_rm_reserve_lms(rm, global_state, crtc_id, topology);
if (ret) {
DPU_ERROR("unable to find appropriate mixers\n");
return ret;
}
- ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id,
+
+ ret = _dpu_rm_reserve_ctls(rm, global_state, crtc_id,
topology);
if (ret) {
DPU_ERROR("unable to find appropriate CTL\n");
return ret;
}
- ret = _dpu_rm_reserve_dsc(rm, global_state, enc, topology);
+ ret = _dpu_rm_reserve_dsc(rm, global_state, crtc_id, topology);
if (ret)
return ret;
if (topology->needs_cdm) {
- ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
+ ret = _dpu_rm_reserve_cdm(rm, global_state, crtc_id);
if (ret) {
DPU_ERROR("unable to find CDM blk\n");
return ret;
@@ -609,103 +608,98 @@ static int _dpu_rm_make_reservation(
}
static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt,
- uint32_t enc_id)
+ uint32_t crtc_id)
{
int i;
for (i = 0; i < cnt; i++) {
- if (res_mapping[i] == enc_id)
+ if (res_mapping[i] == crtc_id)
res_mapping[i] = 0;
}
}
void dpu_rm_release(struct dpu_global_state *global_state,
- struct drm_encoder *enc)
+ struct drm_crtc *crtc)
{
- _dpu_rm_clear_mapping(global_state->pingpong_to_enc_id,
- ARRAY_SIZE(global_state->pingpong_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->mixer_to_enc_id,
- ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->ctl_to_enc_id,
- ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->dsc_to_enc_id,
- ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
- ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id);
+ uint32_t crtc_id = crtc->base.id;
+
+ _dpu_rm_clear_mapping(global_state->pingpong_to_crtc_id,
+ ARRAY_SIZE(global_state->pingpong_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->mixer_to_crtc_id,
+ ARRAY_SIZE(global_state->mixer_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->ctl_to_crtc_id,
+ ARRAY_SIZE(global_state->ctl_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->dsc_to_crtc_id,
+ ARRAY_SIZE(global_state->dsc_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->dspp_to_crtc_id,
+ ARRAY_SIZE(global_state->dspp_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(&global_state->cdm_to_crtc_id, 1, crtc_id);
}
int dpu_rm_reserve(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc,
- struct drm_crtc_state *crtc_state,
+ struct drm_crtc *crtc,
struct msm_display_topology *topology)
{
int ret;
- /* Check if this is just a page-flip */
- if (!drm_atomic_crtc_needs_modeset(crtc_state))
- return 0;
-
if (IS_ERR(global_state)) {
DPU_ERROR("failed to global state\n");
return PTR_ERR(global_state);
}
- DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n",
- enc->base.id, crtc_state->crtc->base.id);
+ DRM_DEBUG_KMS("reserving hw for crtc %d\n", crtc->base.id);
DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
topology->num_lm, topology->num_dsc,
topology->num_intf);
- ret = _dpu_rm_make_reservation(rm, global_state, enc, topology);
+ ret = _dpu_rm_make_reservation(rm, global_state, crtc->base.id, topology);
if (ret)
DPU_ERROR("failed to reserve hw resources: %d\n", ret);
-
-
return ret;
}
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
- struct dpu_global_state *global_state, uint32_t enc_id,
+ struct dpu_global_state *global_state, struct drm_crtc *crtc,
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size)
{
+ uint32_t crtc_id = crtc->base.id;
struct dpu_hw_blk **hw_blks;
- uint32_t *hw_to_enc_id;
+ uint32_t *hw_to_crtc_id;
int i, num_blks, max_blks;
switch (type) {
case DPU_HW_BLK_PINGPONG:
hw_blks = rm->pingpong_blks;
- hw_to_enc_id = global_state->pingpong_to_enc_id;
+ hw_to_crtc_id = global_state->pingpong_to_crtc_id;
max_blks = ARRAY_SIZE(rm->pingpong_blks);
break;
case DPU_HW_BLK_LM:
hw_blks = rm->mixer_blks;
- hw_to_enc_id = global_state->mixer_to_enc_id;
+ hw_to_crtc_id = global_state->mixer_to_crtc_id;
max_blks = ARRAY_SIZE(rm->mixer_blks);
break;
case DPU_HW_BLK_CTL:
hw_blks = rm->ctl_blks;
- hw_to_enc_id = global_state->ctl_to_enc_id;
+ hw_to_crtc_id = global_state->ctl_to_crtc_id;
max_blks = ARRAY_SIZE(rm->ctl_blks);
break;
case DPU_HW_BLK_DSPP:
hw_blks = rm->dspp_blks;
- hw_to_enc_id = global_state->dspp_to_enc_id;
+ hw_to_crtc_id = global_state->dspp_to_crtc_id;
max_blks = ARRAY_SIZE(rm->dspp_blks);
break;
case DPU_HW_BLK_DSC:
hw_blks = rm->dsc_blks;
- hw_to_enc_id = global_state->dsc_to_enc_id;
+ hw_to_crtc_id = global_state->dsc_to_crtc_id;
max_blks = ARRAY_SIZE(rm->dsc_blks);
break;
case DPU_HW_BLK_CDM:
hw_blks = &rm->cdm_blk;
- hw_to_enc_id = &global_state->cdm_to_enc_id;
+ hw_to_crtc_id = &global_state->cdm_to_crtc_id;
max_blks = 1;
break;
default:
@@ -715,17 +709,17 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
num_blks = 0;
for (i = 0; i < max_blks; i++) {
- if (hw_to_enc_id[i] != enc_id)
+ if (hw_to_crtc_id[i] != crtc_id)
continue;
if (num_blks == blks_size) {
- DPU_ERROR("More than %d resources assigned to enc %d\n",
- blks_size, enc_id);
+ DPU_ERROR("More than %d resources assigned to crtc %d\n",
+ blks_size, crtc_id);
break;
}
if (!hw_blks[i]) {
- DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
- type, enc_id);
+ DPU_ERROR("Allocated resource %d unavailable to assign to crtc %d\n",
+ type, crtc_id);
break;
}
blks[num_blks++] = hw_blks[i];
@@ -755,37 +749,37 @@ void dpu_rm_print_state(struct drm_printer *p,
drm_puts(p, "resource mapping:\n");
drm_puts(p, "\tpingpong=");
- for (i = 0; i < ARRAY_SIZE(global_state->pingpong_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->pingpong_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->pingpong_blks[i],
- global_state->pingpong_to_enc_id[i]);
+ global_state->pingpong_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tmixer=");
- for (i = 0; i < ARRAY_SIZE(global_state->mixer_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->mixer_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->mixer_blks[i],
- global_state->mixer_to_enc_id[i]);
+ global_state->mixer_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tctl=");
- for (i = 0; i < ARRAY_SIZE(global_state->ctl_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->ctl_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->ctl_blks[i],
- global_state->ctl_to_enc_id[i]);
+ global_state->ctl_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tdspp=");
- for (i = 0; i < ARRAY_SIZE(global_state->dspp_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->dspp_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->dspp_blks[i],
- global_state->dspp_to_enc_id[i]);
+ global_state->dspp_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tdsc=");
- for (i = 0; i < ARRAY_SIZE(global_state->dsc_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->dsc_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->dsc_blks[i],
- global_state->dsc_to_enc_id[i]);
+ global_state->dsc_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tcdm=");
dpu_rm_print_state_helper(p, rm->cdm_blk,
- global_state->cdm_to_enc_id);
+ global_state->cdm_to_crtc_id);
drm_puts(p, "\n");
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 62cc2edd2ee0..36a0b6ed628d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -61,32 +61,30 @@ int dpu_rm_init(struct drm_device *dev,
* HW blocks can then be accessed through dpu_rm_get_* functions.
* HW Reservations should be released via dpu_rm_release_hw.
* @rm: DPU Resource Manager handle
- * @drm_enc: DRM Encoder handle
- * @crtc_state: Proposed Atomic DRM CRTC State handle
+ * @crtc: DRM CRTC handle
* @topology: Pointer to topology info for the display
* @Return: 0 on Success otherwise -ERROR
*/
int dpu_rm_reserve(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *drm_enc,
- struct drm_crtc_state *crtc_state,
+ struct drm_crtc *crtc,
struct msm_display_topology *topology);
/**
* dpu_rm_reserve - Given the encoder for the display chain, release any
* HW blocks previously reserved for that use case.
* @rm: DPU Resource Manager handle
- * @enc: DRM Encoder handle
+ * @crtc: DRM CRTC handle
* @Return: 0 on Success otherwise -ERROR
*/
void dpu_rm_release(struct dpu_global_state *global_state,
- struct drm_encoder *enc);
+ struct drm_crtc *crtc);
/**
* Get hw resources of the given type that are assigned to this encoder.
*/
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
- struct dpu_global_state *global_state, uint32_t enc_id,
+ struct dpu_global_state *global_state, struct drm_crtc *crtc,
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (3 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 04/22] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:13 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c Jessica Zhang
` (16 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
All resource allocation is centered around the LMs. Then other blocks
(except DSCs) are allocated basing on the LMs that was selected, and LM
powers up the CRTC rather than the encoder.
Moreover if at some point the driver supports encoder cloning,
allocating resources from the encoder will be incorrect, as all clones
will have different encoder IDs, while LMs are to be shared by these
encoders.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
[quic_abhinavk@quicinc.com: Refactored resource allocation for CDM]
Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
[quic_jesszhan@quicinc.com: Changed to grabbing exising global state]
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 86 ++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 +++++++++++-----------------
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++
3 files changed, 183 insertions(+), 123 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 4c1be2f0555f..b918c80d30b3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1163,6 +1163,78 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
return false;
}
+#define MAX_HDISPLAY_SPLIT 1080
+
+static struct msm_display_topology dpu_crtc_get_topology(
+ struct drm_crtc *crtc,
+ struct dpu_kms *dpu_kms,
+ struct drm_crtc_state *crtc_state)
+{
+ struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+ struct msm_display_topology topology = {0};
+ struct drm_encoder *drm_enc;
+
+ drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask)
+ dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state,
+ &crtc_state->adjusted_mode);
+
+ /*
+ * Datapath topology selection
+ *
+ * Dual display
+ * 2 LM, 2 INTF ( Split display using 2 interfaces)
+ *
+ * Single display
+ * 1 LM, 1 INTF
+ * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
+ *
+ * Add dspps to the reservation requirements if ctm is requested
+ */
+
+ if (topology.num_intf == 2)
+ topology.num_lm = 2;
+ else if (topology.num_dsc == 2)
+ topology.num_lm = 2;
+ else if (dpu_kms->catalog->caps->has_3d_merge)
+ topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
+ else
+ topology.num_lm = 1;
+
+ if (crtc_state->ctm)
+ topology.num_dspp = topology.num_lm;
+
+ return topology;
+}
+
+static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
+{
+ struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+ struct dpu_global_state *global_state;
+ struct msm_display_topology topology;
+ int ret;
+
+ /*
+ * Release and Allocate resources on every modeset
+ * Dont allocate when enable is false.
+ */
+ global_state = dpu_kms_get_existing_global_state(dpu_kms);
+ if (IS_ERR(global_state))
+ return PTR_ERR(global_state);
+
+ dpu_rm_release(global_state, crtc);
+
+ if (!crtc_state->enable)
+ return 0;
+
+ topology = dpu_crtc_get_topology(crtc, dpu_kms, crtc_state);
+ ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
+ crtc, &topology);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
@@ -1174,10 +1246,24 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
const struct drm_plane_state *pstate;
struct drm_plane *plane;
+ struct drm_encoder *drm_enc;
+
int rc = 0;
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
+ /* there might be cases where encoder needs a modeset too */
+ drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
+ if (dpu_encoder_needs_modeset(drm_enc, crtc_state->state))
+ crtc_state->mode_changed = true;
+ }
+
+ if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+ rc = dpu_crtc_assign_resources(crtc, crtc_state);
+ if (rc < 0)
+ return rc;
+ }
+
if (!crtc_state->enable || !drm_atomic_crtc_effectively_active(crtc_state)) {
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
crtc->base.id, crtc_state->enable,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 4a9edcfbcaae..ada9119326ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -58,8 +58,6 @@
#define IDLE_SHORT_TIMEOUT 1
-#define MAX_HDISPLAY_SPLIT 1080
-
/* timeout in frames waiting for frame done */
#define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5
@@ -544,159 +542,117 @@ void dpu_encoder_helper_split_config(
}
}
-bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
+void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
+ struct msm_display_topology *topology,
+ struct drm_atomic_state *state,
+ const struct drm_display_mode *adj_mode)
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
- int i, intf_count = 0, num_dsc = 0;
+ struct drm_connector *connector;
+ struct drm_connector_state *conn_state;
+ struct msm_display_info *disp_info;
+ struct drm_framebuffer *fb;
+ struct msm_drm_private *priv;
+ int i;
for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
if (dpu_enc->phys_encs[i])
- intf_count++;
+ topology->num_intf++;
- /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
+ /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
if (dpu_enc->dsc)
- num_dsc = 2;
+ topology->num_dsc += 2;
- return (num_dsc > 0) && (num_dsc > intf_count);
-}
+ connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
+ if (!connector)
+ return;
+ conn_state = drm_atomic_get_new_connector_state(state, connector);
+ if (!conn_state)
+ return;
-struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
-{
- struct msm_drm_private *priv = drm_enc->dev->dev_private;
- struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
- int index = dpu_enc->disp_info.h_tile_instance[0];
+ disp_info = &dpu_enc->disp_info;
- if (dpu_enc->disp_info.intf_type == INTF_DSI)
- return msm_dsi_get_dsc_config(priv->dsi[index]);
+ priv = drm_enc->dev->dev_private;
- return NULL;
+ /*
+ * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
+ * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
+ * earlier.
+ */
+ if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
+ fb = conn_state->writeback_job->fb;
+
+ if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
+ topology->needs_cdm = true;
+ } else if (disp_info->intf_type == INTF_DP) {
+ if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
+ topology->needs_cdm = true;
+ }
}
-static struct msm_display_topology dpu_encoder_get_topology(
- struct dpu_encoder_virt *dpu_enc,
- struct dpu_kms *dpu_kms,
- struct drm_display_mode *mode,
- struct drm_crtc_state *crtc_state,
- struct drm_dsc_config *dsc)
+static bool dpu_encoder_needs_dsc_merge(struct drm_encoder *drm_enc)
{
- struct msm_display_topology topology = {0};
- int i, intf_count = 0;
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+ u32 num_intf = 0;
+ u32 num_dsc = 0;
+ int i;
for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
if (dpu_enc->phys_encs[i])
- intf_count++;
-
- /* Datapath topology selection
- *
- * Dual display
- * 2 LM, 2 INTF ( Split display using 2 interfaces)
- *
- * Single display
- * 1 LM, 1 INTF
- * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
- *
- * Add dspps to the reservation requirements if ctm is requested
- */
- if (intf_count == 2)
- topology.num_lm = 2;
- else if (!dpu_kms->catalog->caps->has_3d_merge)
- topology.num_lm = 1;
- else
- topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
-
- if (crtc_state->ctm)
- topology.num_dspp = topology.num_lm;
-
- topology.num_intf = intf_count;
+ num_intf++;
- if (dsc) {
- /*
- * In case of Display Stream Compression (DSC), we would use
- * 2 DSC encoders, 2 layer mixers and 1 interface
- * this is power optimal and can drive up to (including) 4k
- * screens
- */
- topology.num_dsc = 2;
- topology.num_lm = 2;
- topology.num_intf = 1;
- }
+ /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
+ if (dpu_enc->dsc)
+ num_dsc += 2;
- return topology;
+ return (num_dsc > 0) && (num_dsc > num_intf);
}
-static int dpu_encoder_virt_atomic_check(
- struct drm_encoder *drm_enc,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
+bool dpu_encoder_needs_modeset(struct drm_encoder *drm_enc, struct drm_atomic_state *state)
{
- struct dpu_encoder_virt *dpu_enc;
- struct msm_drm_private *priv;
- struct dpu_kms *dpu_kms;
- struct drm_display_mode *adj_mode;
- struct msm_display_topology topology;
- struct msm_display_info *disp_info;
- struct dpu_global_state *global_state;
+ struct drm_connector *connector;
+ struct drm_connector_state *conn_state;
struct drm_framebuffer *fb;
- struct drm_dsc_config *dsc;
- int ret = 0;
-
- if (!drm_enc || !crtc_state || !conn_state) {
- DPU_ERROR("invalid arg(s), drm_enc %d, crtc/conn state %d/%d\n",
- drm_enc != NULL, crtc_state != NULL, conn_state != NULL);
- return -EINVAL;
- }
-
- dpu_enc = to_dpu_encoder_virt(drm_enc);
- DPU_DEBUG_ENC(dpu_enc, "\n");
-
- priv = drm_enc->dev->dev_private;
- disp_info = &dpu_enc->disp_info;
- dpu_kms = to_dpu_kms(priv->kms);
- adj_mode = &crtc_state->adjusted_mode;
- global_state = dpu_kms_get_global_state(crtc_state->state);
- if (IS_ERR(global_state))
- return PTR_ERR(global_state);
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
- trace_dpu_enc_atomic_check(DRMID(drm_enc));
+ if (!drm_enc || !state)
+ return false;
- dsc = dpu_encoder_get_dsc_config(drm_enc);
+ connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
+ if (!connector)
+ return false;
- topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
+ conn_state = drm_atomic_get_new_connector_state(state, connector);
- /*
- * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
- * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
- * earlier.
- */
- if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
+ if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
fb = conn_state->writeback_job->fb;
-
- if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
- topology.needs_cdm = true;
- } else if (disp_info->intf_type == INTF_DP) {
- if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
- topology.needs_cdm = true;
+ if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb))) {
+ if (!dpu_enc->cur_master->hw_cdm)
+ return true;
+ } else {
+ if (dpu_enc->cur_master->hw_cdm)
+ return true;
+ }
}
- if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
- crtc_state->mode_changed = true;
- else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
- crtc_state->mode_changed = true;
- /*
- * Release and Allocate resources on every modeset
- * Dont allocate when active is false.
- */
- if (drm_atomic_crtc_needs_modeset(crtc_state)) {
- dpu_rm_release(global_state, crtc_state->crtc);
+ return false;
+}
- if (!crtc_state->active_changed || crtc_state->enable)
- ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
- crtc_state->crtc, &topology);
- }
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
+{
+ struct msm_drm_private *priv = drm_enc->dev->dev_private;
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+ int index = dpu_enc->disp_info.h_tile_instance[0];
- trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
+ if (dpu_enc->disp_info.intf_type == INTF_DSI)
+ return msm_dsi_get_dsc_config(priv->dsi[index]);
- return ret;
+ return NULL;
+}
+
+bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
+{
+ return dpu_encoder_needs_dsc_merge(drm_enc);
}
static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
@@ -2449,7 +2405,6 @@ static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
.atomic_mode_set = dpu_encoder_virt_atomic_mode_set,
.atomic_disable = dpu_encoder_virt_atomic_disable,
.atomic_enable = dpu_encoder_virt_atomic_enable,
- .atomic_check = dpu_encoder_virt_atomic_check,
};
static const struct drm_encoder_funcs dpu_encoder_funcs = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index f7465a1774aa..0d27e50384f0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -169,6 +169,25 @@ int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos);
*/
bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc);
+/**
+ * dpu_encoder_update_topology - update topology with the requirements for the encoder
+ * @drm_enc: Pointer to previously created drm encoder structure
+ * @topology: Topology to be updated
+ * @state: Current DRM atomic state
+ * @adj_mode: Current DRM display mode associated with the crtc
+ */
+void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
+ struct msm_display_topology *topology,
+ struct drm_atomic_state *state,
+ const struct drm_display_mode *adj_mode);
+
+/**
+ * dpu_encoder_update_topology - update topology with the requirements for the encoder
+ * @drm_enc: Pointer to previously created drm encoder structure
+ * @topology: Current DRM atomic state
+ */
+bool dpu_encoder_needs_modeset(struct drm_encoder *drm_enc, struct drm_atomic_state *state);
+
/**
* dpu_encoder_prepare_wb_job - prepare writeback job for the encoder.
* @drm_enc: Pointer to previously created drm encoder structure
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC
2024-09-24 22:59 ` [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC Jessica Zhang
@ 2024-09-24 23:13 ` Dmitry Baryshkov
2024-09-25 20:38 ` Jessica Zhang
0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:13 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:21PM GMT, Jessica Zhang wrote:
> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>
> All resource allocation is centered around the LMs. Then other blocks
> (except DSCs) are allocated basing on the LMs that was selected, and LM
> powers up the CRTC rather than the encoder.
>
> Moreover if at some point the driver supports encoder cloning,
> allocating resources from the encoder will be incorrect, as all clones
> will have different encoder IDs, while LMs are to be shared by these
> encoders.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> [quic_abhinavk@quicinc.com: Refactored resource allocation for CDM]
> Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> [quic_jesszhan@quicinc.com: Changed to grabbing exising global state]
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 86 ++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 +++++++++++-----------------
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++
> 3 files changed, 183 insertions(+), 123 deletions(-)
>
> @@ -544,159 +542,117 @@ void dpu_encoder_helper_split_config(
> }
> }
>
> -bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
> +void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
> + struct msm_display_topology *topology,
> + struct drm_atomic_state *state,
> + const struct drm_display_mode *adj_mode)
> {
> struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> - int i, intf_count = 0, num_dsc = 0;
> + struct drm_connector *connector;
> + struct drm_connector_state *conn_state;
> + struct msm_display_info *disp_info;
> + struct drm_framebuffer *fb;
> + struct msm_drm_private *priv;
> + int i;
>
> for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
> if (dpu_enc->phys_encs[i])
> - intf_count++;
> + topology->num_intf++;
>
> - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
> + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
> if (dpu_enc->dsc)
> - num_dsc = 2;
> + topology->num_dsc += 2;
>
> - return (num_dsc > 0) && (num_dsc > intf_count);
> -}
> + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
> + if (!connector)
> + return;
> + conn_state = drm_atomic_get_new_connector_state(state, connector);
> + if (!conn_state)
> + return;
>
> -struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
> -{
> - struct msm_drm_private *priv = drm_enc->dev->dev_private;
> - struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> - int index = dpu_enc->disp_info.h_tile_instance[0];
> + disp_info = &dpu_enc->disp_info;
>
> - if (dpu_enc->disp_info.intf_type == INTF_DSI)
> - return msm_dsi_get_dsc_config(priv->dsi[index]);
> + priv = drm_enc->dev->dev_private;
>
> - return NULL;
> + /*
> + * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
> + * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
> + * earlier.
> + */
> + if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
> + fb = conn_state->writeback_job->fb;
> +
> + if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
> + topology->needs_cdm = true;
> + } else if (disp_info->intf_type == INTF_DP) {
> + if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
> + topology->needs_cdm = true;
> + }
Just to note, the needs_cdm is not enough once you introduce CWB
support. E.g. DP/YUV420 + WB/YUV case requires two CDM blocks (which we
don't have), but this doesn't get reflected in the topology.
> }
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC
2024-09-24 23:13 ` Dmitry Baryshkov
@ 2024-09-25 20:38 ` Jessica Zhang
2024-09-25 21:11 ` Dmitry Baryshkov
0 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-25 20:38 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On 9/24/2024 4:13 PM, Dmitry Baryshkov wrote:
> On Tue, Sep 24, 2024 at 03:59:21PM GMT, Jessica Zhang wrote:
>> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>
>> All resource allocation is centered around the LMs. Then other blocks
>> (except DSCs) are allocated basing on the LMs that was selected, and LM
>> powers up the CRTC rather than the encoder.
>>
>> Moreover if at some point the driver supports encoder cloning,
>> allocating resources from the encoder will be incorrect, as all clones
>> will have different encoder IDs, while LMs are to be shared by these
>> encoders.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> [quic_abhinavk@quicinc.com: Refactored resource allocation for CDM]
>> Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>> [quic_jesszhan@quicinc.com: Changed to grabbing exising global state]
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 86 ++++++++++++
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 +++++++++++-----------------
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++
>> 3 files changed, 183 insertions(+), 123 deletions(-)
>>
>> @@ -544,159 +542,117 @@ void dpu_encoder_helper_split_config(
>> }
>> }
>>
>> -bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
>> +void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
>> + struct msm_display_topology *topology,
>> + struct drm_atomic_state *state,
>> + const struct drm_display_mode *adj_mode)
>> {
>> struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
>> - int i, intf_count = 0, num_dsc = 0;
>> + struct drm_connector *connector;
>> + struct drm_connector_state *conn_state;
>> + struct msm_display_info *disp_info;
>> + struct drm_framebuffer *fb;
>> + struct msm_drm_private *priv;
>> + int i;
>>
>> for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
>> if (dpu_enc->phys_encs[i])
>> - intf_count++;
>> + topology->num_intf++;
>>
>> - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
>> + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
>> if (dpu_enc->dsc)
>> - num_dsc = 2;
>> + topology->num_dsc += 2;
>>
>> - return (num_dsc > 0) && (num_dsc > intf_count);
>> -}
>> + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
>> + if (!connector)
>> + return;
>> + conn_state = drm_atomic_get_new_connector_state(state, connector);
>> + if (!conn_state)
>> + return;
>>
>> -struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
>> -{
>> - struct msm_drm_private *priv = drm_enc->dev->dev_private;
>> - struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
>> - int index = dpu_enc->disp_info.h_tile_instance[0];
>> + disp_info = &dpu_enc->disp_info;
>>
>> - if (dpu_enc->disp_info.intf_type == INTF_DSI)
>> - return msm_dsi_get_dsc_config(priv->dsi[index]);
>> + priv = drm_enc->dev->dev_private;
>>
>> - return NULL;
>> + /*
>> + * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
>> + * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
>> + * earlier.
>> + */
>> + if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
>> + fb = conn_state->writeback_job->fb;
>> +
>> + if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
>> + topology->needs_cdm = true;
>> + } else if (disp_info->intf_type == INTF_DP) {
>> + if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
>> + topology->needs_cdm = true;
>> + }
>
> Just to note, the needs_cdm is not enough once you introduce CWB
> support. E.g. DP/YUV420 + WB/YUV case requires two CDM blocks (which we
> don't have), but this doesn't get reflected in the topology.
Hi Dmitry,
Ack. I can add something to make atomic_check fail if the input FB is
YUV format and CWB is enabled.
Thanks,
Jessica Zhang
>
>> }
>>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC
2024-09-25 20:38 ` Jessica Zhang
@ 2024-09-25 21:11 ` Dmitry Baryshkov
2024-09-25 21:49 ` Abhinav Kumar
0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-25 21:11 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Wed, 25 Sept 2024 at 22:39, Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>
>
>
> On 9/24/2024 4:13 PM, Dmitry Baryshkov wrote:
> > On Tue, Sep 24, 2024 at 03:59:21PM GMT, Jessica Zhang wrote:
> >> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >>
> >> All resource allocation is centered around the LMs. Then other blocks
> >> (except DSCs) are allocated basing on the LMs that was selected, and LM
> >> powers up the CRTC rather than the encoder.
> >>
> >> Moreover if at some point the driver supports encoder cloning,
> >> allocating resources from the encoder will be incorrect, as all clones
> >> will have different encoder IDs, while LMs are to be shared by these
> >> encoders.
> >>
> >> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >> [quic_abhinavk@quicinc.com: Refactored resource allocation for CDM]
> >> Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> >> [quic_jesszhan@quicinc.com: Changed to grabbing exising global state]
> >> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> >> ---
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 86 ++++++++++++
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 +++++++++++-----------------
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++
> >> 3 files changed, 183 insertions(+), 123 deletions(-)
> >>
> >> @@ -544,159 +542,117 @@ void dpu_encoder_helper_split_config(
> >> }
> >> }
> >>
> >> -bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
> >> +void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
> >> + struct msm_display_topology *topology,
> >> + struct drm_atomic_state *state,
> >> + const struct drm_display_mode *adj_mode)
> >> {
> >> struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> >> - int i, intf_count = 0, num_dsc = 0;
> >> + struct drm_connector *connector;
> >> + struct drm_connector_state *conn_state;
> >> + struct msm_display_info *disp_info;
> >> + struct drm_framebuffer *fb;
> >> + struct msm_drm_private *priv;
> >> + int i;
> >>
> >> for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
> >> if (dpu_enc->phys_encs[i])
> >> - intf_count++;
> >> + topology->num_intf++;
> >>
> >> - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
> >> + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
> >> if (dpu_enc->dsc)
> >> - num_dsc = 2;
> >> + topology->num_dsc += 2;
> >>
> >> - return (num_dsc > 0) && (num_dsc > intf_count);
> >> -}
> >> + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
> >> + if (!connector)
> >> + return;
> >> + conn_state = drm_atomic_get_new_connector_state(state, connector);
> >> + if (!conn_state)
> >> + return;
> >>
> >> -struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
> >> -{
> >> - struct msm_drm_private *priv = drm_enc->dev->dev_private;
> >> - struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> >> - int index = dpu_enc->disp_info.h_tile_instance[0];
> >> + disp_info = &dpu_enc->disp_info;
> >>
> >> - if (dpu_enc->disp_info.intf_type == INTF_DSI)
> >> - return msm_dsi_get_dsc_config(priv->dsi[index]);
> >> + priv = drm_enc->dev->dev_private;
> >>
> >> - return NULL;
> >> + /*
> >> + * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
> >> + * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
> >> + * earlier.
> >> + */
> >> + if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
> >> + fb = conn_state->writeback_job->fb;
> >> +
> >> + if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
> >> + topology->needs_cdm = true;
> >> + } else if (disp_info->intf_type == INTF_DP) {
> >> + if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
> >> + topology->needs_cdm = true;
> >> + }
> >
> > Just to note, the needs_cdm is not enough once you introduce CWB
> > support. E.g. DP/YUV420 + WB/YUV case requires two CDM blocks (which we
> > don't have), but this doesn't get reflected in the topology.
>
> Hi Dmitry,
>
> Ack. I can add something to make atomic_check fail if the input FB is
> YUV format and CWB is enabled.
I'd prefer for this to be more natural rather than just checking for
the DP && DP_YUV420 && WB && WB_FMT_YUV. In the worst case, count CDM
requests and then in RM check them against the catalog. But I had a
more logical (although more intrusive) implementation on my mind:
struct msm_display_topology {
struct {
u32 num_intf;
u32 num_wb;
u32 num_dsc;
bool needs_cdm;
} outputs[MAX_OUTPUTS];
u32 num_lm;
};
WDYT?
>
> Thanks,
>
> Jessica Zhang
>
> >
> >> }
> >>
> > --
> > With best wishes
> > Dmitry
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC
2024-09-25 21:11 ` Dmitry Baryshkov
@ 2024-09-25 21:49 ` Abhinav Kumar
2024-09-26 7:12 ` Dmitry Baryshkov
0 siblings, 1 reply; 64+ messages in thread
From: Abhinav Kumar @ 2024-09-25 21:49 UTC (permalink / raw)
To: Dmitry Baryshkov, Jessica Zhang
Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 9/25/2024 2:11 PM, Dmitry Baryshkov wrote:
> On Wed, 25 Sept 2024 at 22:39, Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>>
>>
>>
>> On 9/24/2024 4:13 PM, Dmitry Baryshkov wrote:
>>> On Tue, Sep 24, 2024 at 03:59:21PM GMT, Jessica Zhang wrote:
>>>> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>
>>>> All resource allocation is centered around the LMs. Then other blocks
>>>> (except DSCs) are allocated basing on the LMs that was selected, and LM
>>>> powers up the CRTC rather than the encoder.
>>>>
>>>> Moreover if at some point the driver supports encoder cloning,
>>>> allocating resources from the encoder will be incorrect, as all clones
>>>> will have different encoder IDs, while LMs are to be shared by these
>>>> encoders.
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> [quic_abhinavk@quicinc.com: Refactored resource allocation for CDM]
>>>> Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>> [quic_jesszhan@quicinc.com: Changed to grabbing exising global state]
>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>> ---
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 86 ++++++++++++
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 +++++++++++-----------------
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++
>>>> 3 files changed, 183 insertions(+), 123 deletions(-)
>>>>
>>>> @@ -544,159 +542,117 @@ void dpu_encoder_helper_split_config(
>>>> }
>>>> }
>>>>
>>>> -bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
>>>> +void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
>>>> + struct msm_display_topology *topology,
>>>> + struct drm_atomic_state *state,
>>>> + const struct drm_display_mode *adj_mode)
>>>> {
>>>> struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
>>>> - int i, intf_count = 0, num_dsc = 0;
>>>> + struct drm_connector *connector;
>>>> + struct drm_connector_state *conn_state;
>>>> + struct msm_display_info *disp_info;
>>>> + struct drm_framebuffer *fb;
>>>> + struct msm_drm_private *priv;
>>>> + int i;
>>>>
>>>> for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
>>>> if (dpu_enc->phys_encs[i])
>>>> - intf_count++;
>>>> + topology->num_intf++;
>>>>
>>>> - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
>>>> + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
>>>> if (dpu_enc->dsc)
>>>> - num_dsc = 2;
>>>> + topology->num_dsc += 2;
>>>>
>>>> - return (num_dsc > 0) && (num_dsc > intf_count);
>>>> -}
>>>> + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
>>>> + if (!connector)
>>>> + return;
>>>> + conn_state = drm_atomic_get_new_connector_state(state, connector);
>>>> + if (!conn_state)
>>>> + return;
>>>>
>>>> -struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
>>>> -{
>>>> - struct msm_drm_private *priv = drm_enc->dev->dev_private;
>>>> - struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
>>>> - int index = dpu_enc->disp_info.h_tile_instance[0];
>>>> + disp_info = &dpu_enc->disp_info;
>>>>
>>>> - if (dpu_enc->disp_info.intf_type == INTF_DSI)
>>>> - return msm_dsi_get_dsc_config(priv->dsi[index]);
>>>> + priv = drm_enc->dev->dev_private;
>>>>
>>>> - return NULL;
>>>> + /*
>>>> + * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
>>>> + * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
>>>> + * earlier.
>>>> + */
>>>> + if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
>>>> + fb = conn_state->writeback_job->fb;
>>>> +
>>>> + if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
>>>> + topology->needs_cdm = true;
>>>> + } else if (disp_info->intf_type == INTF_DP) {
>>>> + if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
>>>> + topology->needs_cdm = true;
>>>> + }
>>>
>>> Just to note, the needs_cdm is not enough once you introduce CWB
>>> support. E.g. DP/YUV420 + WB/YUV case requires two CDM blocks (which we
>>> don't have), but this doesn't get reflected in the topology.
>>
>> Hi Dmitry,
>>
>> Ack. I can add something to make atomic_check fail if the input FB is
>> YUV format and CWB is enabled.
>
> I'd prefer for this to be more natural rather than just checking for
> the DP && DP_YUV420 && WB && WB_FMT_YUV. In the worst case, count CDM
> requests and then in RM check them against the catalog. But I had a
> more logical (although more intrusive) implementation on my mind:
>
> struct msm_display_topology {
> struct {
> u32 num_intf;
> u32 num_wb;
> u32 num_dsc;
> bool needs_cdm;
> } outputs[MAX_OUTPUTS];
> u32 num_lm;
> };
>
> WDYT?
>
the struct msm_display_topology was originally designed as a per-encoder
struct (dpu_encoder_get_topology() indicates the same). Making this an
array of outputs was not needed as there is expected to be one struct
msm_display_topology for each virt encoder's requested topology and the
blocks inside of it other than LM, are "encoder" hw blocks.
needs_cdm was made a boolean instead of a num_cdm_count like other
hardware blocks because till the most recent chipset, we have only one
CDM block. Whenever we do have more CDM blocks why will introducing
num_cdm to the topology struct not solve your problem rather than making
it an array of outputs?
Because then, RM will know that the request exceeds the max blocks.
I think what you are trying to do now is make struct
msm_display_topology's encoder parts per-encoder and rest like num_lm
per "RM session".
The thought is not wrong but at the same time seems a bit of an overkill
because its mostly already like that. Apart from CDM for which I have no
indication of another one getting added, rest of the blocks are already
aligned towards a per-encoder model and not a "RM session" model.
Even if we end up doing it this way, most of the model is kind of unused
really because each encoder will request its own topology anyway, there
is just no aggregation for CDM which at this point is not needed as
there is no HW we are aware of needing this.
I think the atomic_check validation is needed either way because if two
encoders request cdm, we cannot do clone mode as there is only one cdm
block today. Its just that we are not tracking num_cdm today due to
reasons explained above but basically doing something like below seems
right to me:
if (enc_is_in_clone_mode && needs_cdm)
return -ENOTSUPPORTED;
When we add more cdm_blocks, we can drop this check and making needs_cdm
a num_cdm will make it naturally fail.
>>
>> Thanks,
>>
>> Jessica Zhang
>>
>>>
>>>> }
>>>>
>>> --
>>> With best wishes
>>> Dmitry
>>
>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC
2024-09-25 21:49 ` Abhinav Kumar
@ 2024-09-26 7:12 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-26 7:12 UTC (permalink / raw)
To: Abhinav Kumar
Cc: Jessica Zhang, Rob Clark, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Wed, Sep 25, 2024 at 02:49:48PM GMT, Abhinav Kumar wrote:
> On 9/25/2024 2:11 PM, Dmitry Baryshkov wrote:
> > On Wed, 25 Sept 2024 at 22:39, Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> > > On 9/24/2024 4:13 PM, Dmitry Baryshkov wrote:
> > > > On Tue, Sep 24, 2024 at 03:59:21PM GMT, Jessica Zhang wrote:
> > > > > From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > > >
> > > > > All resource allocation is centered around the LMs. Then other blocks
> > > > > (except DSCs) are allocated basing on the LMs that was selected, and LM
> > > > > powers up the CRTC rather than the encoder.
> > > > >
> > > > > Moreover if at some point the driver supports encoder cloning,
> > > > > allocating resources from the encoder will be incorrect, as all clones
> > > > > will have different encoder IDs, while LMs are to be shared by these
> > > > > encoders.
> > > > >
> > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > > > [quic_abhinavk@quicinc.com: Refactored resource allocation for CDM]
> > > > > Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> > > > > [quic_jesszhan@quicinc.com: Changed to grabbing exising global state]
> > > > > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > > > > ---
> > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 86 ++++++++++++
> > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 201 +++++++++++-----------------
> > > > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 19 +++
> > > > > 3 files changed, 183 insertions(+), 123 deletions(-)
> > > > >
> > > > > @@ -544,159 +542,117 @@ void dpu_encoder_helper_split_config(
> > > > > }
> > > > > }
> > > > >
> > > > > -bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
> > > > > +void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
> > > > > + struct msm_display_topology *topology,
> > > > > + struct drm_atomic_state *state,
> > > > > + const struct drm_display_mode *adj_mode)
> > > > > {
> > > > > struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> > > > > - int i, intf_count = 0, num_dsc = 0;
> > > > > + struct drm_connector *connector;
> > > > > + struct drm_connector_state *conn_state;
> > > > > + struct msm_display_info *disp_info;
> > > > > + struct drm_framebuffer *fb;
> > > > > + struct msm_drm_private *priv;
> > > > > + int i;
> > > > >
> > > > > for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
> > > > > if (dpu_enc->phys_encs[i])
> > > > > - intf_count++;
> > > > > + topology->num_intf++;
> > > > >
> > > > > - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
> > > > > + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */
> > > > > if (dpu_enc->dsc)
> > > > > - num_dsc = 2;
> > > > > + topology->num_dsc += 2;
> > > > >
> > > > > - return (num_dsc > 0) && (num_dsc > intf_count);
> > > > > -}
> > > > > + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
> > > > > + if (!connector)
> > > > > + return;
> > > > > + conn_state = drm_atomic_get_new_connector_state(state, connector);
> > > > > + if (!conn_state)
> > > > > + return;
> > > > >
> > > > > -struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
> > > > > -{
> > > > > - struct msm_drm_private *priv = drm_enc->dev->dev_private;
> > > > > - struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> > > > > - int index = dpu_enc->disp_info.h_tile_instance[0];
> > > > > + disp_info = &dpu_enc->disp_info;
> > > > >
> > > > > - if (dpu_enc->disp_info.intf_type == INTF_DSI)
> > > > > - return msm_dsi_get_dsc_config(priv->dsi[index]);
> > > > > + priv = drm_enc->dev->dev_private;
> > > > >
> > > > > - return NULL;
> > > > > + /*
> > > > > + * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
> > > > > + * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
> > > > > + * earlier.
> > > > > + */
> > > > > + if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
> > > > > + fb = conn_state->writeback_job->fb;
> > > > > +
> > > > > + if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb)))
> > > > > + topology->needs_cdm = true;
> > > > > + } else if (disp_info->intf_type == INTF_DP) {
> > > > > + if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
> > > > > + topology->needs_cdm = true;
> > > > > + }
> > > >
> > > > Just to note, the needs_cdm is not enough once you introduce CWB
> > > > support. E.g. DP/YUV420 + WB/YUV case requires two CDM blocks (which we
> > > > don't have), but this doesn't get reflected in the topology.
> > >
> > > Hi Dmitry,
> > >
> > > Ack. I can add something to make atomic_check fail if the input FB is
> > > YUV format and CWB is enabled.
> >
> > I'd prefer for this to be more natural rather than just checking for
> > the DP && DP_YUV420 && WB && WB_FMT_YUV. In the worst case, count CDM
> > requests and then in RM check them against the catalog. But I had a
> > more logical (although more intrusive) implementation on my mind:
> >
> > struct msm_display_topology {
> > struct {
> > u32 num_intf;
> > u32 num_wb;
> > u32 num_dsc;
> > bool needs_cdm;
> > } outputs[MAX_OUTPUTS];
> > u32 num_lm;
> > };
> >
> > WDYT?
> >
>
> the struct msm_display_topology was originally designed as a per-encoder
> struct (dpu_encoder_get_topology() indicates the same). Making this an array
> of outputs was not needed as there is expected to be one struct
> msm_display_topology for each virt encoder's requested topology and the
> blocks inside of it other than LM, are "encoder" hw blocks.
>
> needs_cdm was made a boolean instead of a num_cdm_count like other hardware
> blocks because till the most recent chipset, we have only one CDM block.
> Whenever we do have more CDM blocks why will introducing num_cdm to the
> topology struct not solve your problem rather than making it an array of
> outputs?
>
> Because then, RM will know that the request exceeds the max blocks.
>
> I think what you are trying to do now is make struct msm_display_topology's
> encoder parts per-encoder and rest like num_lm per "RM session".
>
> The thought is not wrong but at the same time seems a bit of an overkill
> because its mostly already like that. Apart from CDM for which I have no
> indication of another one getting added, rest of the blocks are already
> aligned towards a per-encoder model and not a "RM session" model.
But we should be leaning towards RM session.
>
> Even if we end up doing it this way, most of the model is kind of unused
> really because each encoder will request its own topology anyway, there is
> just no aggregation for CDM which at this point is not needed as there is no
> HW we are aware of needing this.
With the resource allocation shifted to the CRTC individual encoders
do not request their own topology (as it is now a property of the full
output pipeline, not just an encoder). Yes, CDM aggregation into num_cdm
seems unnecessary as there is just one CDM block.
> I think the atomic_check validation is needed either way because if two
> encoders request cdm, we cannot do clone mode as there is only one cdm block
> today. Its just that we are not tracking num_cdm today due to reasons
> explained above but basically doing something like below seems right to me:
>
> if (enc_is_in_clone_mode && needs_cdm)
> return -ENOTSUPPORTED;
This check is incorrect in my opinion. The hardware should be able to
support DP/YUV420 + WB/RGB and DP/RGB + WB/YUV combinations. Please
correct me if I'm wrong.
> When we add more cdm_blocks, we can drop this check and making needs_cdm a
> num_cdm will make it naturally fail.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (4 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 05/22] drm/msm/dpu: move resource allocation to CRTC Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:16 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 07/22] drm/msm/dpu: Add CWB entry to catalog for SM8650 Jessica Zhang
` (15 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Stop poking into CRTC state from dpu_encoder.c, fill CRTC HW resources
from dpu_crtc_assign_resources().
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
[quic_abhinavk@quicinc.com: cleaned up formatting]
Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
[quic_jesszhan@quicinc.com: dropped clearing num_mixers in CRTC disable
path]
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 32 ++++++++++++++++++++++++++---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++--------------------
2 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b918c80d30b3..d53e986eee54 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1091,9 +1091,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
dpu_core_perf_crtc_update(crtc, 0);
- memset(cstate->mixers, 0, sizeof(cstate->mixers));
- cstate->num_mixers = 0;
-
/* disable clk & bw control until clk & bw properties are set */
cstate->bw_control = false;
cstate->bw_split_vote = false;
@@ -1164,6 +1161,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
}
#define MAX_HDISPLAY_SPLIT 1080
+#define MAX_CHANNELS_PER_CRTC 2
static struct msm_display_topology dpu_crtc_get_topology(
struct drm_crtc *crtc,
@@ -1208,9 +1206,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
{
+ struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC];
+ struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC];
+ struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC];
+ int i, num_lm, num_ctl, num_dspp;
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
struct dpu_global_state *global_state;
struct msm_display_topology topology;
+ struct dpu_crtc_state *cstate;
int ret;
/*
@@ -1232,6 +1235,29 @@ static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_stat
if (ret)
return ret;
+ cstate = to_dpu_crtc_state(crtc_state);
+
+ num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ crtc, DPU_HW_BLK_CTL, hw_ctl,
+ ARRAY_SIZE(hw_ctl));
+ num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ crtc, DPU_HW_BLK_LM, hw_lm,
+ ARRAY_SIZE(hw_lm));
+ num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ crtc, DPU_HW_BLK_DSPP, hw_dspp,
+ ARRAY_SIZE(hw_dspp));
+
+ for (i = 0; i < num_lm; i++) {
+ int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
+
+ cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
+ cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
+ if (i < num_dspp)
+ cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
+ }
+
+ cstate->num_mixers = num_lm;
+
return 0;
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index ada9119326ca..36b677cf9c7a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1049,14 +1049,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
struct dpu_encoder_virt *dpu_enc;
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms;
- struct dpu_crtc_state *cstate;
struct dpu_global_state *global_state;
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
- struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
- struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
- int num_lm, num_ctl, num_pp, num_dsc;
+ int num_pp, num_dsc;
unsigned int dsc_mask = 0;
int i;
@@ -1083,13 +1080,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
ARRAY_SIZE(hw_pp));
- num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
- num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
- ARRAY_SIZE(hw_dspp));
+ drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1115,18 +1107,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
}
- cstate = to_dpu_crtc_state(crtc_state);
-
- for (i = 0; i < num_lm; i++) {
- int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
-
- cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
- cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
- cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
- }
-
- cstate->num_mixers = num_lm;
-
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c
2024-09-24 22:59 ` [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c Jessica Zhang
@ 2024-09-24 23:16 ` Dmitry Baryshkov
2024-09-25 0:37 ` Jessica Zhang
0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:16 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:22PM GMT, Jessica Zhang wrote:
> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>
> Stop poking into CRTC state from dpu_encoder.c, fill CRTC HW resources
> from dpu_crtc_assign_resources().
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> [quic_abhinavk@quicinc.com: cleaned up formatting]
> Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> [quic_jesszhan@quicinc.com: dropped clearing num_mixers in CRTC disable
> path]
Same comment as before: the code is still there.
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 32 ++++++++++++++++++++++++++---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++--------------------
> 2 files changed, 31 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index b918c80d30b3..d53e986eee54 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1091,9 +1091,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
>
> dpu_core_perf_crtc_update(crtc, 0);
>
> - memset(cstate->mixers, 0, sizeof(cstate->mixers));
> - cstate->num_mixers = 0;
> -
> /* disable clk & bw control until clk & bw properties are set */
> cstate->bw_control = false;
> cstate->bw_split_vote = false;
> @@ -1164,6 +1161,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
> }
>
> #define MAX_HDISPLAY_SPLIT 1080
> +#define MAX_CHANNELS_PER_CRTC 2
>
> static struct msm_display_topology dpu_crtc_get_topology(
> struct drm_crtc *crtc,
> @@ -1208,9 +1206,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
>
> static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
> {
> + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC];
> + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC];
> + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC];
> + int i, num_lm, num_ctl, num_dspp;
> struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
> struct dpu_global_state *global_state;
> struct msm_display_topology topology;
> + struct dpu_crtc_state *cstate;
> int ret;
>
> /*
> @@ -1232,6 +1235,29 @@ static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_stat
> if (ret)
> return ret;
>
> + cstate = to_dpu_crtc_state(crtc_state);
> +
> + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + crtc, DPU_HW_BLK_CTL, hw_ctl,
> + ARRAY_SIZE(hw_ctl));
> + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + crtc, DPU_HW_BLK_LM, hw_lm,
> + ARRAY_SIZE(hw_lm));
> + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + crtc, DPU_HW_BLK_DSPP, hw_dspp,
> + ARRAY_SIZE(hw_dspp));
> +
> + for (i = 0; i < num_lm; i++) {
> + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
> +
> + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
> + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
> + if (i < num_dspp)
> + cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
> + }
> +
> + cstate->num_mixers = num_lm;
> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index ada9119326ca..36b677cf9c7a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -1049,14 +1049,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> struct dpu_encoder_virt *dpu_enc;
> struct msm_drm_private *priv;
> struct dpu_kms *dpu_kms;
> - struct dpu_crtc_state *cstate;
> struct dpu_global_state *global_state;
> struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
> - struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> - struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
> struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
> - int num_lm, num_ctl, num_pp, num_dsc;
> + int num_pp, num_dsc;
> unsigned int dsc_mask = 0;
> int i;
>
> @@ -1083,13 +1080,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
> ARRAY_SIZE(hw_pp));
> - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> - drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
> - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> - drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> - drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
> - ARRAY_SIZE(hw_dspp));
> + drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
Please don't mix reindentation with the actual changes. It makes it
harder to read.
>
> for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
> dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
> @@ -1115,18 +1107,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
> }
>
> - cstate = to_dpu_crtc_state(crtc_state);
> -
> - for (i = 0; i < num_lm; i++) {
> - int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
> -
> - cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
> - cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
> - cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
> - }
> -
> - cstate->num_mixers = num_lm;
> -
> for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
>
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c
2024-09-24 23:16 ` Dmitry Baryshkov
@ 2024-09-25 0:37 ` Jessica Zhang
2024-09-25 8:17 ` Dmitry Baryshkov
0 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-25 0:37 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On 9/24/2024 4:16 PM, Dmitry Baryshkov wrote:
> On Tue, Sep 24, 2024 at 03:59:22PM GMT, Jessica Zhang wrote:
>> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>
>> Stop poking into CRTC state from dpu_encoder.c, fill CRTC HW resources
>> from dpu_crtc_assign_resources().
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> [quic_abhinavk@quicinc.com: cleaned up formatting]
>> Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>> [quic_jesszhan@quicinc.com: dropped clearing num_mixers in CRTC disable
>> path]
>
> Same comment as before: the code is still there.
Hi Dmitry,
I thought the original comment was to move the dropping `num_mixers = 0`
chunk from the previous patch to this one?
Sorry if I misunderstood.
Thanks,
Jessica Zhang
>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 32 ++++++++++++++++++++++++++---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++--------------------
>> 2 files changed, 31 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index b918c80d30b3..d53e986eee54 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -1091,9 +1091,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
>>
>> dpu_core_perf_crtc_update(crtc, 0);
>>
>> - memset(cstate->mixers, 0, sizeof(cstate->mixers));
>> - cstate->num_mixers = 0;
>> -
>> /* disable clk & bw control until clk & bw properties are set */
>> cstate->bw_control = false;
>> cstate->bw_split_vote = false;
>> @@ -1164,6 +1161,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
>> }
>>
>> #define MAX_HDISPLAY_SPLIT 1080
>> +#define MAX_CHANNELS_PER_CRTC 2
>>
>> static struct msm_display_topology dpu_crtc_get_topology(
>> struct drm_crtc *crtc,
>> @@ -1208,9 +1206,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
>>
>> static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
>> {
>> + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC];
>> + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC];
>> + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC];
>> + int i, num_lm, num_ctl, num_dspp;
>> struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>> struct dpu_global_state *global_state;
>> struct msm_display_topology topology;
>> + struct dpu_crtc_state *cstate;
>> int ret;
>>
>> /*
>> @@ -1232,6 +1235,29 @@ static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_stat
>> if (ret)
>> return ret;
>>
>> + cstate = to_dpu_crtc_state(crtc_state);
>> +
>> + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> + crtc, DPU_HW_BLK_CTL, hw_ctl,
>> + ARRAY_SIZE(hw_ctl));
>> + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> + crtc, DPU_HW_BLK_LM, hw_lm,
>> + ARRAY_SIZE(hw_lm));
>> + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> + crtc, DPU_HW_BLK_DSPP, hw_dspp,
>> + ARRAY_SIZE(hw_dspp));
>> +
>> + for (i = 0; i < num_lm; i++) {
>> + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
>> +
>> + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
>> + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
>> + if (i < num_dspp)
>> + cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
>> + }
>> +
>> + cstate->num_mixers = num_lm;
>> +
>> return 0;
>> }
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> index ada9119326ca..36b677cf9c7a 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> @@ -1049,14 +1049,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> struct dpu_encoder_virt *dpu_enc;
>> struct msm_drm_private *priv;
>> struct dpu_kms *dpu_kms;
>> - struct dpu_crtc_state *cstate;
>> struct dpu_global_state *global_state;
>> struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
>> struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
>> - struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
>> - struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
>> struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
>> - int num_lm, num_ctl, num_pp, num_dsc;
>> + int num_pp, num_dsc;
>> unsigned int dsc_mask = 0;
>> int i;
>>
>> @@ -1083,13 +1080,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
>> ARRAY_SIZE(hw_pp));
>> - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> - drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
>> - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> - drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
>> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> - drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
>> - ARRAY_SIZE(hw_dspp));
>> + drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
>
> Please don't mix reindentation with the actual changes. It makes it
> harder to read.
>
>>
>> for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
>> dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
>> @@ -1115,18 +1107,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
>> }
>>
>> - cstate = to_dpu_crtc_state(crtc_state);
>> -
>> - for (i = 0; i < num_lm; i++) {
>> - int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
>> -
>> - cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
>> - cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
>> - cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
>> - }
>> -
>> - cstate->num_mixers = num_lm;
>> -
>> for (i = 0; i < dpu_enc->num_phys_encs; i++) {
>> struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
>>
>>
>> --
>> 2.34.1
>>
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c
2024-09-25 0:37 ` Jessica Zhang
@ 2024-09-25 8:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-25 8:17 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 05:37:30PM GMT, Jessica Zhang wrote:
>
>
> On 9/24/2024 4:16 PM, Dmitry Baryshkov wrote:
> > On Tue, Sep 24, 2024 at 03:59:22PM GMT, Jessica Zhang wrote:
> > > From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > >
> > > Stop poking into CRTC state from dpu_encoder.c, fill CRTC HW resources
> > > from dpu_crtc_assign_resources().
> > >
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > [quic_abhinavk@quicinc.com: cleaned up formatting]
> > > Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> > > [quic_jesszhan@quicinc.com: dropped clearing num_mixers in CRTC disable
> > > path]
> >
> > Same comment as before: the code is still there.
>
> Hi Dmitry,
>
> I thought the original comment was to move the dropping `num_mixers = 0`
> chunk from the previous patch to this one?
>
> Sorry if I misunderstood.
Code move is fine. The commit message should reflect the code though. So
if you have "dropped clearing num_mixers..." in the commit message, it
is surprising to see the code actually claring num_mixers.
>
> Thanks,
>
> Jessica Zhang
>
> >
> > > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > > ---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 32 ++++++++++++++++++++++++++---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++--------------------
> > > 2 files changed, 31 insertions(+), 25 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > index b918c80d30b3..d53e986eee54 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > @@ -1091,9 +1091,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
> > > dpu_core_perf_crtc_update(crtc, 0);
> > > - memset(cstate->mixers, 0, sizeof(cstate->mixers));
> > > - cstate->num_mixers = 0;
> > > -
> > > /* disable clk & bw control until clk & bw properties are set */
> > > cstate->bw_control = false;
> > > cstate->bw_split_vote = false;
> > > @@ -1164,6 +1161,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
> > > }
> > > #define MAX_HDISPLAY_SPLIT 1080
> > > +#define MAX_CHANNELS_PER_CRTC 2
> > > static struct msm_display_topology dpu_crtc_get_topology(
> > > struct drm_crtc *crtc,
> > > @@ -1208,9 +1206,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
> > > static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
> > > {
> > > + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC];
> > > + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC];
> > > + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC];
> > > + int i, num_lm, num_ctl, num_dspp;
> > > struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
> > > struct dpu_global_state *global_state;
> > > struct msm_display_topology topology;
> > > + struct dpu_crtc_state *cstate;
> > > int ret;
> > > /*
> > > @@ -1232,6 +1235,29 @@ static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_stat
> > > if (ret)
> > > return ret;
> > > + cstate = to_dpu_crtc_state(crtc_state);
> > > +
> > > + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > + crtc, DPU_HW_BLK_CTL, hw_ctl,
> > > + ARRAY_SIZE(hw_ctl));
> > > + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > + crtc, DPU_HW_BLK_LM, hw_lm,
> > > + ARRAY_SIZE(hw_lm));
> > > + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > + crtc, DPU_HW_BLK_DSPP, hw_dspp,
> > > + ARRAY_SIZE(hw_dspp));
> > > +
> > > + for (i = 0; i < num_lm; i++) {
> > > + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
> > > +
> > > + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
> > > + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
> > > + if (i < num_dspp)
> > > + cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
> > > + }
> > > +
> > > + cstate->num_mixers = num_lm;
> > > +
> > > return 0;
> > > }
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > index ada9119326ca..36b677cf9c7a 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > @@ -1049,14 +1049,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> > > struct dpu_encoder_virt *dpu_enc;
> > > struct msm_drm_private *priv;
> > > struct dpu_kms *dpu_kms;
> > > - struct dpu_crtc_state *cstate;
> > > struct dpu_global_state *global_state;
> > > struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
> > > struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
> > > - struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> > > - struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
> > > struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
> > > - int num_lm, num_ctl, num_pp, num_dsc;
> > > + int num_pp, num_dsc;
> > > unsigned int dsc_mask = 0;
> > > int i;
> > > @@ -1083,13 +1080,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> > > num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
> > > ARRAY_SIZE(hw_pp));
> > > - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > - drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
> > > - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > - drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
> > > dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> > > - drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
> > > - ARRAY_SIZE(hw_dspp));
> > > + drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
> >
> > Please don't mix reindentation with the actual changes. It makes it
> > harder to read.
> >
> > > for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
> > > dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
> > > @@ -1115,18 +1107,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> > > dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
> > > }
> > > - cstate = to_dpu_crtc_state(crtc_state);
> > > -
> > > - for (i = 0; i < num_lm; i++) {
> > > - int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
> > > -
> > > - cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
> > > - cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
> > > - cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
> > > - }
> > > -
> > > - cstate->num_mixers = num_lm;
> > > -
> > > for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> > > struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
> > >
> > > --
> > > 2.34.1
> > >
> >
> > --
> > With best wishes
> > Dmitry
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 07/22] drm/msm/dpu: Add CWB entry to catalog for SM8650
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (5 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 06/22] drm/msm/dpu: fill CRTC resources in dpu_crtc.c Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:17 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 08/22] drm/msm/dpu: Specify dedicated CWB pingpong blocks Jessica Zhang
` (14 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Add a new block for concurrent writeback mux to the SM8650 HW catalog
Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
.../gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 21 +++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 13 +++++++++++++
2 files changed, 34 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
index eb5dfff2ec4f..33f5faf4833f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
@@ -350,6 +350,25 @@ static const struct dpu_wb_cfg sm8650_wb[] = {
},
};
+static const struct dpu_cwb_cfg sm8650_cwb[] = {
+ {
+ .name = "cwb_0", .id = CWB_0,
+ .base = 0x66200, .len = 0x8,
+ },
+ {
+ .name = "cwb_1", .id = CWB_1,
+ .base = 0x66600, .len = 0x8,
+ },
+ {
+ .name = "cwb_2", .id = CWB_2,
+ .base = 0x7E200, .len = 0x8,
+ },
+ {
+ .name = "cwb_3", .id = CWB_3,
+ .base = 0x7E600, .len = 0x8,
+ },
+};
+
static const struct dpu_intf_cfg sm8650_intf[] = {
{
.name = "intf_0", .id = INTF_0,
@@ -447,6 +466,8 @@ const struct dpu_mdss_cfg dpu_sm8650_cfg = {
.merge_3d = sm8650_merge_3d,
.wb_count = ARRAY_SIZE(sm8650_wb),
.wb = sm8650_wb,
+ .cwb_count = ARRAY_SIZE(sm8650_cwb),
+ .cwb = sm8650_cwb,
.intf_count = ARRAY_SIZE(sm8650_intf),
.intf = sm8650_intf,
.vbif_count = ARRAY_SIZE(sm8650_vbif),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 37e18e820a20..b42d8b3640e2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -621,6 +621,16 @@ struct dpu_wb_cfg {
enum dpu_clk_ctrl_type clk_ctrl;
};
+/*
+ * struct dpu_cwb_cfg : MDP CWB mux instance info
+ * @id: enum identifying this block
+ * @base: register base offset to mdss
+ * @features bit mask identifying sub-blocks/features
+ */
+struct dpu_cwb_cfg {
+ DPU_HW_BLK_INFO;
+};
+
/**
* struct dpu_vbif_dynamic_ot_cfg - dynamic OT setting
* @pps pixel per seconds
@@ -823,6 +833,9 @@ struct dpu_mdss_cfg {
u32 dspp_count;
const struct dpu_dspp_cfg *dspp;
+ u32 cwb_count;
+ const struct dpu_cwb_cfg *cwb;
+
/* Add additional block data structures here */
const struct dpu_perf_cfg *perf;
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 07/22] drm/msm/dpu: Add CWB entry to catalog for SM8650
2024-09-24 22:59 ` [PATCH v2 07/22] drm/msm/dpu: Add CWB entry to catalog for SM8650 Jessica Zhang
@ 2024-09-24 23:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:17 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:23PM GMT, Jessica Zhang wrote:
> From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
>
> Add a new block for concurrent writeback mux to the SM8650 HW catalog
>
> Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 21 +++++++++++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 13 +++++++++++++
> 2 files changed, 34 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 08/22] drm/msm/dpu: Specify dedicated CWB pingpong blocks
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (6 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 07/22] drm/msm/dpu: Add CWB entry to catalog for SM8650 Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:17 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 09/22] drm/msm/dpu: add devcoredumps for cwb registers Jessica Zhang
` (13 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Change pingpong index and names to distinguish between general use
pingpong blocks and pingpong blocks dedicated for concurrent writeback
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 8 ++++----
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 ++--
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 ++--
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h | 4 ++--
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 8 ++++----
5 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
index 33f5faf4833f..bfb64b7c1a47 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
@@ -252,25 +252,25 @@ static const struct dpu_pingpong_cfg sm8650_pp[] = {
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
}, {
- .name = "pingpong_6", .id = PINGPONG_6,
+ .name = "pingpong_cwb_0", .id = PINGPONG_CWB_0,
.base = 0x66000, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
- .name = "pingpong_7", .id = PINGPONG_7,
+ .name = "pingpong_cwb_1", .id = PINGPONG_CWB_1,
.base = 0x66400, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
- .name = "pingpong_8", .id = PINGPONG_8,
+ .name = "pingpong_cwb_2", .id = PINGPONG_CWB_2,
.base = 0x7e000, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_4,
}, {
- .name = "pingpong_9", .id = PINGPONG_9,
+ .name = "pingpong_cwb_3", .id = PINGPONG_CWB_3,
.base = 0x7e400, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h
index a1779c5597ae..08742472f9cc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h
@@ -257,13 +257,13 @@ static const struct dpu_pingpong_cfg sm8450_pp[] = {
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
}, {
- .name = "pingpong_6", .id = PINGPONG_6,
+ .name = "pingpong_cwb_0", .id = PINGPONG_CWB_0,
.base = 0x65800, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
- .name = "pingpong_7", .id = PINGPONG_7,
+ .name = "pingpong_cwb_1", .id = PINGPONG_CWB_1,
.base = 0x65c00, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
index ad48defa154f..173f6f53a30c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
@@ -251,13 +251,13 @@ static const struct dpu_pingpong_cfg sm8550_pp[] = {
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
}, {
- .name = "pingpong_6", .id = PINGPONG_6,
+ .name = "pingpong_cwb_0", .id = PINGPONG_CWB_0,
.base = 0x66000, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
- .name = "pingpong_7", .id = PINGPONG_7,
+ .name = "pingpong_cwb_1", .id = PINGPONG_CWB_1,
.base = 0x66400, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h
index a3e60ac70689..592ba9abd1ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h
@@ -251,13 +251,13 @@ static const struct dpu_pingpong_cfg x1e80100_pp[] = {
.merge_3d = MERGE_3D_2,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
}, {
- .name = "pingpong_6", .id = PINGPONG_6,
+ .name = "pingpong_cwb_0", .id = PINGPONG_CWB_0,
.base = 0x66000, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
- .name = "pingpong_7", .id = PINGPONG_7,
+ .name = "pingpong_cwb_1", .id = PINGPONG_CWB_1,
.base = 0x66400, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index a2eff36a2224..c17d2d356f7a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -181,10 +181,10 @@ enum dpu_pingpong {
PINGPONG_3,
PINGPONG_4,
PINGPONG_5,
- PINGPONG_6,
- PINGPONG_7,
- PINGPONG_8,
- PINGPONG_9,
+ PINGPONG_CWB_0,
+ PINGPONG_CWB_1,
+ PINGPONG_CWB_2,
+ PINGPONG_CWB_3,
PINGPONG_S0,
PINGPONG_MAX
};
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 08/22] drm/msm/dpu: Specify dedicated CWB pingpong blocks
2024-09-24 22:59 ` [PATCH v2 08/22] drm/msm/dpu: Specify dedicated CWB pingpong blocks Jessica Zhang
@ 2024-09-24 23:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:17 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:24PM GMT, Jessica Zhang wrote:
> Change pingpong index and names to distinguish between general use
> pingpong blocks and pingpong blocks dedicated for concurrent writeback
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 8 ++++----
> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 ++--
> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 ++--
> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h | 4 ++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 8 ++++----
> 5 files changed, 14 insertions(+), 14 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 09/22] drm/msm/dpu: add devcoredumps for cwb registers
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (7 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 08/22] drm/msm/dpu: Specify dedicated CWB pingpong blocks Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 10/22] drm/msm/dpu: Add dpu_hw_cwb abstraction for CWB block Jessica Zhang
` (12 subsequent siblings)
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Implement instance of snapshot function to dump new registers used
for cwb
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 9bcae53c4f45..47e304b357e8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -989,6 +989,11 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k
dpu_kms->mmio + cat->mdp[0].base, "top");
}
+ /* dump CWB sub-blocks HW regs info */
+ for (i = 0; i < cat->cwb_count; i++)
+ msm_disp_snapshot_add_block(disp_state, cat->cwb[i].len,
+ dpu_kms->mmio + cat->cwb[i].base, cat->cwb[i].name);
+
/* dump DSC sub-blocks HW regs info */
for (i = 0; i < cat->dsc_count; i++) {
base = dpu_kms->mmio + cat->dsc[i].base;
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 10/22] drm/msm/dpu: Add dpu_hw_cwb abstraction for CWB block
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (8 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 09/22] drm/msm/dpu: add devcoredumps for cwb registers Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:19 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 11/22] drm/msm/dpu: add CWB support to dpu_hw_wb Jessica Zhang
` (11 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
The CWB mux has its own registers and set of operations. Add dpu_hw_cwb
abstraction to allow driver to configure the CWB mux.
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/Makefile | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.c | 73 +++++++++++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.h | 70 +++++++++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 5 +-
4 files changed, 148 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 13110fcc46a8..e05bb740246b 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -77,6 +77,7 @@ msm-display-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_cdm.o \
disp/dpu1/dpu_hw_ctl.o \
+ disp/dpu1/dpu_hw_cwb.o \
disp/dpu1/dpu_hw_dsc.o \
disp/dpu1/dpu_hw_dsc_1_2.o \
disp/dpu1/dpu_hw_interrupts.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.c
new file mode 100644
index 000000000000..5fbf52906ea9
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#include <drm/drm_managed.h>
+#include "dpu_hw_cwb.h"
+
+#define CWB_MUX 0x000
+#define CWB_MODE 0x004
+
+/* CWB mux block bit definitions */
+#define CWB_MUX_MASK GENMASK(3, 0)
+#define CWB_MODE_MASK GENMASK(2, 0)
+
+static void dpu_hw_cwb_config(struct dpu_hw_cwb *ctx,
+ struct dpu_hw_cwb_setup_cfg *cwb_cfg)
+{
+ struct dpu_hw_blk_reg_map *c = &ctx->hw;
+ int cwb_mux_cfg = 0xF;
+ enum dpu_pingpong pp;
+ enum cwb_mode_input input;
+
+ if (!cwb_cfg)
+ return;
+
+ input = cwb_cfg->input;
+ pp = cwb_cfg->pp_idx;
+
+ if (input >= INPUT_MODE_MAX)
+ return;
+
+ /*
+ * The CWB_MUX register takes the pingpong index for the real-time
+ * display
+ */
+ if ((pp != PINGPONG_NONE) && (pp < PINGPONG_MAX))
+ cwb_mux_cfg = FIELD_PREP(CWB_MUX_MASK, pp - PINGPONG_0);
+
+ input = FIELD_PREP(CWB_MODE_MASK, input);
+
+ DPU_REG_WRITE(c, CWB_MUX, cwb_mux_cfg);
+ DPU_REG_WRITE(c, CWB_MODE, input);
+}
+
+/**
+ * dpu_hw_cwb_init() - Initializes the writeback hw driver object with cwb.
+ * @dev: Corresponding device for devres management
+ * @cfg: wb_path catalog entry for which driver object is required
+ * @addr: mapped register io address of MDP
+ * Return: Error code or allocated dpu_hw_wb context
+ */
+struct dpu_hw_cwb *dpu_hw_cwb_init(struct drm_device *dev,
+ const struct dpu_cwb_cfg *cfg,
+ void __iomem *addr)
+{
+ struct dpu_hw_cwb *c;
+
+ if (!addr)
+ return ERR_PTR(-EINVAL);
+
+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+ if (!c)
+ return ERR_PTR(-ENOMEM);
+
+ c->hw.blk_addr = addr + cfg->base;
+ c->hw.log_mask = DPU_DBG_MASK_CWB;
+
+ c->idx = cfg->id;
+ c->ops.config_cwb = dpu_hw_cwb_config;
+
+ return c;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.h
new file mode 100644
index 000000000000..96b6edf6b2bb
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#ifndef _DPU_HW_CWB_H
+#define _DPU_HW_CWB_H
+
+#include "dpu_hw_util.h"
+
+struct dpu_hw_cwb;
+
+enum cwb_mode_input {
+ INPUT_MODE_LM_OUT,
+ INPUT_MODE_DSPP_OUT,
+ INPUT_MODE_MAX
+};
+
+/**
+ * struct dpu_hw_cwb_setup_cfg : Describes configuration for CWB mux
+ * @pp_idx: Index of the real-time pinpong that the CWB mux will
+ * feed the CWB mux
+ * @input: Input tap point
+ */
+struct dpu_hw_cwb_setup_cfg {
+ enum dpu_pingpong pp_idx;
+ enum cwb_mode_input input;
+};
+
+/**
+ *
+ * struct dpu_hw_cwb_ops : Interface to the cwb hw driver functions
+ * @config_cwb: configure CWB mux
+ */
+struct dpu_hw_cwb_ops {
+ void (*config_cwb)(struct dpu_hw_cwb *ctx,
+ struct dpu_hw_cwb_setup_cfg *cwb_cfg);
+};
+
+/**
+ * struct dpu_hw_cwb : CWB mux driver object
+ * @base: Hardware block base structure
+ * @hw: Block hardware details
+ * @idx: CWB index
+ * @ops: handle to operations possible for this CWB
+ */
+struct dpu_hw_cwb {
+ struct dpu_hw_blk base;
+ struct dpu_hw_blk_reg_map hw;
+
+ enum dpu_cwb idx;
+
+ struct dpu_hw_cwb_ops ops;
+};
+
+/**
+ * dpu_hw_cwb - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_cwb *to_dpu_hw_cwb(struct dpu_hw_blk *hw)
+{
+ return container_of(hw, struct dpu_hw_cwb, base);
+}
+
+struct dpu_hw_cwb *dpu_hw_cwb_init(struct drm_device *dev,
+ const struct dpu_cwb_cfg *cfg,
+ void __iomem *addr);
+
+#endif /*_DPU_HW_CWB_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index c17d2d356f7a..c43cb55fe1d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#ifndef _DPU_HW_MDSS_H
@@ -352,6 +354,7 @@ struct dpu_mdss_color {
#define DPU_DBG_MASK_DSPP (1 << 10)
#define DPU_DBG_MASK_DSC (1 << 11)
#define DPU_DBG_MASK_CDM (1 << 12)
+#define DPU_DBG_MASK_CWB (1 << 13)
/**
* struct dpu_hw_tear_check - Struct contains parameters to configure
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 10/22] drm/msm/dpu: Add dpu_hw_cwb abstraction for CWB block
2024-09-24 22:59 ` [PATCH v2 10/22] drm/msm/dpu: Add dpu_hw_cwb abstraction for CWB block Jessica Zhang
@ 2024-09-24 23:19 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:19 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:26PM GMT, Jessica Zhang wrote:
> The CWB mux has its own registers and set of operations. Add dpu_hw_cwb
> abstraction to allow driver to configure the CWB mux.
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/Makefile | 1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.c | 73 +++++++++++++++++++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cwb.h | 70 +++++++++++++++++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 5 +-
> 4 files changed, 148 insertions(+), 1 deletion(-)
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 11/22] drm/msm/dpu: add CWB support to dpu_hw_wb
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (9 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 10/22] drm/msm/dpu: Add dpu_hw_cwb abstraction for CWB block Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:20 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 12/22] drm/msm/dpu: Add RM support for allocating CWB Jessica Zhang
` (10 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Adjust the WB_MUX configuration to account for using dedicated CWB
pingpong blocks.
Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
index 93ff01c889b5..76d6fd614b7e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
@@ -173,7 +173,9 @@ static void dpu_hw_wb_bind_pingpong_blk(
mux_cfg = DPU_REG_READ(c, WB_MUX);
mux_cfg &= ~0xf;
- if (pp)
+ if (pp >= PINGPONG_CWB_0)
+ mux_cfg |= (pp < PINGPONG_CWB_2) ? 0xd : 0xb;
+ else if (pp)
mux_cfg |= (pp - PINGPONG_0) & 0x7;
else
mux_cfg |= 0xf;
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 11/22] drm/msm/dpu: add CWB support to dpu_hw_wb
2024-09-24 22:59 ` [PATCH v2 11/22] drm/msm/dpu: add CWB support to dpu_hw_wb Jessica Zhang
@ 2024-09-24 23:20 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:20 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:27PM GMT, Jessica Zhang wrote:
> From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
>
> Adjust the WB_MUX configuration to account for using dedicated CWB
> pingpong blocks.
>
> Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 12/22] drm/msm/dpu: Add RM support for allocating CWB
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (10 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 11/22] drm/msm/dpu: add CWB support to dpu_hw_wb Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:20 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 13/22] drm/msm/dpu: Add CWB to msm_display_topology Jessica Zhang
` (9 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Add support for allocating the concurrent writeback mux as part of the
WB allocation
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 17 +++++++++++++++--
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 2 ++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index bc99b04eae3a..96c80cf9f6ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
-#include "msm_drv.h"
#define pr_fmt(fmt) "[drm:%s] " fmt, __func__
#include "dpu_kms.h"
#include "dpu_hw_lm.h"
#include "dpu_hw_ctl.h"
#include "dpu_hw_cdm.h"
+#include "dpu_hw_cwb.h"
#include "dpu_hw_pingpong.h"
#include "dpu_hw_sspp.h"
#include "dpu_hw_intf.h"
@@ -113,6 +113,19 @@ int dpu_rm_init(struct drm_device *dev,
rm->hw_wb[wb->id - WB_0] = hw;
}
+ for (i = 0; i < cat->cwb_count; i++) {
+ struct dpu_hw_cwb *hw;
+ const struct dpu_cwb_cfg *cwb = &cat->cwb[i];
+
+ hw = dpu_hw_cwb_init(dev, cwb, mmio);
+ if (IS_ERR(hw)) {
+ rc = PTR_ERR(hw);
+ DPU_ERROR("failed cwb object creation: err %d\n", rc);
+ goto fail;
+ }
+ rm->cwb_blks[cwb->id - CWB_0] = &hw->base;
+ }
+
for (i = 0; i < cat->ctl_count; i++) {
struct dpu_hw_ctl *hw;
const struct dpu_ctl_cfg *ctl = &cat->ctl[i];
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 36a0b6ed628d..8b968655d05b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -20,6 +20,7 @@ struct dpu_global_state;
* @ctl_blks: array of ctl hardware resources
* @hw_intf: array of intf hardware resources
* @hw_wb: array of wb hardware resources
+ * @hw_cwb: array of cwb hardware resources
* @dspp_blks: array of dspp hardware resources
* @hw_sspp: array of sspp hardware resources
* @cdm_blk: cdm hardware resource
@@ -30,6 +31,7 @@ struct dpu_rm {
struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0];
struct dpu_hw_wb *hw_wb[WB_MAX - WB_0];
+ struct dpu_hw_blk *cwb_blks[CWB_MAX - CWB_0];
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 12/22] drm/msm/dpu: Add RM support for allocating CWB
2024-09-24 22:59 ` [PATCH v2 12/22] drm/msm/dpu: Add RM support for allocating CWB Jessica Zhang
@ 2024-09-24 23:20 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:20 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:28PM GMT, Jessica Zhang wrote:
> Add support for allocating the concurrent writeback mux as part of the
> WB allocation
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 17 +++++++++++++++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 2 ++
> 2 files changed, 17 insertions(+), 2 deletions(-)
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 13/22] drm/msm/dpu: Add CWB to msm_display_topology
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (11 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 12/22] drm/msm/dpu: Add RM support for allocating CWB Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:22 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes Jessica Zhang
` (8 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Add the cwb_enabled flag to msm_display topology and adjust the toplogy
to account for concurrent writeback
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++++--
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 10 ++++++++--
drivers/gpu/drm/msm/msm_drv.h | 2 ++
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d53e986eee54..a7850bf844db 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1176,6 +1176,8 @@ static struct msm_display_topology dpu_crtc_get_topology(
dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state,
&crtc_state->adjusted_mode);
+ topology.cwb_enabled = drm_crtc_in_clone_mode(crtc_state);
+
/*
* Datapath topology selection
*
@@ -1189,9 +1191,9 @@ static struct msm_display_topology dpu_crtc_get_topology(
* Add dspps to the reservation requirements if ctm is requested
*/
- if (topology.num_intf == 2)
+ if (topology.num_intf == 2 && !topology.cwb_enabled)
topology.num_lm = 2;
- else if (topology.num_dsc == 2)
+ else if (topology.num_dsc == 2 && !topology.cwb_enabled)
topology.num_lm = 2;
else if (dpu_kms->catalog->caps->has_3d_merge)
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 96c80cf9f6ad..04df3056d75a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -371,8 +371,14 @@ static int _dpu_rm_reserve_ctls(
int i = 0, j, num_ctls;
bool needs_split_display;
- /* each hw_intf needs its own hw_ctrl to program its control path */
- num_ctls = top->num_intf;
+ /*
+ * For non-CWB mode, each hw_intf needs its own hw_ctl to program its
+ * control path. Hardcode num_ctls to 1 if CWB is enabled
+ */
+ if (top->cwb_enabled)
+ num_ctls = 1;
+ else
+ num_ctls = top->num_intf;
needs_split_display = _dpu_rm_needs_split_display(top);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 0d3adf398bc1..8a2a3705f117 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
@@ -88,6 +89,7 @@ struct msm_display_topology {
u32 num_dspp;
u32 num_dsc;
bool needs_cdm;
+ bool cwb_enabled;
};
/* Commit/Event thread specific structure */
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 13/22] drm/msm/dpu: Add CWB to msm_display_topology
2024-09-24 22:59 ` [PATCH v2 13/22] drm/msm/dpu: Add CWB to msm_display_topology Jessica Zhang
@ 2024-09-24 23:22 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:22 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:29PM GMT, Jessica Zhang wrote:
> Add the cwb_enabled flag to msm_display topology and adjust the toplogy
> to account for concurrent writeback
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 10 ++++++++--
> drivers/gpu/drm/msm/msm_drv.h | 2 ++
> 3 files changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index d53e986eee54..a7850bf844db 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1176,6 +1176,8 @@ static struct msm_display_topology dpu_crtc_get_topology(
> dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state,
> &crtc_state->adjusted_mode);
>
> + topology.cwb_enabled = drm_crtc_in_clone_mode(crtc_state);
> +
> /*
> * Datapath topology selection
> *
> @@ -1189,9 +1191,9 @@ static struct msm_display_topology dpu_crtc_get_topology(
> * Add dspps to the reservation requirements if ctm is requested
> */
>
> - if (topology.num_intf == 2)
> + if (topology.num_intf == 2 && !topology.cwb_enabled)
> topology.num_lm = 2;
> - else if (topology.num_dsc == 2)
> + else if (topology.num_dsc == 2 && !topology.cwb_enabled)
Is it a temporal restriction or is it a hardware limitation? Can we use
two LMs with a single WB?
> topology.num_lm = 2;
> else if (dpu_kms->catalog->caps->has_3d_merge)
> topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index 96c80cf9f6ad..04df3056d75a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -371,8 +371,14 @@ static int _dpu_rm_reserve_ctls(
> int i = 0, j, num_ctls;
> bool needs_split_display;
>
> - /* each hw_intf needs its own hw_ctrl to program its control path */
> - num_ctls = top->num_intf;
> + /*
> + * For non-CWB mode, each hw_intf needs its own hw_ctl to program its
> + * control path. Hardcode num_ctls to 1 if CWB is enabled
> + */
> + if (top->cwb_enabled)
> + num_ctls = 1;
> + else
> + num_ctls = top->num_intf;
>
> needs_split_display = _dpu_rm_needs_split_display(top);
>
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 0d3adf398bc1..8a2a3705f117 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -1,5 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
> * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
> * Copyright (C) 2013 Red Hat
> * Author: Rob Clark <robdclark@gmail.com>
> @@ -88,6 +89,7 @@ struct msm_display_topology {
> u32 num_dspp;
> u32 num_dsc;
> bool needs_cdm;
> + bool cwb_enabled;
> };
>
> /* Commit/Event thread specific structure */
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (12 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 13/22] drm/msm/dpu: Add CWB to msm_display_topology Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:25 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 15/22] drm/msm/dpu: Reserve resources for CWB Jessica Zhang
` (7 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
If the clone mode enabled status is changing, a modeset needs to happen
so that the resources can be reassigned
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index a7850bf844db..f20e44e9fc05 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1268,6 +1268,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
{
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
crtc);
+ struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
+ crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
@@ -1279,6 +1281,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
int rc = 0;
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
+ bool clone_mode_requested = drm_crtc_in_clone_mode(old_crtc_state);
+ bool clone_mode_enabled = drm_crtc_in_clone_mode(crtc_state);
/* there might be cases where encoder needs a modeset too */
drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
@@ -1286,6 +1290,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
crtc_state->mode_changed = true;
}
+ if ((clone_mode_requested && !clone_mode_enabled) ||
+ (!clone_mode_requested && clone_mode_enabled))
+ crtc_state->mode_changed = true;
+
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
rc = dpu_crtc_assign_resources(crtc, crtc_state);
if (rc < 0)
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes
2024-09-24 22:59 ` [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes Jessica Zhang
@ 2024-09-24 23:25 ` Dmitry Baryshkov
2024-09-25 0:05 ` Abhinav Kumar
0 siblings, 1 reply; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:25 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:30PM GMT, Jessica Zhang wrote:
> If the clone mode enabled status is changing, a modeset needs to happen
> so that the resources can be reassigned
Sima's comment regarding crtc_state->mode_changed seems to be ignored...
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index a7850bf844db..f20e44e9fc05 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1268,6 +1268,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> {
> struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
> crtc);
> + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
> + crtc);
> struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
> struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
>
> @@ -1279,6 +1281,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> int rc = 0;
>
> bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
> + bool clone_mode_requested = drm_crtc_in_clone_mode(old_crtc_state);
> + bool clone_mode_enabled = drm_crtc_in_clone_mode(crtc_state);
>
> /* there might be cases where encoder needs a modeset too */
> drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
> @@ -1286,6 +1290,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> crtc_state->mode_changed = true;
> }
>
> + if ((clone_mode_requested && !clone_mode_enabled) ||
> + (!clone_mode_requested && clone_mode_enabled))
> + crtc_state->mode_changed = true;
> +
> if (drm_atomic_crtc_needs_modeset(crtc_state)) {
> rc = dpu_crtc_assign_resources(crtc, crtc_state);
> if (rc < 0)
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes
2024-09-24 23:25 ` Dmitry Baryshkov
@ 2024-09-25 0:05 ` Abhinav Kumar
2024-09-25 8:28 ` Dmitry Baryshkov
0 siblings, 1 reply; 64+ messages in thread
From: Abhinav Kumar @ 2024-09-25 0:05 UTC (permalink / raw)
To: Dmitry Baryshkov, Jessica Zhang
Cc: Rob Clark, Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 9/24/2024 4:25 PM, Dmitry Baryshkov wrote:
> On Tue, Sep 24, 2024 at 03:59:30PM GMT, Jessica Zhang wrote:
>> If the clone mode enabled status is changing, a modeset needs to happen
>> so that the resources can be reassigned
>
> Sima's comment regarding crtc_state->mode_changed seems to be ignored...
>
Not ignored. One of us has to take that up. There is a broader cleanup
required for that.
We can sync up on how to tackle this : whether it needs to be in this
series or push another one cleaning up all the instances.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index a7850bf844db..f20e44e9fc05 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -1268,6 +1268,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>> {
>> struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
>> crtc);
>> + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
>> + crtc);
>> struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>> struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
>>
>> @@ -1279,6 +1281,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>> int rc = 0;
>>
>> bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
>> + bool clone_mode_requested = drm_crtc_in_clone_mode(old_crtc_state);
>> + bool clone_mode_enabled = drm_crtc_in_clone_mode(crtc_state);
>>
>> /* there might be cases where encoder needs a modeset too */
>> drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
>> @@ -1286,6 +1290,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>> crtc_state->mode_changed = true;
>> }
>>
>> + if ((clone_mode_requested && !clone_mode_enabled) ||
>> + (!clone_mode_requested && clone_mode_enabled))
>> + crtc_state->mode_changed = true;
>> +
>> if (drm_atomic_crtc_needs_modeset(crtc_state)) {
>> rc = dpu_crtc_assign_resources(crtc, crtc_state);
>> if (rc < 0)
>>
>> --
>> 2.34.1
>>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes
2024-09-25 0:05 ` Abhinav Kumar
@ 2024-09-25 8:28 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-25 8:28 UTC (permalink / raw)
To: Abhinav Kumar
Cc: Jessica Zhang, Rob Clark, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 05:05:43PM GMT, Abhinav Kumar wrote:
>
>
> On 9/24/2024 4:25 PM, Dmitry Baryshkov wrote:
> > On Tue, Sep 24, 2024 at 03:59:30PM GMT, Jessica Zhang wrote:
> > > If the clone mode enabled status is changing, a modeset needs to happen
> > > so that the resources can be reassigned
> >
> > Sima's comment regarding crtc_state->mode_changed seems to be ignored...
> >
>
> Not ignored. One of us has to take that up. There is a broader cleanup
> required for that.
At least then it should be mentioned in the commit message or under the
commit message.
>
> We can sync up on how to tackle this : whether it needs to be in this series
> or push another one cleaning up all the instances.
Yes, let's sync separately.
>
> > >
> > > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > > ---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 ++++++++
> > > 1 file changed, 8 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > index a7850bf844db..f20e44e9fc05 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > @@ -1268,6 +1268,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> > > {
> > > struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
> > > crtc);
> > > + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
> > > + crtc);
> > > struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
> > > struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
> > > @@ -1279,6 +1281,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> > > int rc = 0;
> > > bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
> > > + bool clone_mode_requested = drm_crtc_in_clone_mode(old_crtc_state);
> > > + bool clone_mode_enabled = drm_crtc_in_clone_mode(crtc_state);
> > > /* there might be cases where encoder needs a modeset too */
> > > drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) {
> > > @@ -1286,6 +1290,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> > > crtc_state->mode_changed = true;
> > > }
> > > + if ((clone_mode_requested && !clone_mode_enabled) ||
> > > + (!clone_mode_requested && clone_mode_enabled))
> > > + crtc_state->mode_changed = true;
> > > +
> > > if (drm_atomic_crtc_needs_modeset(crtc_state)) {
> > > rc = dpu_crtc_assign_resources(crtc, crtc_state);
> > > if (rc < 0)
> > >
> > > --
> > > 2.34.1
> > >
> >
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 15/22] drm/msm/dpu: Reserve resources for CWB
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (13 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 14/22] drm/msm/dpu: Require modeset if clone mode status changes Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:33 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder Jessica Zhang
` (6 subsequent siblings)
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Add support for RM to reserve dedicated CWB pingpongs and CWB muxes
For concurrent writeback, even-indexed CWB muxes must be assigned to
even-indexed LMs and odd-indexed CWB muxes for odd-indexed LMs. The same
even/odd rule applies for dedicated CWB pingpongs.
Track the CWB muxes in the global state and add a CWB-specific helper to
reserve the correct CWB muxes and dedicated pingpongs following the
even/odd rule.
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 34 ++++++++++--
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 84 +++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 36b677cf9c7a..b2f0bf412451 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2013 Red Hat
* Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Author: Rob Clark <robdclark@gmail.com>
*/
@@ -28,6 +28,7 @@
#include "dpu_hw_dsc.h"
#include "dpu_hw_merge3d.h"
#include "dpu_hw_cdm.h"
+#include "dpu_hw_cwb.h"
#include "dpu_formats.h"
#include "dpu_encoder_phys.h"
#include "dpu_crtc.h"
@@ -133,6 +134,9 @@ enum dpu_enc_rc_states {
* @cur_slave: As above but for the slave encoder.
* @hw_pp: Handle to the pingpong blocks used for the display. No.
* pingpong blocks can be different than num_phys_encs.
+ * @hw_cwb: Handle to the CWB muxes used for concurrent writeback
+ * display. Number of CWB muxes can be different than
+ * num_phys_encs.
* @hw_dsc: Handle to the DSC blocks used for the display.
* @dsc_mask: Bitmask of used DSC blocks.
* @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
@@ -177,6 +181,7 @@ struct dpu_encoder_virt {
struct dpu_encoder_phys *cur_master;
struct dpu_encoder_phys *cur_slave;
struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
+ struct dpu_hw_cwb *hw_cwb[MAX_CHANNELS_PER_ENC];
struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
unsigned int dsc_mask;
@@ -1053,7 +1058,10 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
+ struct dpu_hw_blk *hw_cwb[MAX_CHANNELS_PER_ENC];
int num_pp, num_dsc;
+ int num_cwb = 0;
+ bool is_cwb_encoder;
unsigned int dsc_mask = 0;
int i;
@@ -1067,6 +1075,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
priv = drm_enc->dev->dev_private;
dpu_kms = to_dpu_kms(priv->kms);
+ is_cwb_encoder = drm_crtc_in_clone_mode(crtc_state) &&
+ dpu_enc->disp_info.intf_type == INTF_WB;
global_state = dpu_kms_get_existing_global_state(dpu_kms);
if (IS_ERR_OR_NULL(global_state)) {
@@ -1077,9 +1087,25 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
trace_dpu_enc_mode_set(DRMID(drm_enc));
/* Query resource that have been reserved in atomic check step. */
- num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
- ARRAY_SIZE(hw_pp));
+ if (is_cwb_encoder) {
+ num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ drm_enc->crtc,
+ DPU_HW_BLK_DCWB_PINGPONG,
+ hw_pp, ARRAY_SIZE(hw_pp));
+ num_cwb = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ drm_enc->crtc,
+ DPU_HW_BLK_CWB,
+ hw_cwb, ARRAY_SIZE(hw_cwb));
+ } else {
+ num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ drm_enc->crtc,
+ DPU_HW_BLK_PINGPONG, hw_pp,
+ ARRAY_SIZE(hw_pp));
+ }
+
+ for (i = 0; i < num_cwb; i++)
+ dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
+
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index c43cb55fe1d2..34195bf4e270 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -77,12 +77,14 @@ enum dpu_hw_blk_type {
DPU_HW_BLK_LM,
DPU_HW_BLK_CTL,
DPU_HW_BLK_PINGPONG,
+ DPU_HW_BLK_DCWB_PINGPONG,
DPU_HW_BLK_INTF,
DPU_HW_BLK_WB,
DPU_HW_BLK_DSPP,
DPU_HW_BLK_MERGE_3D,
DPU_HW_BLK_DSC,
DPU_HW_BLK_CDM,
+ DPU_HW_BLK_CWB,
DPU_HW_BLK_MAX,
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 4fdc5f933261..a078b5334dc1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -128,6 +128,7 @@ struct dpu_global_state {
uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0];
uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0];
uint32_t cdm_to_crtc_id;
+ uint32_t cwb_to_crtc_id[CWB_MAX - CWB_0];
};
struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 04df3056d75a..429e432e2163 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -223,6 +223,54 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
return -EINVAL;
}
+static int _dpu_rm_reserve_cwb_mux_and_pingpongs(struct dpu_rm *rm,
+ struct dpu_global_state *global_state,
+ uint32_t crtc_id,
+ struct msm_display_topology *topology)
+{
+ int num_cwb_pp = topology->num_lm, cwb_pp_count = 0;
+ int cwb_pp_start_idx = PINGPONG_CWB_0 - PINGPONG_0;
+ int cwb_pp_idx[MAX_BLOCKS];
+ int cwb_mux_idx[MAX_BLOCKS];
+
+ /*
+ * Reserve additional dedicated CWB pingpong blocks and muxes for each
+ * mixer
+ *
+ * TODO: add support for reserving non-dedicated CWB pingpong blocks
+ */
+ for (int i = 0; i < ARRAY_SIZE(rm->mixer_blks) &&
+ cwb_pp_count < num_cwb_pp; i++) {
+ for (int j = cwb_pp_start_idx;
+ j < ARRAY_SIZE(rm->pingpong_blks); j++) {
+ /*
+ * Odd LMs must be assigned to odd pingpongs and even
+ * LMs with even pingpongs
+ */
+ if (reserved_by_other(global_state->pingpong_to_crtc_id,
+ j, crtc_id) || i % 2 != j % 2)
+ continue;
+
+ cwb_pp_idx[cwb_pp_count] = j;
+ cwb_mux_idx[cwb_pp_count] = j - cwb_pp_start_idx;
+ cwb_pp_count++;
+ break;
+ }
+ }
+
+ if (cwb_pp_count != num_cwb_pp) {
+ DPU_ERROR("Unable to reserve all cwb pingpongs\n");
+ return -ENAVAIL;
+ }
+
+ for (int i = 0; i < cwb_pp_count; i++) {
+ global_state->pingpong_to_crtc_id[cwb_pp_idx[i]] = crtc_id;
+ global_state->cwb_to_crtc_id[cwb_mux_idx[i]] = crtc_id;
+ }
+
+ return 0;
+}
+
/**
* _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer meets
* proposed use case requirements, incl. hardwired dependent blocks like
@@ -603,6 +651,14 @@ static int _dpu_rm_make_reservation(
return ret;
}
+ if (topology->cwb_enabled) {
+ ret = _dpu_rm_reserve_cwb_mux_and_pingpongs(rm, global_state,
+ crtc_id, topology);
+ if (ret) {
+ DPU_ERROR("unable to find appropriate dcwb pingpongs\n");
+ return ret;
+ }
+ }
ret = _dpu_rm_reserve_ctls(rm, global_state, crtc_id,
topology);
@@ -653,6 +709,8 @@ void dpu_rm_release(struct dpu_global_state *global_state,
_dpu_rm_clear_mapping(global_state->dspp_to_crtc_id,
ARRAY_SIZE(global_state->dspp_to_crtc_id), crtc_id);
_dpu_rm_clear_mapping(&global_state->cdm_to_crtc_id, 1, crtc_id);
+ _dpu_rm_clear_mapping(global_state->cwb_to_crtc_id,
+ ARRAY_SIZE(global_state->cwb_to_crtc_id), crtc_id);
}
int dpu_rm_reserve(
@@ -692,6 +750,7 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
switch (type) {
case DPU_HW_BLK_PINGPONG:
+ case DPU_HW_BLK_DCWB_PINGPONG:
hw_blks = rm->pingpong_blks;
hw_to_crtc_id = global_state->pingpong_to_crtc_id;
max_blks = ARRAY_SIZE(rm->pingpong_blks);
@@ -721,6 +780,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
hw_to_crtc_id = &global_state->cdm_to_crtc_id;
max_blks = 1;
break;
+ case DPU_HW_BLK_CWB:
+ hw_blks = rm->cwb_blks;
+ hw_to_crtc_id = global_state->cwb_to_crtc_id;
+ max_blks = ARRAY_SIZE(rm->cwb_blks);
+ break;
default:
DPU_ERROR("blk type %d not managed by rm\n", type);
return 0;
@@ -731,6 +795,20 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
if (hw_to_crtc_id[i] != crtc_id)
continue;
+ if (type == DPU_HW_BLK_PINGPONG) {
+ struct dpu_hw_pingpong *pp = to_dpu_hw_pingpong(hw_blks[i]);
+
+ if (pp->idx >= PINGPONG_CWB_0)
+ continue;
+ }
+
+ if (type == DPU_HW_BLK_DCWB_PINGPONG) {
+ struct dpu_hw_pingpong *pp = to_dpu_hw_pingpong(hw_blks[i]);
+
+ if (pp->idx < PINGPONG_CWB_0)
+ continue;
+ }
+
if (num_blks == blks_size) {
DPU_ERROR("More than %d resources assigned to crtc %d\n",
blks_size, crtc_id);
@@ -801,4 +879,10 @@ void dpu_rm_print_state(struct drm_printer *p,
dpu_rm_print_state_helper(p, rm->cdm_blk,
global_state->cdm_to_crtc_id);
drm_puts(p, "\n");
+
+ drm_puts(p, "\tcwb=");
+ for (i = 0; i < ARRAY_SIZE(global_state->cwb_to_crtc_id); i++)
+ dpu_rm_print_state_helper(p, rm->cwb_blks[i],
+ global_state->cwb_to_crtc_id[i]);
+ drm_puts(p, "\n");
}
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 15/22] drm/msm/dpu: Reserve resources for CWB
2024-09-24 22:59 ` [PATCH v2 15/22] drm/msm/dpu: Reserve resources for CWB Jessica Zhang
@ 2024-09-24 23:33 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:33 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:31PM GMT, Jessica Zhang wrote:
> Add support for RM to reserve dedicated CWB pingpongs and CWB muxes
>
> For concurrent writeback, even-indexed CWB muxes must be assigned to
> even-indexed LMs and odd-indexed CWB muxes for odd-indexed LMs. The same
> even/odd rule applies for dedicated CWB pingpongs.
>
> Track the CWB muxes in the global state and add a CWB-specific helper to
> reserve the correct CWB muxes and dedicated pingpongs following the
> even/odd rule.
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 34 ++++++++++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 84 +++++++++++++++++++++++++++++
> 4 files changed, 117 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 36b677cf9c7a..b2f0bf412451 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -2,7 +2,7 @@
> /*
> * Copyright (C) 2013 Red Hat
> * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
> - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> *
> * Author: Rob Clark <robdclark@gmail.com>
> */
> @@ -28,6 +28,7 @@
> #include "dpu_hw_dsc.h"
> #include "dpu_hw_merge3d.h"
> #include "dpu_hw_cdm.h"
> +#include "dpu_hw_cwb.h"
> #include "dpu_formats.h"
> #include "dpu_encoder_phys.h"
> #include "dpu_crtc.h"
> @@ -133,6 +134,9 @@ enum dpu_enc_rc_states {
> * @cur_slave: As above but for the slave encoder.
> * @hw_pp: Handle to the pingpong blocks used for the display. No.
> * pingpong blocks can be different than num_phys_encs.
> + * @hw_cwb: Handle to the CWB muxes used for concurrent writeback
> + * display. Number of CWB muxes can be different than
> + * num_phys_encs.
> * @hw_dsc: Handle to the DSC blocks used for the display.
> * @dsc_mask: Bitmask of used DSC blocks.
> * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
> @@ -177,6 +181,7 @@ struct dpu_encoder_virt {
> struct dpu_encoder_phys *cur_master;
> struct dpu_encoder_phys *cur_slave;
> struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
> + struct dpu_hw_cwb *hw_cwb[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>
> unsigned int dsc_mask;
> @@ -1053,7 +1058,10 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
> + struct dpu_hw_blk *hw_cwb[MAX_CHANNELS_PER_ENC];
> int num_pp, num_dsc;
> + int num_cwb = 0;
> + bool is_cwb_encoder;
> unsigned int dsc_mask = 0;
> int i;
>
> @@ -1067,6 +1075,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>
> priv = drm_enc->dev->dev_private;
> dpu_kms = to_dpu_kms(priv->kms);
> + is_cwb_encoder = drm_crtc_in_clone_mode(crtc_state) &&
> + dpu_enc->disp_info.intf_type == INTF_WB;
>
> global_state = dpu_kms_get_existing_global_state(dpu_kms);
> if (IS_ERR_OR_NULL(global_state)) {
> @@ -1077,9 +1087,25 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> trace_dpu_enc_mode_set(DRMID(drm_enc));
>
> /* Query resource that have been reserved in atomic check step. */
> - num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> - drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
> - ARRAY_SIZE(hw_pp));
> + if (is_cwb_encoder) {
> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + drm_enc->crtc,
> + DPU_HW_BLK_DCWB_PINGPONG,
> + hw_pp, ARRAY_SIZE(hw_pp));
> + num_cwb = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + drm_enc->crtc,
> + DPU_HW_BLK_CWB,
> + hw_cwb, ARRAY_SIZE(hw_cwb));
> + } else {
> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + drm_enc->crtc,
> + DPU_HW_BLK_PINGPONG, hw_pp,
> + ARRAY_SIZE(hw_pp));
> + }
> +
> + for (i = 0; i < num_cwb; i++)
> + dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
> +
> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> index c43cb55fe1d2..34195bf4e270 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -77,12 +77,14 @@ enum dpu_hw_blk_type {
> DPU_HW_BLK_LM,
> DPU_HW_BLK_CTL,
> DPU_HW_BLK_PINGPONG,
> + DPU_HW_BLK_DCWB_PINGPONG,
> DPU_HW_BLK_INTF,
> DPU_HW_BLK_WB,
> DPU_HW_BLK_DSPP,
> DPU_HW_BLK_MERGE_3D,
> DPU_HW_BLK_DSC,
> DPU_HW_BLK_CDM,
> + DPU_HW_BLK_CWB,
> DPU_HW_BLK_MAX,
> };
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index 4fdc5f933261..a078b5334dc1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -128,6 +128,7 @@ struct dpu_global_state {
> uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0];
> uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0];
> uint32_t cdm_to_crtc_id;
> + uint32_t cwb_to_crtc_id[CWB_MAX - CWB_0];
> };
>
> struct dpu_global_state
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index 04df3056d75a..429e432e2163 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -223,6 +223,54 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
> return -EINVAL;
> }
>
> +static int _dpu_rm_reserve_cwb_mux_and_pingpongs(struct dpu_rm *rm,
> + struct dpu_global_state *global_state,
> + uint32_t crtc_id,
> + struct msm_display_topology *topology)
> +{
> + int num_cwb_pp = topology->num_lm, cwb_pp_count = 0;
> + int cwb_pp_start_idx = PINGPONG_CWB_0 - PINGPONG_0;
> + int cwb_pp_idx[MAX_BLOCKS];
> + int cwb_mux_idx[MAX_BLOCKS];
> +
> + /*
> + * Reserve additional dedicated CWB pingpong blocks and muxes for each
s/pingpong/PINGPONG/ globally
> + * mixer
> + *
> + * TODO: add support for reserving non-dedicated CWB pingpong blocks
... on platforms with no dedicated PINGPONG_CWB
> + */
> + for (int i = 0; i < ARRAY_SIZE(rm->mixer_blks) &&
> + cwb_pp_count < num_cwb_pp; i++) {
> + for (int j = cwb_pp_start_idx;
> + j < ARRAY_SIZE(rm->pingpong_blks); j++) {
> + /*
> + * Odd LMs must be assigned to odd pingpongs and even
> + * LMs with even pingpongs
> + */
> + if (reserved_by_other(global_state->pingpong_to_crtc_id,
> + j, crtc_id) || i % 2 != j % 2)
Carriage return after ||, please. Maybe use single line for
reserved_by_other call, it's easier to read this way.
> + continue;
> +
> + cwb_pp_idx[cwb_pp_count] = j;
> + cwb_mux_idx[cwb_pp_count] = j - cwb_pp_start_idx;
> + cwb_pp_count++;
> + break;
> + }
> + }
> +
> + if (cwb_pp_count != num_cwb_pp) {
> + DPU_ERROR("Unable to reserve all cwb pingpongs\n");
> + return -ENAVAIL;
> + }
> +
> + for (int i = 0; i < cwb_pp_count; i++) {
> + global_state->pingpong_to_crtc_id[cwb_pp_idx[i]] = crtc_id;
> + global_state->cwb_to_crtc_id[cwb_mux_idx[i]] = crtc_id;
> + }
> +
> + return 0;
> +}
> +
> /**
> * _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer meets
> * proposed use case requirements, incl. hardwired dependent blocks like
> @@ -603,6 +651,14 @@ static int _dpu_rm_make_reservation(
> return ret;
> }
>
> + if (topology->cwb_enabled) {
> + ret = _dpu_rm_reserve_cwb_mux_and_pingpongs(rm, global_state,
> + crtc_id, topology);
> + if (ret) {
> + DPU_ERROR("unable to find appropriate dcwb pingpongs\n");
Can we have a single error please? There was already one in the
reserve-cwb-and-pp function.
> + return ret;
> + }
> + }
>
> ret = _dpu_rm_reserve_ctls(rm, global_state, crtc_id,
> topology);
> @@ -653,6 +709,8 @@ void dpu_rm_release(struct dpu_global_state *global_state,
> _dpu_rm_clear_mapping(global_state->dspp_to_crtc_id,
> ARRAY_SIZE(global_state->dspp_to_crtc_id), crtc_id);
> _dpu_rm_clear_mapping(&global_state->cdm_to_crtc_id, 1, crtc_id);
> + _dpu_rm_clear_mapping(global_state->cwb_to_crtc_id,
> + ARRAY_SIZE(global_state->cwb_to_crtc_id), crtc_id);
> }
>
> int dpu_rm_reserve(
> @@ -692,6 +750,7 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>
> switch (type) {
> case DPU_HW_BLK_PINGPONG:
> + case DPU_HW_BLK_DCWB_PINGPONG:
> hw_blks = rm->pingpong_blks;
> hw_to_crtc_id = global_state->pingpong_to_crtc_id;
> max_blks = ARRAY_SIZE(rm->pingpong_blks);
> @@ -721,6 +780,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
> hw_to_crtc_id = &global_state->cdm_to_crtc_id;
> max_blks = 1;
> break;
> + case DPU_HW_BLK_CWB:
> + hw_blks = rm->cwb_blks;
> + hw_to_crtc_id = global_state->cwb_to_crtc_id;
> + max_blks = ARRAY_SIZE(rm->cwb_blks);
> + break;
> default:
> DPU_ERROR("blk type %d not managed by rm\n", type);
> return 0;
> @@ -731,6 +795,20 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
> if (hw_to_crtc_id[i] != crtc_id)
> continue;
>
> + if (type == DPU_HW_BLK_PINGPONG) {
> + struct dpu_hw_pingpong *pp = to_dpu_hw_pingpong(hw_blks[i]);
> +
> + if (pp->idx >= PINGPONG_CWB_0)
> + continue;
> + }
> +
> + if (type == DPU_HW_BLK_DCWB_PINGPONG) {
> + struct dpu_hw_pingpong *pp = to_dpu_hw_pingpong(hw_blks[i]);
> +
> + if (pp->idx < PINGPONG_CWB_0)
> + continue;
> + }
> +
> if (num_blks == blks_size) {
> DPU_ERROR("More than %d resources assigned to crtc %d\n",
> blks_size, crtc_id);
> @@ -801,4 +879,10 @@ void dpu_rm_print_state(struct drm_printer *p,
> dpu_rm_print_state_helper(p, rm->cdm_blk,
> global_state->cdm_to_crtc_id);
> drm_puts(p, "\n");
> +
> + drm_puts(p, "\tcwb=");
> + for (i = 0; i < ARRAY_SIZE(global_state->cwb_to_crtc_id); i++)
> + dpu_rm_print_state_helper(p, rm->cwb_blks[i],
> + global_state->cwb_to_crtc_id[i]);
> + drm_puts(p, "\n");
> }
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (14 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 15/22] drm/msm/dpu: Reserve resources for CWB Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:41 ` Dmitry Baryshkov
2024-09-30 14:17 ` neil.armstrong
2024-09-24 22:59 ` [PATCH v2 17/22] drm/msm/dpu: Support CWB in dpu_hw_ctl Jessica Zhang
` (5 subsequent siblings)
21 siblings, 2 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Cache the CWB block mask in the DPU virtual encoder and configure CWB
according to the CWB block mask within the writeback phys encoder
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 +++++++++++++++++++++-
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
.../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
3 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index b2f0bf412451..2628f2d55cb3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -24,6 +24,7 @@
#include "dpu_hw_catalog.h"
#include "dpu_hw_intf.h"
#include "dpu_hw_ctl.h"
+#include "dpu_hw_cwb.h"
#include "dpu_hw_dspp.h"
#include "dpu_hw_dsc.h"
#include "dpu_hw_merge3d.h"
@@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
* num_phys_encs.
* @hw_dsc: Handle to the DSC blocks used for the display.
* @dsc_mask: Bitmask of used DSC blocks.
+ * @cwb_mask Bitmask of used CWB muxes
* @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
* for partial update right-only cases, such as pingpong
* split where virtual pingpong does not generate IRQs
@@ -185,6 +187,7 @@ struct dpu_encoder_virt {
struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
unsigned int dsc_mask;
+ unsigned int cwb_mask;
bool intfs_swapped;
@@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
int num_cwb = 0;
bool is_cwb_encoder;
unsigned int dsc_mask = 0;
+ unsigned int cwb_mask = 0;
int i;
if (!drm_enc) {
@@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
ARRAY_SIZE(hw_pp));
}
- for (i = 0; i < num_cwb; i++)
+ for (i = 0; i < num_cwb; i++) {
dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
+ cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
+ }
+
+ dpu_enc->cwb_mask = cwb_mask;
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
@@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
}
}
+ if (dpu_enc->cwb_mask)
+ dpu_encoder_helper_phys_setup_cwb(phys_enc, false);
+
/* reset the merge 3D HW block */
if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
@@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
ctl->ops.clear_pending_flush(ctl);
}
+void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
+ bool enable)
+{
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+ struct dpu_hw_cwb *hw_cwb;
+ struct dpu_hw_cwb_setup_cfg cwb_cfg;
+
+ struct dpu_kms *dpu_kms;
+ struct dpu_global_state *global_state;
+ struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
+ int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
+
+ if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
+ return;
+
+ dpu_kms = phys_enc->dpu_kms;
+ global_state = dpu_kms_get_existing_global_state(dpu_kms);
+ num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ phys_enc->parent->crtc,
+ DPU_HW_BLK_PINGPONG, rt_pp_list,
+ ARRAY_SIZE(rt_pp_list));
+
+ if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
+ DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
+ return;
+ }
+
+ for (int i = 0; i < num_pp; i++) {
+ struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]);
+
+ for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
+ hw_cwb = dpu_enc->hw_cwb[i];
+
+ /*
+ * Even CWB muxes must take input from even real-time
+ * pingpongs and odd CWB muxes must take input from odd
+ * pingpongs
+ */
+ if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
+ rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
+ break;
+ }
+ }
+ }
+
+ /*
+ * The CWB mux supports using LM or DSPP as tap points. For now,
+ * always use LM tap point
+ */
+ cwb_cfg.input = INPUT_MODE_LM_OUT;
+
+ for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+ hw_cwb = dpu_enc->hw_cwb[i];
+ if (!hw_cwb)
+ continue;
+
+ cwb_cfg.pp_idx = rt_pp_idx[i];
+
+ hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
+ }
+}
+
void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
const struct msm_format *dpu_fmt,
u32 output_type)
@@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
return INTF_MODE_NONE;
}
+unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
+{
+ struct drm_encoder *encoder = phys_enc->parent;
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
+
+ return dpu_enc->cwb_mask;
+}
+
unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
{
struct drm_encoder *encoder = phys_enc->parent;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index e77ebe3a68da..d7a02d1f8053 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
*/
@@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
return BLEND_3D_NONE;
}
+/**
+ * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
+ * @phys_enc: Pointer to physical encoder structure
+ */
+unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
+
/**
* dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
* This helper function is used by physical encoder to get DSC blocks mask
@@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
*/
void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
+/**
+ * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
+ * @phys_enc: Pointer to physical encoder structure
+ * @enable: Enable CWB mux
+ */
+void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
+ bool enable);
+
/**
* dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
* @phys_enc: Pointer to physical encoder
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index 882c717859ce..e88c4d91041f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
@@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
+ dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
+
dpu_encoder_phys_wb_setup_ctl(phys_enc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-24 22:59 ` [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder Jessica Zhang
@ 2024-09-24 23:41 ` Dmitry Baryshkov
2024-09-25 0:14 ` Jessica Zhang
2024-09-30 14:17 ` neil.armstrong
1 sibling, 1 reply; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:41 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:32PM GMT, Jessica Zhang wrote:
> Cache the CWB block mask in the DPU virtual encoder and configure CWB
> according to the CWB block mask within the writeback phys encoder
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 +++++++++++++++++++++-
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
> 3 files changed, 100 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index b2f0bf412451..2628f2d55cb3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -24,6 +24,7 @@
> #include "dpu_hw_catalog.h"
> #include "dpu_hw_intf.h"
> #include "dpu_hw_ctl.h"
> +#include "dpu_hw_cwb.h"
> #include "dpu_hw_dspp.h"
> #include "dpu_hw_dsc.h"
> #include "dpu_hw_merge3d.h"
> @@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
> * num_phys_encs.
> * @hw_dsc: Handle to the DSC blocks used for the display.
> * @dsc_mask: Bitmask of used DSC blocks.
> + * @cwb_mask Bitmask of used CWB muxes
> * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
> * for partial update right-only cases, such as pingpong
> * split where virtual pingpong does not generate IRQs
> @@ -185,6 +187,7 @@ struct dpu_encoder_virt {
> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>
> unsigned int dsc_mask;
> + unsigned int cwb_mask;
>
> bool intfs_swapped;
>
> @@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> int num_cwb = 0;
> bool is_cwb_encoder;
> unsigned int dsc_mask = 0;
> + unsigned int cwb_mask = 0;
> int i;
>
> if (!drm_enc) {
> @@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> ARRAY_SIZE(hw_pp));
> }
>
> - for (i = 0; i < num_cwb; i++)
> + for (i = 0; i < num_cwb; i++) {
> dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
> + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
> + }
> +
> + dpu_enc->cwb_mask = cwb_mask;
>
> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
> @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
> }
> }
>
> + if (dpu_enc->cwb_mask)
> + dpu_encoder_helper_phys_setup_cwb(phys_enc, false);
> +
> /* reset the merge 3D HW block */
> if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
> phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
> @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
> ctl->ops.clear_pending_flush(ctl);
> }
>
> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
> + bool enable)
> +{
> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
> + struct dpu_hw_cwb *hw_cwb;
> + struct dpu_hw_cwb_setup_cfg cwb_cfg;
> +
> + struct dpu_kms *dpu_kms;
> + struct dpu_global_state *global_state;
> + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
> + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
> +
> + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
> + return;
We have already dereferened phys_enc, so checking that it's not NULL is
futile. Also we know that the function is only called if cwb_mask is not
zero, so the last check is also useless.
> +
> + dpu_kms = phys_enc->dpu_kms;
> + global_state = dpu_kms_get_existing_global_state(dpu_kms);
> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + phys_enc->parent->crtc,
> + DPU_HW_BLK_PINGPONG, rt_pp_list,
> + ARRAY_SIZE(rt_pp_list));
> +
> + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
> + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
> + return;
> + }
> +
> + for (int i = 0; i < num_pp; i++) {
> + struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]);
> +
> + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
> + hw_cwb = dpu_enc->hw_cwb[i];
> +
> + /*
> + * Even CWB muxes must take input from even real-time
> + * pingpongs and odd CWB muxes must take input from odd
> + * pingpongs
> + */
> + if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
What about `if (a != b) continue;`?
> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
Can we call config_cwb() here directly with no intermediate arrays?
> + break;
> + }
> + }
> + }
> +
> + /*
> + * The CWB mux supports using LM or DSPP as tap points. For now,
> + * always use LM tap point
> + */
> + cwb_cfg.input = INPUT_MODE_LM_OUT;
> +
> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
> + hw_cwb = dpu_enc->hw_cwb[i];
> + if (!hw_cwb)
> + continue;
> +
> + cwb_cfg.pp_idx = rt_pp_idx[i];
> +
> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
> + }
> +}
> +
> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
> const struct msm_format *dpu_fmt,
> u32 output_type)
> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
> return INTF_MODE_NONE;
> }
>
> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
it's called get_cwb, but it returns a mask?
> +{
> + struct drm_encoder *encoder = phys_enc->parent;
> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
> +
> + return dpu_enc->cwb_mask;
> +}
> +
> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
> {
> struct drm_encoder *encoder = phys_enc->parent;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> index e77ebe3a68da..d7a02d1f8053 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
> */
>
> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
> return BLEND_3D_NONE;
> }
>
> +/**
> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
> + * @phys_enc: Pointer to physical encoder structure
> + */
All kerneldoc at the function definition, please. I plan to go through
the existing codebase and move existing docs. It seems to be the only
way to get kerneldoc-related warnings.
> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
> +
> /**
> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
> * This helper function is used by physical encoder to get DSC blocks mask
> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
> */
> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
>
> +/**
> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
> + * @phys_enc: Pointer to physical encoder structure
> + * @enable: Enable CWB mux
> + */
> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
> + bool enable);
> +
> /**
> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
> * @phys_enc: Pointer to physical encoder
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> index 882c717859ce..e88c4d91041f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> */
>
> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>
> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
>
> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
> +
> dpu_encoder_phys_wb_setup_ctl(phys_enc);
> }
>
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-24 23:41 ` Dmitry Baryshkov
@ 2024-09-25 0:14 ` Jessica Zhang
2024-09-25 8:30 ` Dmitry Baryshkov
0 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-25 0:14 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On 9/24/2024 4:41 PM, Dmitry Baryshkov wrote:
> On Tue, Sep 24, 2024 at 03:59:32PM GMT, Jessica Zhang wrote:
>> Cache the CWB block mask in the DPU virtual encoder and configure CWB
>> according to the CWB block mask within the writeback phys encoder
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 +++++++++++++++++++++-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
>> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
>> 3 files changed, 100 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> index b2f0bf412451..2628f2d55cb3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> @@ -24,6 +24,7 @@
>> #include "dpu_hw_catalog.h"
>> #include "dpu_hw_intf.h"
>> #include "dpu_hw_ctl.h"
>> +#include "dpu_hw_cwb.h"
>> #include "dpu_hw_dspp.h"
>> #include "dpu_hw_dsc.h"
>> #include "dpu_hw_merge3d.h"
>> @@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
>> * num_phys_encs.
>> * @hw_dsc: Handle to the DSC blocks used for the display.
>> * @dsc_mask: Bitmask of used DSC blocks.
>> + * @cwb_mask Bitmask of used CWB muxes
>> * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
>> * for partial update right-only cases, such as pingpong
>> * split where virtual pingpong does not generate IRQs
>> @@ -185,6 +187,7 @@ struct dpu_encoder_virt {
>> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>>
>> unsigned int dsc_mask;
>> + unsigned int cwb_mask;
>>
>> bool intfs_swapped;
>>
>> @@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> int num_cwb = 0;
>> bool is_cwb_encoder;
>> unsigned int dsc_mask = 0;
>> + unsigned int cwb_mask = 0;
>> int i;
>>
>> if (!drm_enc) {
>> @@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> ARRAY_SIZE(hw_pp));
>> }
>>
>> - for (i = 0; i < num_cwb; i++)
>> + for (i = 0; i < num_cwb; i++) {
>> dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
>> + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
>> + }
>> +
>> + dpu_enc->cwb_mask = cwb_mask;
>>
>> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
>> @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
>> }
>> }
>>
>> + if (dpu_enc->cwb_mask)
>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, false);
>> +
>> /* reset the merge 3D HW block */
>> if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
>> phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
>> @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
>> ctl->ops.clear_pending_flush(ctl);
>> }
>>
>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
>> + bool enable)
>> +{
>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
>> + struct dpu_hw_cwb *hw_cwb;
>> + struct dpu_hw_cwb_setup_cfg cwb_cfg;
>> +
>> + struct dpu_kms *dpu_kms;
>> + struct dpu_global_state *global_state;
>> + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
>> + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
>> +
>> + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
>> + return;
>
> We have already dereferened phys_enc, so checking that it's not NULL is
> futile. Also we know that the function is only called if cwb_mask is not
> zero, so the last check is also useless.
Hi Dmitry,
Ack.
>
>> +
>> + dpu_kms = phys_enc->dpu_kms;
>> + global_state = dpu_kms_get_existing_global_state(dpu_kms);
>> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> + phys_enc->parent->crtc,
>> + DPU_HW_BLK_PINGPONG, rt_pp_list,
>> + ARRAY_SIZE(rt_pp_list));
>> +
>> + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
>> + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
>> + return;
>> + }
>> +
>> + for (int i = 0; i < num_pp; i++) {
>> + struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]);
>> +
>> + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
>> + hw_cwb = dpu_enc->hw_cwb[i];
>> +
>> + /*
>> + * Even CWB muxes must take input from even real-time
>> + * pingpongs and odd CWB muxes must take input from odd
>> + * pingpongs
>> + */
>> + if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
>
> What about `if (a != b) continue;`?
>
>> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
>
> Can we call config_cwb() here directly with no intermediate arrays?
Yes -- I should drop this for loop (and the associated array) as RM
should reserve the CWB muxes and real-time pingpongs in the correct order.
>
>> + break;
>> + }
>> + }
>> + }
>> +
>> + /*
>> + * The CWB mux supports using LM or DSPP as tap points. For now,
>> + * always use LM tap point
>> + */
>> + cwb_cfg.input = INPUT_MODE_LM_OUT;
>> +
>> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>> + hw_cwb = dpu_enc->hw_cwb[i];
>> + if (!hw_cwb)
>> + continue;
>> +
>> + cwb_cfg.pp_idx = rt_pp_idx[i];
>> +
>> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
>> + }
>> +}
>> +
>> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
>> const struct msm_format *dpu_fmt,
>> u32 output_type)
>> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
>> return INTF_MODE_NONE;
>> }
>>
>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
>
> it's called get_cwb, but it returns a mask?
I'd based this function off of dpu_encoder_helper_get_dsc(), but I can
rename this to *_get_cwb_mask() instead
>
>> +{
>> + struct drm_encoder *encoder = phys_enc->parent;
>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
>> +
>> + return dpu_enc->cwb_mask;
>> +}
>> +
>> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
>> {
>> struct drm_encoder *encoder = phys_enc->parent;
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> index e77ebe3a68da..d7a02d1f8053 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> @@ -1,6 +1,6 @@
>> /* SPDX-License-Identifier: GPL-2.0-only */
>> /*
>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
>> */
>>
>> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
>> return BLEND_3D_NONE;
>> }
>>
>> +/**
>> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
>> + * @phys_enc: Pointer to physical encoder structure
>> + */
>
> All kerneldoc at the function definition, please. I plan to go through
> the existing codebase and move existing docs. It seems to be the only
> way to get kerneldoc-related warnings.
Ack.
Thanks,
Jessica Zhang
>
>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
>> +
>> /**
>> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
>> * This helper function is used by physical encoder to get DSC blocks mask
>> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
>> */
>> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
>>
>> +/**
>> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
>> + * @phys_enc: Pointer to physical encoder structure
>> + * @enable: Enable CWB mux
>> + */
>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
>> + bool enable);
>> +
>> /**
>> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
>> * @phys_enc: Pointer to physical encoder
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>> index 882c717859ce..e88c4d91041f 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>> @@ -1,6 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /*
>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> */
>>
>> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
>> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>>
>> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
>>
>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
>> +
>> dpu_encoder_phys_wb_setup_ctl(phys_enc);
>> }
>>
>>
>> --
>> 2.34.1
>>
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-25 0:14 ` Jessica Zhang
@ 2024-09-25 8:30 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-25 8:30 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 05:14:49PM GMT, Jessica Zhang wrote:
>
>
> On 9/24/2024 4:41 PM, Dmitry Baryshkov wrote:
> > On Tue, Sep 24, 2024 at 03:59:32PM GMT, Jessica Zhang wrote:
> > > Cache the CWB block mask in the DPU virtual encoder and configure CWB
> > > according to the CWB block mask within the writeback phys encoder
> > >
> > > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > > ---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 +++++++++++++++++++++-
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
> > > .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
> > > 3 files changed, 100 insertions(+), 3 deletions(-)
> > >
> > > @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
> > > return INTF_MODE_NONE;
> > > }
> > > +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
> >
> > it's called get_cwb, but it returns a mask?
>
> I'd based this function off of dpu_encoder_helper_get_dsc(), but I can
> rename this to *_get_cwb_mask() instead
Yes, please.
>
> >
> > > +{
> > > + struct drm_encoder *encoder = phys_enc->parent;
> > > + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
> > > +
> > > + return dpu_enc->cwb_mask;
> > > +}
> > > +
> > > unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
> > > {
> > > struct drm_encoder *encoder = phys_enc->parent;
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-24 22:59 ` [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder Jessica Zhang
2024-09-24 23:41 ` Dmitry Baryshkov
@ 2024-09-30 14:17 ` neil.armstrong
2024-09-30 19:19 ` Jessica Zhang
1 sibling, 1 reply; 64+ messages in thread
From: neil.armstrong @ 2024-09-30 14:17 UTC (permalink / raw)
To: Jessica Zhang, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 25/09/2024 00:59, Jessica Zhang wrote:
> Cache the CWB block mask in the DPU virtual encoder and configure CWB
> according to the CWB block mask within the writeback phys encoder
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 +++++++++++++++++++++-
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
> 3 files changed, 100 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index b2f0bf412451..2628f2d55cb3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -24,6 +24,7 @@
> #include "dpu_hw_catalog.h"
> #include "dpu_hw_intf.h"
> #include "dpu_hw_ctl.h"
> +#include "dpu_hw_cwb.h"
> #include "dpu_hw_dspp.h"
> #include "dpu_hw_dsc.h"
> #include "dpu_hw_merge3d.h"
> @@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
> * num_phys_encs.
> * @hw_dsc: Handle to the DSC blocks used for the display.
> * @dsc_mask: Bitmask of used DSC blocks.
> + * @cwb_mask Bitmask of used CWB muxes
> * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
> * for partial update right-only cases, such as pingpong
> * split where virtual pingpong does not generate IRQs
> @@ -185,6 +187,7 @@ struct dpu_encoder_virt {
> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>
> unsigned int dsc_mask;
> + unsigned int cwb_mask;
>
> bool intfs_swapped;
>
> @@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> int num_cwb = 0;
> bool is_cwb_encoder;
> unsigned int dsc_mask = 0;
> + unsigned int cwb_mask = 0;
> int i;
>
> if (!drm_enc) {
> @@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> ARRAY_SIZE(hw_pp));
> }
>
> - for (i = 0; i < num_cwb; i++)
> + for (i = 0; i < num_cwb; i++) {
> dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
> + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
> + }
> +
> + dpu_enc->cwb_mask = cwb_mask;
>
> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
> @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
> }
> }
>
> + if (dpu_enc->cwb_mask)
> + dpu_encoder_helper_phys_setup_cwb(phys_enc, false);
> +
> /* reset the merge 3D HW block */
> if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
> phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
> @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
> ctl->ops.clear_pending_flush(ctl);
> }
>
> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
> + bool enable)
> +{
> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
> + struct dpu_hw_cwb *hw_cwb;
> + struct dpu_hw_cwb_setup_cfg cwb_cfg;
> +
> + struct dpu_kms *dpu_kms;
> + struct dpu_global_state *global_state;
> + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
> + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
> +
> + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
> + return;
> +
> + dpu_kms = phys_enc->dpu_kms;
> + global_state = dpu_kms_get_existing_global_state(dpu_kms);
> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + phys_enc->parent->crtc,
> + DPU_HW_BLK_PINGPONG, rt_pp_list,
> + ARRAY_SIZE(rt_pp_list));
> +
> + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
> + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
> + return;
> + }
> +
> + for (int i = 0; i < num_pp; i++) {
> + struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]);
> +
> + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
> + hw_cwb = dpu_enc->hw_cwb[i];
> +
> + /*
> + * Even CWB muxes must take input from even real-time
> + * pingpongs and odd CWB muxes must take input from odd
> + * pingpongs
> + */
> + if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
When running igt-test on QRD8650, I get:
# IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt-gpu-tools/kms_writeback -d
[ 2566.668998] Console: switching to colour dummy device 80x25
IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79 aarch64)
[ 2566.674859] [IGT] kms_writeback: executing
Using IGT_SRANDOM=1709057323 for randomisation
Opened device: /dev/dri/card0
[ 2566.741375] [IGT] kms_writeback: starting subtest dump-writeback
Starting subtest: dump-writeback
Subtest dump-writeback: SUCCESS (0.305s)[ 2567.053189] [IGT] kms_writeback: finished subtest dump-writeback, SUCCESS
[ 2567.064505] [IGT] kms_writeback: starting subtest dump-valid-clones
Starting subtest: dump-valid-clones
[ 2567.762793] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
[ 2567.771919] Mem abort info:
[ 2567.774888] ESR = 0x0000000096000006
[ 2567.778831] EC = 0x25: DABT (current EL), IL = 32 bits
[ 2567.784371] SET = 0, FnV = 0
[ 2567.787601] EA = 0, S1PTW = 0
[ 2567.790942] FSC = 0x06: level 2 translation fault
[ 2567.796044] Data abort info:
[ 2567.799083] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
[ 2567.804793] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 2567.810057] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 2567.815600] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008d60cf000
[ 2567.822290] [0000000000000010] pgd=08000008d6049003, p4d=08000008d6049003, pud=080000089397e003, pmd=0000000000000000
[ 2567.833254] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
[ 2567.839747] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_lpass_dais snd_q6dsp_common q6apm_dai q6prm 8021q garp mrp stp llc usb_f_fs libcomposite qrtr_mhi snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi panel_visionox_vtdr6130 snd_q6apm pci_pwrctl_pwrseq pci_pwrctl_core rpmsg_ctrl apr fastrpc qrtr_smd rpmsg_char wcd939x_usbss nb7vpq904m qcom_pd_mapper goodix_berlin_spi goodix_berlin_core ucsi_glink typec_ucsi pmic_glink_altmode aux_hpd_bridge qcom_battmgr leds_qcom_lpg msm ocmem drm_exec hci_uart qcom_pbs gpu_sched led_class_multicolor btqca phy_qcom_eusb2_repeater btbcm qcom_spmi_temp_alarm drm_dp_aux_bus phy_qcom_qmp_combo crct10dif_ce bluetooth drm_display_helper sm3_ce ecdh_generic aux_bridge sm3 snd_soc_sc8280xp pwrseq_qcom_wcn sha3_ce snd_soc_qcom_sdw rtc_pm8xxx qcom_pon ecc nvmem_qcom_spmi_sdam sha512_ce qcom_stats spi_geni_qcom snd_soc_qcom_common sha512_arm64 pwrseq_core i2c_qcom_geni cfg80211 drm_kms_helper dispcc_sm8550 gpi ipa snd_soc_lpass_va_macro snd_soc_lpass_tx_macro soundwire_qcom
[ 2567.839860] pinctrl_sm8650_lpass_lpi snd_soc_lpass_wsa_macro snd_soc_lpass_rx_macro rfkill slimbus phy_qcom_snps_eusb2 pinctrl_lpass_lpi gpucc_sm8650 snd_soc_lpass_macro_common qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcrypto authenc icc_bwmon qcom_sysmon qcom_common qrtr qcom_glink_smem phy_qcom_qmp_pcie mdt_loader libdes llcc_qcom ufs_qcom phy_qcom_qmp_ufs pmic_glink snd_soc_wcd939x rmtfs_mem pdr_interface snd_soc_wcd939x_sdw regmap_sdw qcom_pdr_msg snd_soc_wcd_mbhc qmi_helpers snd_soc_wcd_classh soundwire_bus typec nvmem_reboot_mode qcom_rng socinfo fuse drm backlight ipv6
[ 2567.983445] CPU: 5 UID: 0 PID: 554 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
[ 2567.994390] Tainted: [S]=CPU_OUT_OF_SPEC
[ 2567.998483] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
[ 2568.005244] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
[ 2568.012455] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
[ 2568.019009] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
[ 2568.025532] sp : ffff80008939b7e0
[ 2568.028999] x29: ffff80008939b810 x28: ffffcbcb66f26068 x27: ffff37ad962cb080
[ 2568.036388] x26: ffff37ad9887ed80 x25: ffff80008939b878 x24: ffff37ad43642a80
[ 2568.043775] x23: 0000000000000000 x22: ffff37ad42812080 x21: ffff37ad43642a80
[ 2568.051163] x20: ffff37ad962cb080 x19: ffff37ad962c8080 x18: 0000000000000001
[ 2568.058552] x17: 000000040044ffff x16: ffffcbcbb0fc8c64 x15: 00003d08ffff9c00
[ 2568.065939] x14: 00000013519b2832 x13: ffff37ad9d392200 x12: 000000000000000b
[ 2568.073325] x11: ffff37ad40dc56c0 x10: ffff37ad9d392200 x9 : ffff37afbe7bba80
[ 2568.080712] x8 : ffff37ad42812718 x7 : 0000000000000004 x6 : ffff37ad989ac798
[ 2568.088098] x5 : 0000000000000002 x4 : ffff80008939b7f8 x3 : ffff37ad962cb150
[ 2568.095480] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
[ 2568.102868] Call trace:
[ 2568.105446] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
[ 2568.111608] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
[ 2568.117692] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
[ 2568.123233] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
[ 2568.129224] disable_outputs+0x108/0x32c [drm_kms_helper]
[ 2568.134858] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
[ 2568.142614] msm_atomic_commit_tail+0x188/0x514 [msm]
[ 2568.147894] commit_tail+0xa4/0x18c [drm_kms_helper]
[ 2568.153065] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
[ 2568.159482] drm_atomic_commit+0xb8/0xf4 [drm]
[ 2568.164176] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
[ 2568.169369] drm_ioctl_kernel+0xc0/0x128 [drm]
[ 2568.174039] drm_ioctl+0x218/0x49c [drm]
[ 2568.178165] __arm64_sys_ioctl+0xac/0xf0
[ 2568.182271] invoke_syscall+0x48/0x10c
[ 2568.186217] el0_svc_common.constprop.0+0xc0/0xe0
[ 2568.191109] do_el0_svc+0x1c/0x28
[ 2568.194576] el0_svc+0x34/0xd8
[ 2568.197788] el0t_64_sync_handler+0x120/0x12c
[ 2568.202321] el0t_64_sync+0x190/0x194
[ 2568.206157] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
[ 2568.212484] ---[ end trace 0000000000000000 ]---
Neil
> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
> + break;
> + }
> + }
> + }
> +
> + /*
> + * The CWB mux supports using LM or DSPP as tap points. For now,
> + * always use LM tap point
> + */
> + cwb_cfg.input = INPUT_MODE_LM_OUT;
> +
> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
> + hw_cwb = dpu_enc->hw_cwb[i];
> + if (!hw_cwb)
> + continue;
> +
> + cwb_cfg.pp_idx = rt_pp_idx[i];
> +
> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
> + }
> +}
> +
> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
> const struct msm_format *dpu_fmt,
> u32 output_type)
> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
> return INTF_MODE_NONE;
> }
>
> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
> +{
> + struct drm_encoder *encoder = phys_enc->parent;
> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
> +
> + return dpu_enc->cwb_mask;
> +}
> +
> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
> {
> struct drm_encoder *encoder = phys_enc->parent;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> index e77ebe3a68da..d7a02d1f8053 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
> */
>
> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
> return BLEND_3D_NONE;
> }
>
> +/**
> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
> + * @phys_enc: Pointer to physical encoder structure
> + */
> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
> +
> /**
> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
> * This helper function is used by physical encoder to get DSC blocks mask
> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
> */
> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
>
> +/**
> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
> + * @phys_enc: Pointer to physical encoder structure
> + * @enable: Enable CWB mux
> + */
> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
> + bool enable);
> +
> /**
> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
> * @phys_enc: Pointer to physical encoder
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> index 882c717859ce..e88c4d91041f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> */
>
> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>
> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
>
> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
> +
> dpu_encoder_phys_wb_setup_ctl(phys_enc);
> }
>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-30 14:17 ` neil.armstrong
@ 2024-09-30 19:19 ` Jessica Zhang
2024-10-01 7:37 ` neil.armstrong
0 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-30 19:19 UTC (permalink / raw)
To: neil.armstrong, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 9/30/2024 7:17 AM, neil.armstrong@linaro.org wrote:
> On 25/09/2024 00:59, Jessica Zhang wrote:
>> Cache the CWB block mask in the DPU virtual encoder and configure CWB
>> according to the CWB block mask within the writeback phys encoder
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 ++++++++++++
>> +++++++++-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
>> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
>> 3 files changed, 100 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/
>> gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> index b2f0bf412451..2628f2d55cb3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> @@ -24,6 +24,7 @@
>> #include "dpu_hw_catalog.h"
>> #include "dpu_hw_intf.h"
>> #include "dpu_hw_ctl.h"
>> +#include "dpu_hw_cwb.h"
>> #include "dpu_hw_dspp.h"
>> #include "dpu_hw_dsc.h"
>> #include "dpu_hw_merge3d.h"
>> @@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
>> * num_phys_encs.
>> * @hw_dsc: Handle to the DSC blocks used for the display.
>> * @dsc_mask: Bitmask of used DSC blocks.
>> + * @cwb_mask Bitmask of used CWB muxes
>> * @intfs_swapped: Whether or not the phys_enc interfaces have
>> been swapped
>> * for partial update right-only cases, such as pingpong
>> * split where virtual pingpong does not generate IRQs
>> @@ -185,6 +187,7 @@ struct dpu_encoder_virt {
>> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>> unsigned int dsc_mask;
>> + unsigned int cwb_mask;
>> bool intfs_swapped;
>> @@ -1063,6 +1066,7 @@ static void
>> dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> int num_cwb = 0;
>> bool is_cwb_encoder;
>> unsigned int dsc_mask = 0;
>> + unsigned int cwb_mask = 0;
>> int i;
>> if (!drm_enc) {
>> @@ -1103,8 +1107,12 @@ static void
>> dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>> ARRAY_SIZE(hw_pp));
>> }
>> - for (i = 0; i < num_cwb; i++)
>> + for (i = 0; i < num_cwb; i++) {
>> dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
>> + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
>> + }
>> +
>> + dpu_enc->cwb_mask = cwb_mask;
>> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
>> @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct
>> dpu_encoder_phys *phys_enc)
>> }
>> }
>> + if (dpu_enc->cwb_mask)
>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, false);
>> +
>> /* reset the merge 3D HW block */
>> if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
>> phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc-
>> >hw_pp->merge_3d,
>> @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct
>> dpu_encoder_phys *phys_enc)
>> ctl->ops.clear_pending_flush(ctl);
>> }
>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys
>> *phys_enc,
>> + bool enable)
>> +{
>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc-
>> >parent);
>> + struct dpu_hw_cwb *hw_cwb;
>> + struct dpu_hw_cwb_setup_cfg cwb_cfg;
>> +
>> + struct dpu_kms *dpu_kms;
>> + struct dpu_global_state *global_state;
>> + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
>> + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
>> +
>> + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
>> + return;
>> +
>> + dpu_kms = phys_enc->dpu_kms;
>> + global_state = dpu_kms_get_existing_global_state(dpu_kms);
>> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>> + phys_enc->parent->crtc,
>> + DPU_HW_BLK_PINGPONG, rt_pp_list,
>> + ARRAY_SIZE(rt_pp_list));
>> +
>> + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
>> + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
>> + return;
>> + }
>> +
>> + for (int i = 0; i < num_pp; i++) {
>> + struct dpu_hw_pingpong *hw_pp =
>> to_dpu_hw_pingpong(rt_pp_list[i]);
>> +
>> + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
>> + hw_cwb = dpu_enc->hw_cwb[i];
>> +
>> + /*
>> + * Even CWB muxes must take input from even real-time
>> + * pingpongs and odd CWB muxes must take input from odd
>> + * pingpongs
>> + */
>> + if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
>
> When running igt-test on QRD8650, I get:
> # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt-
> gpu-tools/kms_writeback -d
Hi Neil,
Thanks for reporting this. Unfortunately, I'm not able to recreate this
on the MTP8650.
How many/which non-WB outputs are you testing with?
Also, can you share the IGT debug logs?
FWIW, I haven't had the chance to test with DP yet so that might be why
you're hitting this issue and I'm not.
Thanks,
Jessica Zhang
> [ 2566.668998] Console: switching to colour dummy device 80x25
> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79
> aarch64)
> [ 2566.674859] [IGT] kms_writeback: executing
> Using IGT_SRANDOM=1709057323 for randomisation
> Opened device: /dev/dri/card0
> [ 2566.741375] [IGT] kms_writeback: starting subtest dump-writeback
> Starting subtest: dump-writeback
> Subtest dump-writeback: SUCCESS (0.305s)[ 2567.053189] [IGT]
> kms_writeback: finished subtest dump-writeback, SUCCESS
>
> [ 2567.064505] [IGT] kms_writeback: starting subtest dump-valid-clones
> Starting subtest: dump-valid-clones
> [ 2567.762793] Unable to handle kernel NULL pointer dereference at
> virtual address 0000000000000010
> [ 2567.771919] Mem abort info:
> [ 2567.774888] ESR = 0x0000000096000006
> [ 2567.778831] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 2567.784371] SET = 0, FnV = 0
> [ 2567.787601] EA = 0, S1PTW = 0
> [ 2567.790942] FSC = 0x06: level 2 translation fault
> [ 2567.796044] Data abort info:
> [ 2567.799083] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
> [ 2567.804793] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [ 2567.810057] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [ 2567.815600] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008d60cf000
> [ 2567.822290] [0000000000000010] pgd=08000008d6049003,
> p4d=08000008d6049003, pud=080000089397e003, pmd=0000000000000000
> [ 2567.833254] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
> [ 2567.839747] Modules linked in: snd_soc_wsa884x q6prm_clocks
> q6apm_lpass_dais snd_q6dsp_common q6apm_dai q6prm 8021q garp mrp stp llc
> usb_f_fs libcomposite qrtr_mhi snd_soc_hdmi_codec ath12k mac80211
> libarc4 mhi panel_visionox_vtdr6130 snd_q6apm pci_pwrctl_pwrseq
> pci_pwrctl_core rpmsg_ctrl apr fastrpc qrtr_smd rpmsg_char wcd939x_usbss
> nb7vpq904m qcom_pd_mapper goodix_berlin_spi goodix_berlin_core
> ucsi_glink typec_ucsi pmic_glink_altmode aux_hpd_bridge qcom_battmgr
> leds_qcom_lpg msm ocmem drm_exec hci_uart qcom_pbs gpu_sched
> led_class_multicolor btqca phy_qcom_eusb2_repeater btbcm
> qcom_spmi_temp_alarm drm_dp_aux_bus phy_qcom_qmp_combo crct10dif_ce
> bluetooth drm_display_helper sm3_ce ecdh_generic aux_bridge sm3
> snd_soc_sc8280xp pwrseq_qcom_wcn sha3_ce snd_soc_qcom_sdw rtc_pm8xxx
> qcom_pon ecc nvmem_qcom_spmi_sdam sha512_ce qcom_stats spi_geni_qcom
> snd_soc_qcom_common sha512_arm64 pwrseq_core i2c_qcom_geni cfg80211
> drm_kms_helper dispcc_sm8550 gpi ipa snd_soc_lpass_va_macro
> snd_soc_lpass_tx_macro soundwire_qcom
> [ 2567.839860] pinctrl_sm8650_lpass_lpi snd_soc_lpass_wsa_macro
> snd_soc_lpass_rx_macro rfkill slimbus phy_qcom_snps_eusb2
> pinctrl_lpass_lpi gpucc_sm8650 snd_soc_lpass_macro_common qcom_q6v5_pas
> qcom_pil_info qcom_q6v5 qcrypto authenc icc_bwmon qcom_sysmon
> qcom_common qrtr qcom_glink_smem phy_qcom_qmp_pcie mdt_loader libdes
> llcc_qcom ufs_qcom phy_qcom_qmp_ufs pmic_glink snd_soc_wcd939x rmtfs_mem
> pdr_interface snd_soc_wcd939x_sdw regmap_sdw qcom_pdr_msg
> snd_soc_wcd_mbhc qmi_helpers snd_soc_wcd_classh soundwire_bus typec
> nvmem_reboot_mode qcom_rng socinfo fuse drm backlight ipv6
> [ 2567.983445] CPU: 5 UID: 0 PID: 554 Comm: kms_writeback Tainted: G
> S 6.12.0-rc1-00022-ge581f752bf79 #2
> [ 2567.994390] Tainted: [S]=CPU_OUT_OF_SPEC
> [ 2567.998483] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
> [ 2568.005244] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS
> BTYPE=--)
> [ 2568.012455] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
> [ 2568.019009] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
> [ 2568.025532] sp : ffff80008939b7e0
> [ 2568.028999] x29: ffff80008939b810 x28: ffffcbcb66f26068 x27:
> ffff37ad962cb080
> [ 2568.036388] x26: ffff37ad9887ed80 x25: ffff80008939b878 x24:
> ffff37ad43642a80
> [ 2568.043775] x23: 0000000000000000 x22: ffff37ad42812080 x21:
> ffff37ad43642a80
> [ 2568.051163] x20: ffff37ad962cb080 x19: ffff37ad962c8080 x18:
> 0000000000000001
> [ 2568.058552] x17: 000000040044ffff x16: ffffcbcbb0fc8c64 x15:
> 00003d08ffff9c00
> [ 2568.065939] x14: 00000013519b2832 x13: ffff37ad9d392200 x12:
> 000000000000000b
> [ 2568.073325] x11: ffff37ad40dc56c0 x10: ffff37ad9d392200 x9 :
> ffff37afbe7bba80
> [ 2568.080712] x8 : ffff37ad42812718 x7 : 0000000000000004 x6 :
> ffff37ad989ac798
> [ 2568.088098] x5 : 0000000000000002 x4 : ffff80008939b7f8 x3 :
> ffff37ad962cb150
> [ 2568.095480] x2 : 0000000000000002 x1 : 0000000000000000 x0 :
> 0000000000000001
> [ 2568.102868] Call trace:
> [ 2568.105446] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
> [ 2568.111608] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
> [ 2568.117692] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
> [ 2568.123233] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
> [ 2568.129224] disable_outputs+0x108/0x32c [drm_kms_helper]
> [ 2568.134858] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
> [drm_kms_helper]
> [ 2568.142614] msm_atomic_commit_tail+0x188/0x514 [msm]
> [ 2568.147894] commit_tail+0xa4/0x18c [drm_kms_helper]
> [ 2568.153065] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
> [ 2568.159482] drm_atomic_commit+0xb8/0xf4 [drm]
> [ 2568.164176] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
> [ 2568.169369] drm_ioctl_kernel+0xc0/0x128 [drm]
> [ 2568.174039] drm_ioctl+0x218/0x49c [drm]
> [ 2568.178165] __arm64_sys_ioctl+0xac/0xf0
> [ 2568.182271] invoke_syscall+0x48/0x10c
> [ 2568.186217] el0_svc_common.constprop.0+0xc0/0xe0
> [ 2568.191109] do_el0_svc+0x1c/0x28
> [ 2568.194576] el0_svc+0x34/0xd8
> [ 2568.197788] el0t_64_sync_handler+0x120/0x12c
> [ 2568.202321] el0t_64_sync+0x190/0x194
> [ 2568.206157] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
> [ 2568.212484] ---[ end trace 0000000000000000 ]---
>
> Neil
>
>> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
>> + break;
>> + }
>> + }
>> + }
>> +
>> + /*
>> + * The CWB mux supports using LM or DSPP as tap points. For now,
>> + * always use LM tap point
>> + */
>> + cwb_cfg.input = INPUT_MODE_LM_OUT;
>> +
>> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>> + hw_cwb = dpu_enc->hw_cwb[i];
>> + if (!hw_cwb)
>> + continue;
>> +
>> + cwb_cfg.pp_idx = rt_pp_idx[i];
>> +
>> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
>> + }
>> +}
>> +
>> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys
>> *phys_enc,
>> const struct msm_format *dpu_fmt,
>> u32 output_type)
>> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode
>> dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
>> return INTF_MODE_NONE;
>> }
>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys
>> *phys_enc)
>> +{
>> + struct drm_encoder *encoder = phys_enc->parent;
>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
>> +
>> + return dpu_enc->cwb_mask;
>> +}
>> +
>> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys
>> *phys_enc)
>> {
>> struct drm_encoder *encoder = phys_enc->parent;
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> index e77ebe3a68da..d7a02d1f8053 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> @@ -1,6 +1,6 @@
>> /* SPDX-License-Identifier: GPL-2.0-only */
>> /*
>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All
>> rights reserved.
>> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
>> */
>> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode
>> dpu_encoder_helper_get_3d_blend_mode(
>> return BLEND_3D_NONE;
>> }
>> +/**
>> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
>> + * @phys_enc: Pointer to physical encoder structure
>> + */
>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys
>> *phys_enc);
>> +
>> /**
>> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
>> * This helper function is used by physical encoder to get DSC
>> blocks mask
>> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct
>> dpu_encoder_phys *phys_enc,
>> */
>> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys
>> *phys_enc);
>> +/**
>> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
>> + * @phys_enc: Pointer to physical encoder structure
>> + * @enable: Enable CWB mux
>> + */
>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys
>> *phys_enc,
>> + bool enable);
>> +
>> /**
>> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
>> * @phys_enc: Pointer to physical encoder
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>> index 882c717859ce..e88c4d91041f 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>> @@ -1,6 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0-only
>> /*
>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All
>> rights reserved.
>> */
>> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
>> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt,
>> CDM_CDWN_OUTPUT_WB);
>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
>> +
>> dpu_encoder_phys_wb_setup_ctl(phys_enc);
>> }
>>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-09-30 19:19 ` Jessica Zhang
@ 2024-10-01 7:37 ` neil.armstrong
2024-10-08 8:00 ` Neil Armstrong
0 siblings, 1 reply; 64+ messages in thread
From: neil.armstrong @ 2024-10-01 7:37 UTC (permalink / raw)
To: Jessica Zhang, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
Hi,
On 30/09/2024 21:19, Jessica Zhang wrote:
>
>
> On 9/30/2024 7:17 AM, neil.armstrong@linaro.org wrote:
>> On 25/09/2024 00:59, Jessica Zhang wrote:
>>> Cache the CWB block mask in the DPU virtual encoder and configure CWB
>>> according to the CWB block mask within the writeback phys encoder
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 83 ++++++++++++ +++++++++-
>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 16 ++++-
>>> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +-
>>> 3 files changed, 100 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/ gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> index b2f0bf412451..2628f2d55cb3 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> @@ -24,6 +24,7 @@
>>> #include "dpu_hw_catalog.h"
>>> #include "dpu_hw_intf.h"
>>> #include "dpu_hw_ctl.h"
>>> +#include "dpu_hw_cwb.h"
>>> #include "dpu_hw_dspp.h"
>>> #include "dpu_hw_dsc.h"
>>> #include "dpu_hw_merge3d.h"
>>> @@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
>>> * num_phys_encs.
>>> * @hw_dsc: Handle to the DSC blocks used for the display.
>>> * @dsc_mask: Bitmask of used DSC blocks.
>>> + * @cwb_mask Bitmask of used CWB muxes
>>> * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
>>> * for partial update right-only cases, such as pingpong
>>> * split where virtual pingpong does not generate IRQs
>>> @@ -185,6 +187,7 @@ struct dpu_encoder_virt {
>>> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>>> unsigned int dsc_mask;
>>> + unsigned int cwb_mask;
>>> bool intfs_swapped;
>>> @@ -1063,6 +1066,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>>> int num_cwb = 0;
>>> bool is_cwb_encoder;
>>> unsigned int dsc_mask = 0;
>>> + unsigned int cwb_mask = 0;
>>> int i;
>>> if (!drm_enc) {
>>> @@ -1103,8 +1107,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
>>> ARRAY_SIZE(hw_pp));
>>> }
>>> - for (i = 0; i < num_cwb; i++)
>>> + for (i = 0; i < num_cwb; i++) {
>>> dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
>>> + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
>>> + }
>>> +
>>> + dpu_enc->cwb_mask = cwb_mask;
>>> dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>>> drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
>>> @@ -2071,6 +2079,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
>>> }
>>> }
>>> + if (dpu_enc->cwb_mask)
>>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, false);
>>> +
>>> /* reset the merge 3D HW block */
>>> if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
>>> phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc- >hw_pp->merge_3d,
>>> @@ -2114,6 +2125,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
>>> ctl->ops.clear_pending_flush(ctl);
>>> }
>>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
>>> + bool enable)
>>> +{
>>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc- >parent);
>>> + struct dpu_hw_cwb *hw_cwb;
>>> + struct dpu_hw_cwb_setup_cfg cwb_cfg;
>>> +
>>> + struct dpu_kms *dpu_kms;
>>> + struct dpu_global_state *global_state;
>>> + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
>>> + int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
>>> +
>>> + if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
>>> + return;
>>> +
>>> + dpu_kms = phys_enc->dpu_kms;
>>> + global_state = dpu_kms_get_existing_global_state(dpu_kms);
>>> + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
>>> + phys_enc->parent->crtc,
>>> + DPU_HW_BLK_PINGPONG, rt_pp_list,
>>> + ARRAY_SIZE(rt_pp_list));
>>> +
>>> + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
>>> + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
>>> + return;
>>> + }
>>> +
>>> + for (int i = 0; i < num_pp; i++) {
>>> + struct dpu_hw_pingpong *hw_pp = to_dpu_hw_pingpong(rt_pp_list[i]);
>>> +
>>> + for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
>>> + hw_cwb = dpu_enc->hw_cwb[i];
>>> +
>>> + /*
>>> + * Even CWB muxes must take input from even real-time
>>> + * pingpongs and odd CWB muxes must take input from odd
>>> + * pingpongs
>>> + */
>>> + if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
>>
>> When running igt-test on QRD8650, I get:
>> # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt- gpu-tools/kms_writeback -d
>
> Hi Neil,
>
> Thanks for reporting this. Unfortunately, I'm not able to recreate this on the MTP8650.
>
> How many/which non-WB outputs are you testing with?
Here's the modetest output:
==================><====================================================
Encoders:
id crtc type possible crtcs possible clones
32 103 DSI 0x00000007 0x00000005
34 0 TMDS 0x00000007 0x00000006
37 0 Virtual 0x00000007 0x00000007
Connectors:
id encoder status name size (mm) modes encoders
33 32 connected DSI-1 71x157 1 32
modes:
index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
#0 1080x2400 144.00 1080 1100 1102 1122 2400 2420 2422 2440 394225 flags: ; type: preferred, driver
props:
1 EDID:
flags: immutable blob
blobs:
value:
2 DPMS:
flags: enum
enums: On=0 Standby=1 Suspend=2 Off=3
value: 0
5 link-status:
flags: enum
enums: Good=0 Bad=1
value: 0
6 non-desktop:
flags: immutable range
values: 0 1
value: 0
4 TILE:
flags: immutable blob
blobs:
value:
35 0 disconnected DP-1 0x0 0 34
props:
1 EDID:
flags: immutable blob
blobs:
value:
2 DPMS:
flags: enum
enums: On=0 Standby=1 Suspend=2 Off=3
value: 0
5 link-status:
flags: enum
enums: Good=0 Bad=1
value: 0
6 non-desktop:
flags: immutable range
values: 0 1
value: 0
4 TILE:
flags: immutable blob
blobs:
value:
36 subconnector:
flags: immutable enum
enums: Unknown=0 VGA=1 DVI-D=3 HDMI=11 DP=10 Wireless=18 Native=15
value: 0
==================><====================================================
and dri state:
==================><====================================================
# cat /sys/kernel/debug/dri/0/state
plane[43]: plane-0
crtc=crtc-0
fb=106
allocated by = [fbcon]
refcount=2
format=XR24 little-endian (0x34325258)
modifier=0x0
size=1080x2400
layers:
size[0]=1080x2400
pitch[0]=4352
offset[0]=0
obj[0]:
name=0
refcount=1
start=0010102d
size=10444800
imported=no
crtc-pos=1080x2400+0+0
src-pos=1080.000000x2400.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=1
sspp[0]=sspp_0
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=1080x2400+0+0
dst[0]=1080x2400+0+0
plane[49]: plane-1
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_1
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[55]: plane-2
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_2
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[61]: plane-3
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_3
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[67]: plane-4
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_8
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[73]: plane-5
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_9
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[79]: plane-6
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_10
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[85]: plane-7
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_11
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[91]: plane-8
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_12
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
plane[97]: plane-9
crtc=(null)
fb=0
crtc-pos=0x0+0+0
src-pos=0.000000x0.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.601 YCbCr
color-range=YCbCr limited range
color_mgmt_changed=0
stage=0
sspp[0]=sspp_13
multirect_mode[0]=none
multirect_index[0]=solo
src[0]=0x0+0+0
dst[0]=0x0+0+0
crtc[103]: crtc-0
enable=1
active=1
self_refresh_active=0
planes_changed=1
mode_changed=0
active_changed=0
connectors_changed=0
color_mgmt_changed=0
plane_mask=1
connector_mask=1
encoder_mask=1
mode: "1080x2400": 144 394225 1080 1100 1102 1122 2400 2420 2422 2440 0x48 0x0
lm[0]=0
ctl[0]=2
crtc[104]: crtc-1
enable=0
active=0
self_refresh_active=0
planes_changed=0
mode_changed=0
active_changed=0
connectors_changed=0
color_mgmt_changed=0
plane_mask=0
connector_mask=0
encoder_mask=0
mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
crtc[105]: crtc-2
enable=0
active=0
self_refresh_active=0
planes_changed=0
mode_changed=0
active_changed=0
connectors_changed=0
color_mgmt_changed=0
plane_mask=0
connector_mask=0
encoder_mask=0
mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
connector[33]: DSI-1
crtc=crtc-0
self_refresh_aware=0
max_requested_bpc=0
colorspace=Default
connector[35]: DP-1
crtc=(null)
self_refresh_aware=0
max_requested_bpc=0
colorspace=Default
connector[42]: Writeback-1
crtc=(null)
self_refresh_aware=0
max_requested_bpc=0
colorspace=Default
resource mapping:
pingpong=103 # # # # # # # # # -
mixer=103 # # # # # -
ctl=# # 103 # # #
dspp=# # # #
dsc=# # # # # #
cdm=-
cwb=# # # #
==================><====================================================
I pasted all the kms_writeback log, I have nothing more.
If I specify `--run-subtest dump-valid-clones` I get:
==================><====================================================
IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=out.png /usr/libexec/igt-gpu-tools/kms_writeback -d --run-subtest dump-valid-clones
[ 33.250236] Console: switching to colour dummy device 80x25
IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79 aarch64)
Using IGT_SRANDOM=1709054789 for randomisation[ 33.256171] [IGT] kms_writeback: executing
Opened device: /dev/dri/card0
[ 33.360023] [IGT] kms_writeback: starting subtest dump-valid-clones
Starting subtest: dump-valid-clones
[ 34.063316] [drm:dpu_encoder_virt_atomic_disable:1314] [dpu error]enc32 timeout pending
[ 34.244272] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
[ 34.253385] Mem abort info:
[ 34.256328] ESR = 0x0000000096000006
[ 34.260272] EC = 0x25: DABT (current EL), IL = 32 bits
[ 34.265816] SET = 0, FnV = 0
[ 34.269043] EA = 0, S1PTW = 0
[ 34.272332] FSC = 0x06: level 2 translation fault
[ 34.277430] Data abort info:
[ 34.280460] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
[ 34.286170] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 34.291438] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 34.296975] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008824fc000
[ 34.303673] [0000000000000010] pgd=08000008dc4e0003, p4d=08000008dc4e0003, pud=08000008dd4af003, pmd=0000000000000000
[ 34.314647] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
[ 34.321144] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_dai q6apm_lpass_dais snd_q6dsp_common q6prm 8021q garp mrp stp llc usb_f_fs libcomposite qrtr_mhi snd_q6apm rpmsg_ctrl fastrpc apr qrtr_smd rpmsg_char snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi panel_visionox_vtdr6130 qcom_pd_mapper goodix_berlin_spi ucsi_glink pmic_glink_altmode pci_pwrctl_pwrseq pci_pwrctl_core typec_ucsi aux_hpd_bridge qcom_battmgr nb7vpq904m wcd939x_usbss goodix_berlin_core crct10dif_ce phy_qcom_eusb2_repeater msm sm3_ce sm3 qcom_q6v5_pas sha3_ce hci_uart sha512_ce sha512_arm64 leds_qcom_lpg ocmem qcom_pil_info qcom_q6v5 qcom_pbs btqca ipa btbcm drm_exec qcom_sysmon pwrseq_qcom_wcn snd_soc_sc8280xp led_class_multicolor snd_soc_qcom_sdw qrtr qcom_common gpu_sched snd_soc_wcd939x drm_dp_aux_bus qcom_spmi_temp_alarm snd_soc_qcom_common qcom_glink_smem snd_soc_wcd939x_sdw rtc_pm8xxx drm_display_helper pinctrl_sm8650_lpass_lpi regmap_sdw cfg80211 bluetooth qcom_pon pmic_glink ecdh_generic pdr_interface phy_qcom_qmp_combo ecc rfkill
[ 34.321268] nvmem_qcom_spmi_sdam qcom_stats spi_geni_qcom pwrseq_core i2c_qcom_geni aux_bridge phy_qcom_snps_eusb2 dispcc_sm8550 drm_kms_helper gpi soundwire_qcom snd_soc_lpass_va_macro pinctrl_lpass_lpi snd_soc_wcd_mbhc snd_soc_lpass_tx_macro snd_soc_lpass_rx_macro snd_soc_lpass_wsa_macro llcc_qcom snd_soc_lpass_macro_common slimbus snd_soc_wcd_classh mdt_loader qcom_pdr_msg qcrypto gpucc_sm8650 icc_bwmon qmi_helpers authenc phy_qcom_qmp_ufs libdes soundwire_bus ufs_qcom nvmem_reboot_mode phy_qcom_qmp_pcie typec qcom_rng rmtfs_mem socinfo fuse drm backlight ipv6
[ 34.464862] CPU: 5 UID: 0 PID: 513 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
[ 34.475812] Tainted: [S]=CPU_OUT_OF_SPEC
[ 34.479905] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
[ 34.486667] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
[ 34.493880] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
[ 34.500441] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
[ 34.506969] sp : ffff800085fc37e0
[ 34.510437] x29: ffff800085fc3810 x28: ffffb8c93c953068 x27: ffff5af315c90880
[ 34.517826] x26: ffff5af359c55780 x25: ffff800085fc3878 x24: ffff5af35a956e80
[ 34.525217] x23: 0000000000000000 x22: ffff5af355dc2080 x21: ffff5af35a956e80
[ 34.532607] x20: ffff5af315c90880 x19: ffff5af315c90c80 x18: 0000000000000001
[ 34.539997] x17: 0000000000000018 x16: ffffb8c95c9c8c64 x15: 0000000000000038
[ 34.547385] x14: 0000001971602a24 x13: 00000000000000e1 x12: 000000000000000b
[ 34.554774] x11: 0000000000000000 x10: e7125de8a27ae014 x9 : 5aef79bd13b1e2a7
[ 34.562162] x8 : ffff5af355dc2718 x7 : 0000000000000004 x6 : ffff5af356374d98
[ 34.569550] x5 : 0000000000000002 x4 : ffff800085fc37f8 x3 : ffff5af315c90950
[ 34.576938] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
[ 34.584328] Call trace:
[ 34.586905] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
[ 34.593075] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
[ 34.599165] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
[ 34.604713] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
[ 34.610711] disable_outputs+0x108/0x32c [drm_kms_helper]
[ 34.616351] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
[ 34.624110] msm_atomic_commit_tail+0x188/0x514 [msm]
[ 34.629396] commit_tail+0xa4/0x18c [drm_kms_helper]
[ 34.634570] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
[ 34.640990] drm_atomic_commit+0xb8/0xf4 [drm]
[ 34.645690] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
[ 34.650889] drm_ioctl_kernel+0xc0/0x128 [drm]
[ 34.655564] drm_ioctl+0x218/0x49c [drm]
[ 34.659697] __arm64_sys_ioctl+0xac/0xf0
[ 34.663804] invoke_syscall+0x48/0x10c
[ 34.667755] el0_svc_common.constprop.0+0xc0/0xe0
[ 34.672648] do_el0_svc+0x1c/0x28
[ 34.676117] el0_svc+0x34/0xd8
[ 34.679330] el0t_64_sync_handler+0x120/0x12c
[ 34.683864] el0t_64_sync+0x190/0x194
[ 34.687699] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
[ 34.694014] ---[ end trace 0000000000000000 ]---
==================><====================================================
Neil
>
> Also, can you share the IGT debug logs?
>
> FWIW, I haven't had the chance to test with DP yet so that might be why you're hitting this issue and I'm not.
>
> Thanks,
>
> Jessica Zhang
>
>> [ 2566.668998] Console: switching to colour dummy device 80x25
>> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79 aarch64)
>> [ 2566.674859] [IGT] kms_writeback: executing
>> Using IGT_SRANDOM=1709057323 for randomisation
>> Opened device: /dev/dri/card0
>> [ 2566.741375] [IGT] kms_writeback: starting subtest dump-writeback
>> Starting subtest: dump-writeback
>> Subtest dump-writeback: SUCCESS (0.305s)[ 2567.053189] [IGT] kms_writeback: finished subtest dump-writeback, SUCCESS
>>
>> [ 2567.064505] [IGT] kms_writeback: starting subtest dump-valid-clones
>> Starting subtest: dump-valid-clones
>> [ 2567.762793] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
>> [ 2567.771919] Mem abort info:
>> [ 2567.774888] ESR = 0x0000000096000006
>> [ 2567.778831] EC = 0x25: DABT (current EL), IL = 32 bits
>> [ 2567.784371] SET = 0, FnV = 0
>> [ 2567.787601] EA = 0, S1PTW = 0
>> [ 2567.790942] FSC = 0x06: level 2 translation fault
>> [ 2567.796044] Data abort info:
>> [ 2567.799083] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
>> [ 2567.804793] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>> [ 2567.810057] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>> [ 2567.815600] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008d60cf000
>> [ 2567.822290] [0000000000000010] pgd=08000008d6049003, p4d=08000008d6049003, pud=080000089397e003, pmd=0000000000000000
>> [ 2567.833254] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
>> [ 2567.839747] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_lpass_dais snd_q6dsp_common q6apm_dai q6prm 8021q garp mrp stp llc usb_f_fs libcomposite qrtr_mhi snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi panel_visionox_vtdr6130 snd_q6apm pci_pwrctl_pwrseq pci_pwrctl_core rpmsg_ctrl apr fastrpc qrtr_smd rpmsg_char wcd939x_usbss nb7vpq904m qcom_pd_mapper goodix_berlin_spi goodix_berlin_core ucsi_glink typec_ucsi pmic_glink_altmode aux_hpd_bridge qcom_battmgr leds_qcom_lpg msm ocmem drm_exec hci_uart qcom_pbs gpu_sched led_class_multicolor btqca phy_qcom_eusb2_repeater btbcm qcom_spmi_temp_alarm drm_dp_aux_bus phy_qcom_qmp_combo crct10dif_ce bluetooth drm_display_helper sm3_ce ecdh_generic aux_bridge sm3 snd_soc_sc8280xp pwrseq_qcom_wcn sha3_ce snd_soc_qcom_sdw rtc_pm8xxx qcom_pon ecc nvmem_qcom_spmi_sdam sha512_ce qcom_stats spi_geni_qcom snd_soc_qcom_common sha512_arm64 pwrseq_core i2c_qcom_geni cfg80211 drm_kms_helper dispcc_sm8550 gpi ipa snd_soc_lpass_va_macro
>> snd_soc_lpass_tx_macro soundwire_qcom
>> [ 2567.839860] pinctrl_sm8650_lpass_lpi snd_soc_lpass_wsa_macro snd_soc_lpass_rx_macro rfkill slimbus phy_qcom_snps_eusb2 pinctrl_lpass_lpi gpucc_sm8650 snd_soc_lpass_macro_common qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcrypto authenc icc_bwmon qcom_sysmon qcom_common qrtr qcom_glink_smem phy_qcom_qmp_pcie mdt_loader libdes llcc_qcom ufs_qcom phy_qcom_qmp_ufs pmic_glink snd_soc_wcd939x rmtfs_mem pdr_interface snd_soc_wcd939x_sdw regmap_sdw qcom_pdr_msg snd_soc_wcd_mbhc qmi_helpers snd_soc_wcd_classh soundwire_bus typec nvmem_reboot_mode qcom_rng socinfo fuse drm backlight ipv6
>> [ 2567.983445] CPU: 5 UID: 0 PID: 554 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
>> [ 2567.994390] Tainted: [S]=CPU_OUT_OF_SPEC
>> [ 2567.998483] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
>> [ 2568.005244] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
>> [ 2568.012455] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>> [ 2568.019009] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
>> [ 2568.025532] sp : ffff80008939b7e0
>> [ 2568.028999] x29: ffff80008939b810 x28: ffffcbcb66f26068 x27: ffff37ad962cb080
>> [ 2568.036388] x26: ffff37ad9887ed80 x25: ffff80008939b878 x24: ffff37ad43642a80
>> [ 2568.043775] x23: 0000000000000000 x22: ffff37ad42812080 x21: ffff37ad43642a80
>> [ 2568.051163] x20: ffff37ad962cb080 x19: ffff37ad962c8080 x18: 0000000000000001
>> [ 2568.058552] x17: 000000040044ffff x16: ffffcbcbb0fc8c64 x15: 00003d08ffff9c00
>> [ 2568.065939] x14: 00000013519b2832 x13: ffff37ad9d392200 x12: 000000000000000b
>> [ 2568.073325] x11: ffff37ad40dc56c0 x10: ffff37ad9d392200 x9 : ffff37afbe7bba80
>> [ 2568.080712] x8 : ffff37ad42812718 x7 : 0000000000000004 x6 : ffff37ad989ac798
>> [ 2568.088098] x5 : 0000000000000002 x4 : ffff80008939b7f8 x3 : ffff37ad962cb150
>> [ 2568.095480] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
>> [ 2568.102868] Call trace:
>> [ 2568.105446] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>> [ 2568.111608] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
>> [ 2568.117692] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
>> [ 2568.123233] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
>> [ 2568.129224] disable_outputs+0x108/0x32c [drm_kms_helper]
>> [ 2568.134858] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
>> [ 2568.142614] msm_atomic_commit_tail+0x188/0x514 [msm]
>> [ 2568.147894] commit_tail+0xa4/0x18c [drm_kms_helper]
>> [ 2568.153065] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
>> [ 2568.159482] drm_atomic_commit+0xb8/0xf4 [drm]
>> [ 2568.164176] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
>> [ 2568.169369] drm_ioctl_kernel+0xc0/0x128 [drm]
>> [ 2568.174039] drm_ioctl+0x218/0x49c [drm]
>> [ 2568.178165] __arm64_sys_ioctl+0xac/0xf0
>> [ 2568.182271] invoke_syscall+0x48/0x10c
>> [ 2568.186217] el0_svc_common.constprop.0+0xc0/0xe0
>> [ 2568.191109] do_el0_svc+0x1c/0x28
>> [ 2568.194576] el0_svc+0x34/0xd8
>> [ 2568.197788] el0t_64_sync_handler+0x120/0x12c
>> [ 2568.202321] el0t_64_sync+0x190/0x194
>> [ 2568.206157] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
>> [ 2568.212484] ---[ end trace 0000000000000000 ]---
>>
>> Neil
>>
>>> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
>>> + break;
>>> + }
>>> + }
>>> + }
>>> +
>>> + /*
>>> + * The CWB mux supports using LM or DSPP as tap points. For now,
>>> + * always use LM tap point
>>> + */
>>> + cwb_cfg.input = INPUT_MODE_LM_OUT;
>>> +
>>> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>>> + hw_cwb = dpu_enc->hw_cwb[i];
>>> + if (!hw_cwb)
>>> + continue;
>>> +
>>> + cwb_cfg.pp_idx = rt_pp_idx[i];
>>> +
>>> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
>>> + }
>>> +}
>>> +
>>> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
>>> const struct msm_format *dpu_fmt,
>>> u32 output_type)
>>> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
>>> return INTF_MODE_NONE;
>>> }
>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
>>> +{
>>> + struct drm_encoder *encoder = phys_enc->parent;
>>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
>>> +
>>> + return dpu_enc->cwb_mask;
>>> +}
>>> +
>>> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
>>> {
>>> struct drm_encoder *encoder = phys_enc->parent;
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>> index e77ebe3a68da..d7a02d1f8053 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>> @@ -1,6 +1,6 @@
>>> /* SPDX-License-Identifier: GPL-2.0-only */
>>> /*
>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
>>> */
>>> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
>>> return BLEND_3D_NONE;
>>> }
>>> +/**
>>> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
>>> + * @phys_enc: Pointer to physical encoder structure
>>> + */
>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
>>> +
>>> /**
>>> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
>>> * This helper function is used by physical encoder to get DSC blocks mask
>>> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
>>> */
>>> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
>>> +/**
>>> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
>>> + * @phys_enc: Pointer to physical encoder structure
>>> + * @enable: Enable CWB mux
>>> + */
>>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
>>> + bool enable);
>>> +
>>> /**
>>> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
>>> * @phys_enc: Pointer to physical encoder
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>> index 882c717859ce..e88c4d91041f 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>> @@ -1,6 +1,6 @@
>>> // SPDX-License-Identifier: GPL-2.0-only
>>> /*
>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>> */
>>> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
>>> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>>> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
>>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
>>> +
>>> dpu_encoder_phys_wb_setup_ctl(phys_enc);
>>> }
>>>
>>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-10-01 7:37 ` neil.armstrong
@ 2024-10-08 8:00 ` Neil Armstrong
2024-10-08 8:18 ` Maxime Ripard
2024-10-08 12:25 ` Jessica Zhang
0 siblings, 2 replies; 64+ messages in thread
From: Neil Armstrong @ 2024-10-08 8:00 UTC (permalink / raw)
To: Jessica Zhang, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
Hi,
On 01/10/2024 09:37, neil.armstrong@linaro.org wrote:
> Hi,
>
> On 30/09/2024 21:19, Jessica Zhang wrote:
>>
>>
>> On 9/30/2024 7:17 AM, neil.armstrong@linaro.org wrote:
>>> On 25/09/2024 00:59, Jessica Zhang wrote:
<snip>
>>>
>>> When running igt-test on QRD8650, I get:
>>> # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt- gpu-tools/kms_writeback -d
>>
>> Hi Neil,
>>
>> Thanks for reporting this. Unfortunately, I'm not able to recreate this on the MTP8650.
>>
>> How many/which non-WB outputs are you testing with?
>
> Here's the modetest output:
> ==================><====================================================
> Encoders:
> id crtc type possible crtcs possible clones
> 32 103 DSI 0x00000007 0x00000005
> 34 0 TMDS 0x00000007 0x00000006
> 37 0 Virtual 0x00000007 0x00000007
>
> Connectors:
> id encoder status name size (mm) modes encoders
> 33 32 connected DSI-1 71x157 1 32
> modes:
> index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
> #0 1080x2400 144.00 1080 1100 1102 1122 2400 2420 2422 2440 394225 flags: ; type: preferred, driver
> props:
> 1 EDID:
> flags: immutable blob
> blobs:
>
> value:
> 2 DPMS:
> flags: enum
> enums: On=0 Standby=1 Suspend=2 Off=3
> value: 0
> 5 link-status:
> flags: enum
> enums: Good=0 Bad=1
> value: 0
> 6 non-desktop:
> flags: immutable range
> values: 0 1
> value: 0
> 4 TILE:
> flags: immutable blob
> blobs:
>
> value:
> 35 0 disconnected DP-1 0x0 0 34
> props:
> 1 EDID:
> flags: immutable blob
> blobs:
>
> value:
> 2 DPMS:
> flags: enum
> enums: On=0 Standby=1 Suspend=2 Off=3
> value: 0
> 5 link-status:
> flags: enum
> enums: Good=0 Bad=1
> value: 0
> 6 non-desktop:
> flags: immutable range
> values: 0 1
> value: 0
> 4 TILE:
> flags: immutable blob
> blobs:
>
> value:
> 36 subconnector:
> flags: immutable enum
> enums: Unknown=0 VGA=1 DVI-D=3 HDMI=11 DP=10 Wireless=18 Native=15
> value: 0
> ==================><====================================================
>
> and dri state:
> ==================><====================================================
> # cat /sys/kernel/debug/dri/0/state
> plane[43]: plane-0
> crtc=crtc-0
> fb=106
> allocated by = [fbcon]
> refcount=2
> format=XR24 little-endian (0x34325258)
> modifier=0x0
> size=1080x2400
> layers:
> size[0]=1080x2400
> pitch[0]=4352
> offset[0]=0
> obj[0]:
> name=0
> refcount=1
> start=0010102d
> size=10444800
> imported=no
> crtc-pos=1080x2400+0+0
> src-pos=1080.000000x2400.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=1
> sspp[0]=sspp_0
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=1080x2400+0+0
> dst[0]=1080x2400+0+0
> plane[49]: plane-1
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_1
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[55]: plane-2
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_2
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[61]: plane-3
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_3
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[67]: plane-4
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_8
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[73]: plane-5
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_9
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[79]: plane-6
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_10
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[85]: plane-7
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_11
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[91]: plane-8
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_12
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> plane[97]: plane-9
> crtc=(null)
> fb=0
> crtc-pos=0x0+0+0
> src-pos=0.000000x0.000000+0.000000+0.000000
> rotation=1
> normalized-zpos=0
> color-encoding=ITU-R BT.601 YCbCr
> color-range=YCbCr limited range
> color_mgmt_changed=0
> stage=0
> sspp[0]=sspp_13
> multirect_mode[0]=none
> multirect_index[0]=solo
> src[0]=0x0+0+0
> dst[0]=0x0+0+0
> crtc[103]: crtc-0
> enable=1
> active=1
> self_refresh_active=0
> planes_changed=1
> mode_changed=0
> active_changed=0
> connectors_changed=0
> color_mgmt_changed=0
> plane_mask=1
> connector_mask=1
> encoder_mask=1
> mode: "1080x2400": 144 394225 1080 1100 1102 1122 2400 2420 2422 2440 0x48 0x0
> lm[0]=0
> ctl[0]=2
> crtc[104]: crtc-1
> enable=0
> active=0
> self_refresh_active=0
> planes_changed=0
> mode_changed=0
> active_changed=0
> connectors_changed=0
> color_mgmt_changed=0
> plane_mask=0
> connector_mask=0
> encoder_mask=0
> mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
> crtc[105]: crtc-2
> enable=0
> active=0
> self_refresh_active=0
> planes_changed=0
> mode_changed=0
> active_changed=0
> connectors_changed=0
> color_mgmt_changed=0
> plane_mask=0
> connector_mask=0
> encoder_mask=0
> mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
> connector[33]: DSI-1
> crtc=crtc-0
> self_refresh_aware=0
> max_requested_bpc=0
> colorspace=Default
> connector[35]: DP-1
> crtc=(null)
> self_refresh_aware=0
> max_requested_bpc=0
> colorspace=Default
> connector[42]: Writeback-1
> crtc=(null)
> self_refresh_aware=0
> max_requested_bpc=0
> colorspace=Default
> resource mapping:
> pingpong=103 # # # # # # # # # -
> mixer=103 # # # # # -
> ctl=# # 103 # # #
> dspp=# # # #
> dsc=# # # # # #
> cdm=-
> cwb=# # # #
> ==================><====================================================
>
> I pasted all the kms_writeback log, I have nothing more.
>
> If I specify `--run-subtest dump-valid-clones` I get:
> ==================><====================================================
> IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=out.png /usr/libexec/igt-gpu-tools/kms_writeback -d --run-subtest dump-valid-clones
> [ 33.250236] Console: switching to colour dummy device 80x25
> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79 aarch64)
> Using IGT_SRANDOM=1709054789 for randomisation[ 33.256171] [IGT] kms_writeback: executing
>
> Opened device: /dev/dri/card0
> [ 33.360023] [IGT] kms_writeback: starting subtest dump-valid-clones
> Starting subtest: dump-valid-clones
> [ 34.063316] [drm:dpu_encoder_virt_atomic_disable:1314] [dpu error]enc32 timeout pending
> [ 34.244272] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
> [ 34.253385] Mem abort info:
> [ 34.256328] ESR = 0x0000000096000006
> [ 34.260272] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 34.265816] SET = 0, FnV = 0
> [ 34.269043] EA = 0, S1PTW = 0
> [ 34.272332] FSC = 0x06: level 2 translation fault
> [ 34.277430] Data abort info:
> [ 34.280460] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
> [ 34.286170] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [ 34.291438] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [ 34.296975] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008824fc000
> [ 34.303673] [0000000000000010] pgd=08000008dc4e0003, p4d=08000008dc4e0003, pud=08000008dd4af003, pmd=0000000000000000
> [ 34.314647] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
> [ 34.321144] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_dai q6apm_lpass_dais snd_q6dsp_common q6prm 8021q garp mrp stp llc usb_f_fs libcomposite qrtr_mhi snd_q6apm rpmsg_ctrl fastrpc apr qrtr_smd rpmsg_char snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi panel_visionox_vtdr6130 qcom_pd_mapper goodix_berlin_spi ucsi_glink pmic_glink_altmode pci_pwrctl_pwrseq pci_pwrctl_core typec_ucsi aux_hpd_bridge qcom_battmgr nb7vpq904m wcd939x_usbss goodix_berlin_core crct10dif_ce phy_qcom_eusb2_repeater msm sm3_ce sm3 qcom_q6v5_pas sha3_ce hci_uart sha512_ce sha512_arm64 leds_qcom_lpg ocmem qcom_pil_info qcom_q6v5 qcom_pbs btqca ipa btbcm drm_exec qcom_sysmon pwrseq_qcom_wcn snd_soc_sc8280xp led_class_multicolor snd_soc_qcom_sdw qrtr qcom_common gpu_sched snd_soc_wcd939x drm_dp_aux_bus qcom_spmi_temp_alarm snd_soc_qcom_common qcom_glink_smem snd_soc_wcd939x_sdw rtc_pm8xxx drm_display_helper pinctrl_sm8650_lpass_lpi regmap_sdw cfg80211 bluetooth qcom_pon pmic_glink ecdh_generic
> pdr_interface phy_qcom_qmp_combo ecc rfkill
> [ 34.321268] nvmem_qcom_spmi_sdam qcom_stats spi_geni_qcom pwrseq_core i2c_qcom_geni aux_bridge phy_qcom_snps_eusb2 dispcc_sm8550 drm_kms_helper gpi soundwire_qcom snd_soc_lpass_va_macro pinctrl_lpass_lpi snd_soc_wcd_mbhc snd_soc_lpass_tx_macro snd_soc_lpass_rx_macro snd_soc_lpass_wsa_macro llcc_qcom snd_soc_lpass_macro_common slimbus snd_soc_wcd_classh mdt_loader qcom_pdr_msg qcrypto gpucc_sm8650 icc_bwmon qmi_helpers authenc phy_qcom_qmp_ufs libdes soundwire_bus ufs_qcom nvmem_reboot_mode phy_qcom_qmp_pcie typec qcom_rng rmtfs_mem socinfo fuse drm backlight ipv6
> [ 34.464862] CPU: 5 UID: 0 PID: 513 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
> [ 34.475812] Tainted: [S]=CPU_OUT_OF_SPEC
> [ 34.479905] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
> [ 34.486667] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> [ 34.493880] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
> [ 34.500441] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
> [ 34.506969] sp : ffff800085fc37e0
> [ 34.510437] x29: ffff800085fc3810 x28: ffffb8c93c953068 x27: ffff5af315c90880
> [ 34.517826] x26: ffff5af359c55780 x25: ffff800085fc3878 x24: ffff5af35a956e80
> [ 34.525217] x23: 0000000000000000 x22: ffff5af355dc2080 x21: ffff5af35a956e80
> [ 34.532607] x20: ffff5af315c90880 x19: ffff5af315c90c80 x18: 0000000000000001
> [ 34.539997] x17: 0000000000000018 x16: ffffb8c95c9c8c64 x15: 0000000000000038
> [ 34.547385] x14: 0000001971602a24 x13: 00000000000000e1 x12: 000000000000000b
> [ 34.554774] x11: 0000000000000000 x10: e7125de8a27ae014 x9 : 5aef79bd13b1e2a7
> [ 34.562162] x8 : ffff5af355dc2718 x7 : 0000000000000004 x6 : ffff5af356374d98
> [ 34.569550] x5 : 0000000000000002 x4 : ffff800085fc37f8 x3 : ffff5af315c90950
> [ 34.576938] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
> [ 34.584328] Call trace:
> [ 34.586905] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
> [ 34.593075] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
> [ 34.599165] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
> [ 34.604713] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
> [ 34.610711] disable_outputs+0x108/0x32c [drm_kms_helper]
> [ 34.616351] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
> [ 34.624110] msm_atomic_commit_tail+0x188/0x514 [msm]
> [ 34.629396] commit_tail+0xa4/0x18c [drm_kms_helper]
> [ 34.634570] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
> [ 34.640990] drm_atomic_commit+0xb8/0xf4 [drm]
> [ 34.645690] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
> [ 34.650889] drm_ioctl_kernel+0xc0/0x128 [drm]
> [ 34.655564] drm_ioctl+0x218/0x49c [drm]
> [ 34.659697] __arm64_sys_ioctl+0xac/0xf0
> [ 34.663804] invoke_syscall+0x48/0x10c
> [ 34.667755] el0_svc_common.constprop.0+0xc0/0xe0
> [ 34.672648] do_el0_svc+0x1c/0x28
> [ 34.676117] el0_svc+0x34/0xd8
> [ 34.679330] el0t_64_sync_handler+0x120/0x12c
> [ 34.683864] el0t_64_sync+0x190/0x194
> [ 34.687699] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
> [ 34.694014] ---[ end trace 0000000000000000 ]---
> ==================><====================================================
Anything I can try to get past the crash ?
Thanks,
Neil
>
> Neil
>
>>
>> Also, can you share the IGT debug logs?
>>
>> FWIW, I haven't had the chance to test with DP yet so that might be why you're hitting this issue and I'm not.
>>
>> Thanks,
>>
>> Jessica Zhang
>>
>>> [ 2566.668998] Console: switching to colour dummy device 80x25
>>> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79 aarch64)
>>> [ 2566.674859] [IGT] kms_writeback: executing
>>> Using IGT_SRANDOM=1709057323 for randomisation
>>> Opened device: /dev/dri/card0
>>> [ 2566.741375] [IGT] kms_writeback: starting subtest dump-writeback
>>> Starting subtest: dump-writeback
>>> Subtest dump-writeback: SUCCESS (0.305s)[ 2567.053189] [IGT] kms_writeback: finished subtest dump-writeback, SUCCESS
>>>
>>> [ 2567.064505] [IGT] kms_writeback: starting subtest dump-valid-clones
>>> Starting subtest: dump-valid-clones
>>> [ 2567.762793] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
>>> [ 2567.771919] Mem abort info:
>>> [ 2567.774888] ESR = 0x0000000096000006
>>> [ 2567.778831] EC = 0x25: DABT (current EL), IL = 32 bits
>>> [ 2567.784371] SET = 0, FnV = 0
>>> [ 2567.787601] EA = 0, S1PTW = 0
>>> [ 2567.790942] FSC = 0x06: level 2 translation fault
>>> [ 2567.796044] Data abort info:
>>> [ 2567.799083] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
>>> [ 2567.804793] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>>> [ 2567.810057] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>>> [ 2567.815600] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008d60cf000
>>> [ 2567.822290] [0000000000000010] pgd=08000008d6049003, p4d=08000008d6049003, pud=080000089397e003, pmd=0000000000000000
>>> [ 2567.833254] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
>>> [ 2567.839747] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_lpass_dais snd_q6dsp_common q6apm_dai q6prm 8021q garp mrp stp llc usb_f_fs libcomposite qrtr_mhi snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi panel_visionox_vtdr6130 snd_q6apm pci_pwrctl_pwrseq pci_pwrctl_core rpmsg_ctrl apr fastrpc qrtr_smd rpmsg_char wcd939x_usbss nb7vpq904m qcom_pd_mapper goodix_berlin_spi goodix_berlin_core ucsi_glink typec_ucsi pmic_glink_altmode aux_hpd_bridge qcom_battmgr leds_qcom_lpg msm ocmem drm_exec hci_uart qcom_pbs gpu_sched led_class_multicolor btqca phy_qcom_eusb2_repeater btbcm qcom_spmi_temp_alarm drm_dp_aux_bus phy_qcom_qmp_combo crct10dif_ce bluetooth drm_display_helper sm3_ce ecdh_generic aux_bridge sm3 snd_soc_sc8280xp pwrseq_qcom_wcn sha3_ce snd_soc_qcom_sdw rtc_pm8xxx qcom_pon ecc nvmem_qcom_spmi_sdam sha512_ce qcom_stats spi_geni_qcom snd_soc_qcom_common sha512_arm64 pwrseq_core i2c_qcom_geni cfg80211 drm_kms_helper dispcc_sm8550 gpi ipa snd_soc_lpass_va_macro
>>> snd_soc_lpass_tx_macro soundwire_qcom
>>> [ 2567.839860] pinctrl_sm8650_lpass_lpi snd_soc_lpass_wsa_macro snd_soc_lpass_rx_macro rfkill slimbus phy_qcom_snps_eusb2 pinctrl_lpass_lpi gpucc_sm8650 snd_soc_lpass_macro_common qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcrypto authenc icc_bwmon qcom_sysmon qcom_common qrtr qcom_glink_smem phy_qcom_qmp_pcie mdt_loader libdes llcc_qcom ufs_qcom phy_qcom_qmp_ufs pmic_glink snd_soc_wcd939x rmtfs_mem pdr_interface snd_soc_wcd939x_sdw regmap_sdw qcom_pdr_msg snd_soc_wcd_mbhc qmi_helpers snd_soc_wcd_classh soundwire_bus typec nvmem_reboot_mode qcom_rng socinfo fuse drm backlight ipv6
>>> [ 2567.983445] CPU: 5 UID: 0 PID: 554 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
>>> [ 2567.994390] Tainted: [S]=CPU_OUT_OF_SPEC
>>> [ 2567.998483] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
>>> [ 2568.005244] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
>>> [ 2568.012455] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>>> [ 2568.019009] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
>>> [ 2568.025532] sp : ffff80008939b7e0
>>> [ 2568.028999] x29: ffff80008939b810 x28: ffffcbcb66f26068 x27: ffff37ad962cb080
>>> [ 2568.036388] x26: ffff37ad9887ed80 x25: ffff80008939b878 x24: ffff37ad43642a80
>>> [ 2568.043775] x23: 0000000000000000 x22: ffff37ad42812080 x21: ffff37ad43642a80
>>> [ 2568.051163] x20: ffff37ad962cb080 x19: ffff37ad962c8080 x18: 0000000000000001
>>> [ 2568.058552] x17: 000000040044ffff x16: ffffcbcbb0fc8c64 x15: 00003d08ffff9c00
>>> [ 2568.065939] x14: 00000013519b2832 x13: ffff37ad9d392200 x12: 000000000000000b
>>> [ 2568.073325] x11: ffff37ad40dc56c0 x10: ffff37ad9d392200 x9 : ffff37afbe7bba80
>>> [ 2568.080712] x8 : ffff37ad42812718 x7 : 0000000000000004 x6 : ffff37ad989ac798
>>> [ 2568.088098] x5 : 0000000000000002 x4 : ffff80008939b7f8 x3 : ffff37ad962cb150
>>> [ 2568.095480] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
>>> [ 2568.102868] Call trace:
>>> [ 2568.105446] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>>> [ 2568.111608] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
>>> [ 2568.117692] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
>>> [ 2568.123233] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
>>> [ 2568.129224] disable_outputs+0x108/0x32c [drm_kms_helper]
>>> [ 2568.134858] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
>>> [ 2568.142614] msm_atomic_commit_tail+0x188/0x514 [msm]
>>> [ 2568.147894] commit_tail+0xa4/0x18c [drm_kms_helper]
>>> [ 2568.153065] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
>>> [ 2568.159482] drm_atomic_commit+0xb8/0xf4 [drm]
>>> [ 2568.164176] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
>>> [ 2568.169369] drm_ioctl_kernel+0xc0/0x128 [drm]
>>> [ 2568.174039] drm_ioctl+0x218/0x49c [drm]
>>> [ 2568.178165] __arm64_sys_ioctl+0xac/0xf0
>>> [ 2568.182271] invoke_syscall+0x48/0x10c
>>> [ 2568.186217] el0_svc_common.constprop.0+0xc0/0xe0
>>> [ 2568.191109] do_el0_svc+0x1c/0x28
>>> [ 2568.194576] el0_svc+0x34/0xd8
>>> [ 2568.197788] el0t_64_sync_handler+0x120/0x12c
>>> [ 2568.202321] el0t_64_sync+0x190/0x194
>>> [ 2568.206157] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
>>> [ 2568.212484] ---[ end trace 0000000000000000 ]---
>>>
>>> Neil
>>>
>>>> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
>>>> + break;
>>>> + }
>>>> + }
>>>> + }
>>>> +
>>>> + /*
>>>> + * The CWB mux supports using LM or DSPP as tap points. For now,
>>>> + * always use LM tap point
>>>> + */
>>>> + cwb_cfg.input = INPUT_MODE_LM_OUT;
>>>> +
>>>> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>>>> + hw_cwb = dpu_enc->hw_cwb[i];
>>>> + if (!hw_cwb)
>>>> + continue;
>>>> +
>>>> + cwb_cfg.pp_idx = rt_pp_idx[i];
>>>> +
>>>> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
>>>> + }
>>>> +}
>>>> +
>>>> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
>>>> const struct msm_format *dpu_fmt,
>>>> u32 output_type)
>>>> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
>>>> return INTF_MODE_NONE;
>>>> }
>>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
>>>> +{
>>>> + struct drm_encoder *encoder = phys_enc->parent;
>>>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
>>>> +
>>>> + return dpu_enc->cwb_mask;
>>>> +}
>>>> +
>>>> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
>>>> {
>>>> struct drm_encoder *encoder = phys_enc->parent;
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>> index e77ebe3a68da..d7a02d1f8053 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>> @@ -1,6 +1,6 @@
>>>> /* SPDX-License-Identifier: GPL-2.0-only */
>>>> /*
>>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>>> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
>>>> */
>>>> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
>>>> return BLEND_3D_NONE;
>>>> }
>>>> +/**
>>>> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
>>>> + * @phys_enc: Pointer to physical encoder structure
>>>> + */
>>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
>>>> +
>>>> /**
>>>> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
>>>> * This helper function is used by physical encoder to get DSC blocks mask
>>>> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
>>>> */
>>>> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
>>>> +/**
>>>> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
>>>> + * @phys_enc: Pointer to physical encoder structure
>>>> + * @enable: Enable CWB mux
>>>> + */
>>>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
>>>> + bool enable);
>>>> +
>>>> /**
>>>> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
>>>> * @phys_enc: Pointer to physical encoder
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>> index 882c717859ce..e88c4d91041f 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>> @@ -1,6 +1,6 @@
>>>> // SPDX-License-Identifier: GPL-2.0-only
>>>> /*
>>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>>> */
>>>> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
>>>> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>>>> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
>>>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
>>>> +
>>>> dpu_encoder_phys_wb_setup_ctl(phys_enc);
>>>> }
>>>>
>>>
>>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-10-08 8:00 ` Neil Armstrong
@ 2024-10-08 8:18 ` Maxime Ripard
2024-10-08 12:25 ` Jessica Zhang
1 sibling, 0 replies; 64+ messages in thread
From: Maxime Ripard @ 2024-10-08 8:18 UTC (permalink / raw)
To: Neil Armstrong
Cc: Jessica Zhang, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Thomas Zimmermann, quic_ebharadw,
linux-arm-msm, dri-devel, freedreno, linux-kernel, Rob Clark,
Ville Syrjälä
[-- Attachment #1: Type: text/plain, Size: 16536 bytes --]
On Tue, Oct 08, 2024 at 10:00:57AM GMT, Neil Armstrong wrote:
> Hi,
>
> On 01/10/2024 09:37, neil.armstrong@linaro.org wrote:
> > Hi,
> >
> > On 30/09/2024 21:19, Jessica Zhang wrote:
> > >
> > >
> > > On 9/30/2024 7:17 AM, neil.armstrong@linaro.org wrote:
> > > > On 25/09/2024 00:59, Jessica Zhang wrote:
>
> <snip>
>
> > > >
> > > > When running igt-test on QRD8650, I get:
> > > > # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/igt- gpu-tools/kms_writeback -d
> > >
> > > Hi Neil,
> > >
> > > Thanks for reporting this. Unfortunately, I'm not able to recreate this on the MTP8650.
> > >
> > > How many/which non-WB outputs are you testing with?
> >
> > Here's the modetest output:
> > ==================><====================================================
> > Encoders:
> > id crtc type possible crtcs possible clones
> > 32 103 DSI 0x00000007 0x00000005
> > 34 0 TMDS 0x00000007 0x00000006
> > 37 0 Virtual 0x00000007 0x00000007
> >
> > Connectors:
> > id encoder status name size (mm) modes encoders
> > 33 32 connected DSI-1 71x157 1 32
> > modes:
> > index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
> > #0 1080x2400 144.00 1080 1100 1102 1122 2400 2420 2422 2440 394225 flags: ; type: preferred, driver
> > props:
> > 1 EDID:
> > flags: immutable blob
> > blobs:
> >
> > value:
> > 2 DPMS:
> > flags: enum
> > enums: On=0 Standby=1 Suspend=2 Off=3
> > value: 0
> > 5 link-status:
> > flags: enum
> > enums: Good=0 Bad=1
> > value: 0
> > 6 non-desktop:
> > flags: immutable range
> > values: 0 1
> > value: 0
> > 4 TILE:
> > flags: immutable blob
> > blobs:
> >
> > value:
> > 35 0 disconnected DP-1 0x0 0 34
> > props:
> > 1 EDID:
> > flags: immutable blob
> > blobs:
> >
> > value:
> > 2 DPMS:
> > flags: enum
> > enums: On=0 Standby=1 Suspend=2 Off=3
> > value: 0
> > 5 link-status:
> > flags: enum
> > enums: Good=0 Bad=1
> > value: 0
> > 6 non-desktop:
> > flags: immutable range
> > values: 0 1
> > value: 0
> > 4 TILE:
> > flags: immutable blob
> > blobs:
> >
> > value:
> > 36 subconnector:
> > flags: immutable enum
> > enums: Unknown=0 VGA=1 DVI-D=3 HDMI=11 DP=10 Wireless=18 Native=15
> > value: 0
> > ==================><====================================================
> >
> > and dri state:
> > ==================><====================================================
> > # cat /sys/kernel/debug/dri/0/state
> > plane[43]: plane-0
> > crtc=crtc-0
> > fb=106
> > allocated by = [fbcon]
> > refcount=2
> > format=XR24 little-endian (0x34325258)
> > modifier=0x0
> > size=1080x2400
> > layers:
> > size[0]=1080x2400
> > pitch[0]=4352
> > offset[0]=0
> > obj[0]:
> > name=0
> > refcount=1
> > start=0010102d
> > size=10444800
> > imported=no
> > crtc-pos=1080x2400+0+0
> > src-pos=1080.000000x2400.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=1
> > sspp[0]=sspp_0
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=1080x2400+0+0
> > dst[0]=1080x2400+0+0
> > plane[49]: plane-1
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_1
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[55]: plane-2
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_2
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[61]: plane-3
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_3
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[67]: plane-4
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_8
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[73]: plane-5
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_9
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[79]: plane-6
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_10
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[85]: plane-7
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_11
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[91]: plane-8
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_12
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > plane[97]: plane-9
> > crtc=(null)
> > fb=0
> > crtc-pos=0x0+0+0
> > src-pos=0.000000x0.000000+0.000000+0.000000
> > rotation=1
> > normalized-zpos=0
> > color-encoding=ITU-R BT.601 YCbCr
> > color-range=YCbCr limited range
> > color_mgmt_changed=0
> > stage=0
> > sspp[0]=sspp_13
> > multirect_mode[0]=none
> > multirect_index[0]=solo
> > src[0]=0x0+0+0
> > dst[0]=0x0+0+0
> > crtc[103]: crtc-0
> > enable=1
> > active=1
> > self_refresh_active=0
> > planes_changed=1
> > mode_changed=0
> > active_changed=0
> > connectors_changed=0
> > color_mgmt_changed=0
> > plane_mask=1
> > connector_mask=1
> > encoder_mask=1
> > mode: "1080x2400": 144 394225 1080 1100 1102 1122 2400 2420 2422 2440 0x48 0x0
> > lm[0]=0
> > ctl[0]=2
> > crtc[104]: crtc-1
> > enable=0
> > active=0
> > self_refresh_active=0
> > planes_changed=0
> > mode_changed=0
> > active_changed=0
> > connectors_changed=0
> > color_mgmt_changed=0
> > plane_mask=0
> > connector_mask=0
> > encoder_mask=0
> > mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
> > crtc[105]: crtc-2
> > enable=0
> > active=0
> > self_refresh_active=0
> > planes_changed=0
> > mode_changed=0
> > active_changed=0
> > connectors_changed=0
> > color_mgmt_changed=0
> > plane_mask=0
> > connector_mask=0
> > encoder_mask=0
> > mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
> > connector[33]: DSI-1
> > crtc=crtc-0
> > self_refresh_aware=0
> > max_requested_bpc=0
> > colorspace=Default
> > connector[35]: DP-1
> > crtc=(null)
> > self_refresh_aware=0
> > max_requested_bpc=0
> > colorspace=Default
> > connector[42]: Writeback-1
> > crtc=(null)
> > self_refresh_aware=0
> > max_requested_bpc=0
> > colorspace=Default
> > resource mapping:
> > pingpong=103 # # # # # # # # # -
> > mixer=103 # # # # # -
> > ctl=# # 103 # # #
> > dspp=# # # #
> > dsc=# # # # # #
> > cdm=-
> > cwb=# # # #
> > ==================><====================================================
> >
> > I pasted all the kms_writeback log, I have nothing more.
> >
> > If I specify `--run-subtest dump-valid-clones` I get:
> > ==================><====================================================
> > IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=out.png /usr/libexec/igt-gpu-tools/kms_writeback -d --run-subtest dump-valid-clones
> > [ 33.250236] Console: switching to colour dummy device 80x25
> > IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-ge581f752bf79 aarch64)
> > Using IGT_SRANDOM=1709054789 for randomisation[ 33.256171] [IGT] kms_writeback: executing
> >
> > Opened device: /dev/dri/card0
> > [ 33.360023] [IGT] kms_writeback: starting subtest dump-valid-clones
> > Starting subtest: dump-valid-clones
> > [ 34.063316] [drm:dpu_encoder_virt_atomic_disable:1314] [dpu error]enc32 timeout pending
> > [ 34.244272] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
> > [ 34.253385] Mem abort info:
> > [ 34.256328] ESR = 0x0000000096000006
> > [ 34.260272] EC = 0x25: DABT (current EL), IL = 32 bits
> > [ 34.265816] SET = 0, FnV = 0
> > [ 34.269043] EA = 0, S1PTW = 0
> > [ 34.272332] FSC = 0x06: level 2 translation fault
> > [ 34.277430] Data abort info:
> > [ 34.280460] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
> > [ 34.286170] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> > [ 34.291438] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> > [ 34.296975] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008824fc000
> > [ 34.303673] [0000000000000010] pgd=08000008dc4e0003, p4d=08000008dc4e0003, pud=08000008dd4af003, pmd=0000000000000000
> > [ 34.314647] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
> > [ 34.321144] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_dai
> > q6apm_lpass_dais snd_q6dsp_common q6prm 8021q garp mrp stp llc usb_f_fs
> > libcomposite qrtr_mhi snd_q6apm rpmsg_ctrl fastrpc apr qrtr_smd
> > rpmsg_char snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi
> > panel_visionox_vtdr6130 qcom_pd_mapper goodix_berlin_spi ucsi_glink
> > pmic_glink_altmode pci_pwrctl_pwrseq pci_pwrctl_core typec_ucsi
> > aux_hpd_bridge qcom_battmgr nb7vpq904m wcd939x_usbss goodix_berlin_core
> > crct10dif_ce phy_qcom_eusb2_repeater msm sm3_ce sm3 qcom_q6v5_pas
> > sha3_ce hci_uart sha512_ce sha512_arm64 leds_qcom_lpg ocmem
> > qcom_pil_info qcom_q6v5 qcom_pbs btqca ipa btbcm drm_exec qcom_sysmon
> > pwrseq_qcom_wcn snd_soc_sc8280xp led_class_multicolor snd_soc_qcom_sdw
> > qrtr qcom_common gpu_sched snd_soc_wcd939x drm_dp_aux_bus
> > qcom_spmi_temp_alarm snd_soc_qcom_common qcom_glink_smem
> > snd_soc_wcd939x_sdw rtc_pm8xxx drm_display_helper
> > pinctrl_sm8650_lpass_lpi regmap_sdw cfg80211 bluetooth qcom_pon
> > pmic_glink ecdh_generic pdr_interface phy_qcom_qmp_combo ecc rfkill
> > [ 34.321268] nvmem_qcom_spmi_sdam qcom_stats spi_geni_qcom pwrseq_core i2c_qcom_geni aux_bridge phy_qcom_snps_eusb2 dispcc_sm8550 drm_kms_helper gpi soundwire_qcom snd_soc_lpass_va_macro pinctrl_lpass_lpi snd_soc_wcd_mbhc snd_soc_lpass_tx_macro snd_soc_lpass_rx_macro snd_soc_lpass_wsa_macro llcc_qcom snd_soc_lpass_macro_common slimbus snd_soc_wcd_classh mdt_loader qcom_pdr_msg qcrypto gpucc_sm8650 icc_bwmon qmi_helpers authenc phy_qcom_qmp_ufs libdes soundwire_bus ufs_qcom nvmem_reboot_mode phy_qcom_qmp_pcie typec qcom_rng rmtfs_mem socinfo fuse drm backlight ipv6
> > [ 34.464862] CPU: 5 UID: 0 PID: 513 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
> > [ 34.475812] Tainted: [S]=CPU_OUT_OF_SPEC
> > [ 34.479905] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
> > [ 34.486667] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
> > [ 34.493880] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
> > [ 34.500441] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
> > [ 34.506969] sp : ffff800085fc37e0
> > [ 34.510437] x29: ffff800085fc3810 x28: ffffb8c93c953068 x27: ffff5af315c90880
> > [ 34.517826] x26: ffff5af359c55780 x25: ffff800085fc3878 x24: ffff5af35a956e80
> > [ 34.525217] x23: 0000000000000000 x22: ffff5af355dc2080 x21: ffff5af35a956e80
> > [ 34.532607] x20: ffff5af315c90880 x19: ffff5af315c90c80 x18: 0000000000000001
> > [ 34.539997] x17: 0000000000000018 x16: ffffb8c95c9c8c64 x15: 0000000000000038
> > [ 34.547385] x14: 0000001971602a24 x13: 00000000000000e1 x12: 000000000000000b
> > [ 34.554774] x11: 0000000000000000 x10: e7125de8a27ae014 x9 : 5aef79bd13b1e2a7
> > [ 34.562162] x8 : ffff5af355dc2718 x7 : 0000000000000004 x6 : ffff5af356374d98
> > [ 34.569550] x5 : 0000000000000002 x4 : ffff800085fc37f8 x3 : ffff5af315c90950
> > [ 34.576938] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
> > [ 34.584328] Call trace:
> > [ 34.586905] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
> > [ 34.593075] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
> > [ 34.599165] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
> > [ 34.604713] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
> > [ 34.610711] disable_outputs+0x108/0x32c [drm_kms_helper]
> > [ 34.616351] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
> > [ 34.624110] msm_atomic_commit_tail+0x188/0x514 [msm]
> > [ 34.629396] commit_tail+0xa4/0x18c [drm_kms_helper]
> > [ 34.634570] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
> > [ 34.640990] drm_atomic_commit+0xb8/0xf4 [drm]
> > [ 34.645690] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
> > [ 34.650889] drm_ioctl_kernel+0xc0/0x128 [drm]
> > [ 34.655564] drm_ioctl+0x218/0x49c [drm]
> > [ 34.659697] __arm64_sys_ioctl+0xac/0xf0
> > [ 34.663804] invoke_syscall+0x48/0x10c
> > [ 34.667755] el0_svc_common.constprop.0+0xc0/0xe0
> > [ 34.672648] do_el0_svc+0x1c/0x28
> > [ 34.676117] el0_svc+0x34/0xd8
> > [ 34.679330] el0t_64_sync_handler+0x120/0x12c
> > [ 34.683864] el0t_64_sync+0x190/0x194
> > [ 34.687699] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
> > [ 34.694014] ---[ end trace 0000000000000000 ]---
> > ==================><====================================================
>
> Anything I can try to get past the crash ?
The call to dpu_kms_get_existing_global_state in
dpu_encoder_helper_phys_setup_cwb looks suspicious to me, can you check
whether the returned global state is NULL?
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-10-08 8:00 ` Neil Armstrong
2024-10-08 8:18 ` Maxime Ripard
@ 2024-10-08 12:25 ` Jessica Zhang
2024-10-09 7:46 ` neil.armstrong
1 sibling, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-10-08 12:25 UTC (permalink / raw)
To: neil.armstrong, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 10/8/2024 1:00 AM, Neil Armstrong wrote:
> Hi,
>
> On 01/10/2024 09:37, neil.armstrong@linaro.org wrote:
>> Hi,
>>
>> On 30/09/2024 21:19, Jessica Zhang wrote:
>>>
>>>
>>> On 9/30/2024 7:17 AM, neil.armstrong@linaro.org wrote:
>>>> On 25/09/2024 00:59, Jessica Zhang wrote:
>
> <snip>
>
>>>>
>>>> When running igt-test on QRD8650, I get:
>>>> # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/
>>>> igt- gpu-tools/kms_writeback -d
>>>
>>> Hi Neil,
>>>
>>> Thanks for reporting this. Unfortunately, I'm not able to recreate
>>> this on the MTP8650.
>>>
>>> How many/which non-WB outputs are you testing with?
>>
>> Here's the modetest output:
>> ==================><====================================================
>> Encoders:
>> id crtc type possible crtcs possible clones
>> 32 103 DSI 0x00000007 0x00000005
>> 34 0 TMDS 0x00000007 0x00000006
>> 37 0 Virtual 0x00000007 0x00000007
>>
>> Connectors:
>> id encoder status name size (mm) modes encoders
>> 33 32 connected DSI-1 71x157 1 32
>> modes:
>> index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
>> #0 1080x2400 144.00 1080 1100 1102 1122 2400 2420 2422 2440 394225
>> flags: ; type: preferred, driver
>> props:
>> 1 EDID:
>> flags: immutable blob
>> blobs:
>>
>> value:
>> 2 DPMS:
>> flags: enum
>> enums: On=0 Standby=1 Suspend=2 Off=3
>> value: 0
>> 5 link-status:
>> flags: enum
>> enums: Good=0 Bad=1
>> value: 0
>> 6 non-desktop:
>> flags: immutable range
>> values: 0 1
>> value: 0
>> 4 TILE:
>> flags: immutable blob
>> blobs:
>>
>> value:
>> 35 0 disconnected DP-1 0x0 0 34
>> props:
>> 1 EDID:
>> flags: immutable blob
>> blobs:
>>
>> value:
>> 2 DPMS:
>> flags: enum
>> enums: On=0 Standby=1 Suspend=2 Off=3
>> value: 0
>> 5 link-status:
>> flags: enum
>> enums: Good=0 Bad=1
>> value: 0
>> 6 non-desktop:
>> flags: immutable range
>> values: 0 1
>> value: 0
>> 4 TILE:
>> flags: immutable blob
>> blobs:
>>
>> value:
>> 36 subconnector:
>> flags: immutable enum
>> enums: Unknown=0 VGA=1 DVI-D=3 HDMI=11 DP=10 Wireless=18
>> Native=15
>> value: 0
>> ==================><====================================================
>>
>> and dri state:
>> ==================><====================================================
>> # cat /sys/kernel/debug/dri/0/state
>> plane[43]: plane-0
>> crtc=crtc-0
>> fb=106
>> allocated by = [fbcon]
>> refcount=2
>> format=XR24 little-endian (0x34325258)
>> modifier=0x0
>> size=1080x2400
>> layers:
>> size[0]=1080x2400
>> pitch[0]=4352
>> offset[0]=0
>> obj[0]:
>> name=0
>> refcount=1
>> start=0010102d
>> size=10444800
>> imported=no
>> crtc-pos=1080x2400+0+0
>> src-pos=1080.000000x2400.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=1
>> sspp[0]=sspp_0
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=1080x2400+0+0
>> dst[0]=1080x2400+0+0
>> plane[49]: plane-1
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_1
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[55]: plane-2
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_2
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[61]: plane-3
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_3
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[67]: plane-4
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_8
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[73]: plane-5
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_9
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[79]: plane-6
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_10
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[85]: plane-7
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_11
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[91]: plane-8
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_12
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> plane[97]: plane-9
>> crtc=(null)
>> fb=0
>> crtc-pos=0x0+0+0
>> src-pos=0.000000x0.000000+0.000000+0.000000
>> rotation=1
>> normalized-zpos=0
>> color-encoding=ITU-R BT.601 YCbCr
>> color-range=YCbCr limited range
>> color_mgmt_changed=0
>> stage=0
>> sspp[0]=sspp_13
>> multirect_mode[0]=none
>> multirect_index[0]=solo
>> src[0]=0x0+0+0
>> dst[0]=0x0+0+0
>> crtc[103]: crtc-0
>> enable=1
>> active=1
>> self_refresh_active=0
>> planes_changed=1
>> mode_changed=0
>> active_changed=0
>> connectors_changed=0
>> color_mgmt_changed=0
>> plane_mask=1
>> connector_mask=1
>> encoder_mask=1
>> mode: "1080x2400": 144 394225 1080 1100 1102 1122 2400 2420 2422
>> 2440 0x48 0x0
>> lm[0]=0
>> ctl[0]=2
>> crtc[104]: crtc-1
>> enable=0
>> active=0
>> self_refresh_active=0
>> planes_changed=0
>> mode_changed=0
>> active_changed=0
>> connectors_changed=0
>> color_mgmt_changed=0
>> plane_mask=0
>> connector_mask=0
>> encoder_mask=0
>> mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
>> crtc[105]: crtc-2
>> enable=0
>> active=0
>> self_refresh_active=0
>> planes_changed=0
>> mode_changed=0
>> active_changed=0
>> connectors_changed=0
>> color_mgmt_changed=0
>> plane_mask=0
>> connector_mask=0
>> encoder_mask=0
>> mode: "": 0 0 0 0 0 0 0 0 0 0 0x0 0x0
>> connector[33]: DSI-1
>> crtc=crtc-0
>> self_refresh_aware=0
>> max_requested_bpc=0
>> colorspace=Default
>> connector[35]: DP-1
>> crtc=(null)
>> self_refresh_aware=0
>> max_requested_bpc=0
>> colorspace=Default
>> connector[42]: Writeback-1
>> crtc=(null)
>> self_refresh_aware=0
>> max_requested_bpc=0
>> colorspace=Default
>> resource mapping:
>> pingpong=103 # # # # # # # # # -
>> mixer=103 # # # # # -
>> ctl=# # 103 # # #
>> dspp=# # # #
>> dsc=# # # # # #
>> cdm=-
>> cwb=# # # #
>> ==================><====================================================
>>
>> I pasted all the kms_writeback log, I have nothing more.
>>
>> If I specify `--run-subtest dump-valid-clones` I get:
>> ==================><====================================================
>> IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=out.png /usr/libexec/igt-
>> gpu-tools/kms_writeback -d --run-subtest dump-valid-clones
>> [ 33.250236] Console: switching to colour dummy device 80x25
>> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-
>> ge581f752bf79 aarch64)
>> Using IGT_SRANDOM=1709054789 for randomisation[ 33.256171] [IGT]
>> kms_writeback: executing
>>
>> Opened device: /dev/dri/card0
>> [ 33.360023] [IGT] kms_writeback: starting subtest dump-valid-clones
>> Starting subtest: dump-valid-clones
>> [ 34.063316] [drm:dpu_encoder_virt_atomic_disable:1314] [dpu
>> error]enc32 timeout pending
>> [ 34.244272] Unable to handle kernel NULL pointer dereference at
>> virtual address 0000000000000010
>> [ 34.253385] Mem abort info:
>> [ 34.256328] ESR = 0x0000000096000006
>> [ 34.260272] EC = 0x25: DABT (current EL), IL = 32 bits
>> [ 34.265816] SET = 0, FnV = 0
>> [ 34.269043] EA = 0, S1PTW = 0
>> [ 34.272332] FSC = 0x06: level 2 translation fault
>> [ 34.277430] Data abort info:
>> [ 34.280460] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
>> [ 34.286170] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>> [ 34.291438] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>> [ 34.296975] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008824fc000
>> [ 34.303673] [0000000000000010] pgd=08000008dc4e0003,
>> p4d=08000008dc4e0003, pud=08000008dd4af003, pmd=0000000000000000
>> [ 34.314647] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
>> [ 34.321144] Modules linked in: snd_soc_wsa884x q6prm_clocks
>> q6apm_dai q6apm_lpass_dais snd_q6dsp_common q6prm 8021q garp mrp stp
>> llc usb_f_fs libcomposite qrtr_mhi snd_q6apm rpmsg_ctrl fastrpc apr
>> qrtr_smd rpmsg_char snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi
>> panel_visionox_vtdr6130 qcom_pd_mapper goodix_berlin_spi ucsi_glink
>> pmic_glink_altmode pci_pwrctl_pwrseq pci_pwrctl_core typec_ucsi
>> aux_hpd_bridge qcom_battmgr nb7vpq904m wcd939x_usbss
>> goodix_berlin_core crct10dif_ce phy_qcom_eusb2_repeater msm sm3_ce sm3
>> qcom_q6v5_pas sha3_ce hci_uart sha512_ce sha512_arm64 leds_qcom_lpg
>> ocmem qcom_pil_info qcom_q6v5 qcom_pbs btqca ipa btbcm drm_exec
>> qcom_sysmon pwrseq_qcom_wcn snd_soc_sc8280xp led_class_multicolor
>> snd_soc_qcom_sdw qrtr qcom_common gpu_sched snd_soc_wcd939x
>> drm_dp_aux_bus qcom_spmi_temp_alarm snd_soc_qcom_common
>> qcom_glink_smem snd_soc_wcd939x_sdw rtc_pm8xxx drm_display_helper
>> pinctrl_sm8650_lpass_lpi regmap_sdw cfg80211 bluetooth qcom_pon
>> pmic_glink ecdh_generic pdr_interface phy_qcom_qmp_combo ecc rfkill
>> [ 34.321268] nvmem_qcom_spmi_sdam qcom_stats spi_geni_qcom
>> pwrseq_core i2c_qcom_geni aux_bridge phy_qcom_snps_eusb2 dispcc_sm8550
>> drm_kms_helper gpi soundwire_qcom snd_soc_lpass_va_macro
>> pinctrl_lpass_lpi snd_soc_wcd_mbhc snd_soc_lpass_tx_macro
>> snd_soc_lpass_rx_macro snd_soc_lpass_wsa_macro llcc_qcom
>> snd_soc_lpass_macro_common slimbus snd_soc_wcd_classh mdt_loader
>> qcom_pdr_msg qcrypto gpucc_sm8650 icc_bwmon qmi_helpers authenc
>> phy_qcom_qmp_ufs libdes soundwire_bus ufs_qcom nvmem_reboot_mode
>> phy_qcom_qmp_pcie typec qcom_rng rmtfs_mem socinfo fuse drm backlight
>> ipv6
>> [ 34.464862] CPU: 5 UID: 0 PID: 513 Comm: kms_writeback Tainted: G
>> S 6.12.0-rc1-00022-ge581f752bf79 #2
>> [ 34.475812] Tainted: [S]=CPU_OUT_OF_SPEC
>> [ 34.479905] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
>> [ 34.486667] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS
>> BTYPE=--)
>> [ 34.493880] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>> [ 34.500441] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
>> [ 34.506969] sp : ffff800085fc37e0
>> [ 34.510437] x29: ffff800085fc3810 x28: ffffb8c93c953068 x27:
>> ffff5af315c90880
>> [ 34.517826] x26: ffff5af359c55780 x25: ffff800085fc3878 x24:
>> ffff5af35a956e80
>> [ 34.525217] x23: 0000000000000000 x22: ffff5af355dc2080 x21:
>> ffff5af35a956e80
>> [ 34.532607] x20: ffff5af315c90880 x19: ffff5af315c90c80 x18:
>> 0000000000000001
>> [ 34.539997] x17: 0000000000000018 x16: ffffb8c95c9c8c64 x15:
>> 0000000000000038
>> [ 34.547385] x14: 0000001971602a24 x13: 00000000000000e1 x12:
>> 000000000000000b
>> [ 34.554774] x11: 0000000000000000 x10: e7125de8a27ae014 x9 :
>> 5aef79bd13b1e2a7
>> [ 34.562162] x8 : ffff5af355dc2718 x7 : 0000000000000004 x6 :
>> ffff5af356374d98
>> [ 34.569550] x5 : 0000000000000002 x4 : ffff800085fc37f8 x3 :
>> ffff5af315c90950
>> [ 34.576938] x2 : 0000000000000002 x1 : 0000000000000000 x0 :
>> 0000000000000001
>> [ 34.584328] Call trace:
>> [ 34.586905] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>> [ 34.593075] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
>> [ 34.599165] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
>> [ 34.604713] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
>> [ 34.610711] disable_outputs+0x108/0x32c [drm_kms_helper]
>> [ 34.616351] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
>> [drm_kms_helper]
>> [ 34.624110] msm_atomic_commit_tail+0x188/0x514 [msm]
>> [ 34.629396] commit_tail+0xa4/0x18c [drm_kms_helper]
>> [ 34.634570] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
>> [ 34.640990] drm_atomic_commit+0xb8/0xf4 [drm]
>> [ 34.645690] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
>> [ 34.650889] drm_ioctl_kernel+0xc0/0x128 [drm]
>> [ 34.655564] drm_ioctl+0x218/0x49c [drm]
>> [ 34.659697] __arm64_sys_ioctl+0xac/0xf0
>> [ 34.663804] invoke_syscall+0x48/0x10c
>> [ 34.667755] el0_svc_common.constprop.0+0xc0/0xe0
>> [ 34.672648] do_el0_svc+0x1c/0x28
>> [ 34.676117] el0_svc+0x34/0xd8
>> [ 34.679330] el0t_64_sync_handler+0x120/0x12c
>> [ 34.683864] el0t_64_sync+0x190/0x194
>> [ 34.687699] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
>> [ 34.694014] ---[ end trace 0000000000000000 ]---
>> ==================><====================================================
>
> Anything I can try to get past the crash ?
Hey Neil,
Sorry for the late reply -- I was able to recreate this error using a
clean IGT build. Looks like the NULL dereference is coming from looping
through rt_pp_list.
I'm already planning to drop this in the v3, but for now can you try
applying this change and seeing if it fixes the NULL dereference for you:
@@ -2166,7 +2172,7 @@ void dpu_encoder_helper_phys_setup_cwb(struct
dpu_encoder_phys *phys_enc,
struct dpu_kms *dpu_kms;
struct dpu_global_state *global_state;
struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
- int num_pp, rt_pp_idx[MAX_CHANNELS_PER_ENC];
+ int num_pp;
if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
return;
@@ -2191,24 +2197,6 @@ void dpu_encoder_helper_phys_setup_cwb(struct
dpu_encoder_phys *phys_enc,
return;
}
- for (int i = 0; i < num_pp; i++) {
- struct dpu_hw_pingpong *hw_pp =
to_dpu_hw_pingpong(rt_pp_list[i]);
-
- for (int j = 0; j < ARRAY_SIZE(dpu_enc->hw_cwb); j++) {
- hw_cwb = dpu_enc->hw_cwb[i];
-
- /*
- * Even CWB muxes must take input from even
real-time
- * pingpongs and odd CWB muxes must take input
from odd
- * pingpongs
- */
- if (hw_pp->idx % 2 == hw_cwb->idx % 2) {
- rt_pp_idx[i] = enable ? hw_pp->idx :
PINGPONG_NONE;
- break;
- }
- }
- }
-
/*
* The CWB mux supports using LM or DSPP as tap points. For now,
* always use LM tap point
@@ -2220,7 +2208,13 @@ void dpu_encoder_helper_phys_setup_cwb(struct
dpu_encoder_phys *phys_enc,
if (!hw_cwb)
continue;
- cwb_cfg.pp_idx = rt_pp_idx[i];
+ if (enable) {
+ struct dpu_hw_pingpong *hw_pp =
+ to_dpu_hw_pingpong(rt_pp_list[i]);
+ cwb_cfg.pp_idx = hw_pp->idx;
+ } else {
+ cwb_cfg.pp_idx = PINGPONG_NONE;
+ }
Thanks,
Jessica Zhang
>
> Thanks,
> Neil
>
>>
>> Neil
>>
>>>
>>> Also, can you share the IGT debug logs?
>>>
>>> FWIW, I haven't had the chance to test with DP yet so that might be
>>> why you're hitting this issue and I'm not.
>>>
>>> Thanks,
>>>
>>> Jessica Zhang
>>>
>>>> [ 2566.668998] Console: switching to colour dummy device 80x25
>>>> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022-
>>>> ge581f752bf79 aarch64)
>>>> [ 2566.674859] [IGT] kms_writeback: executing
>>>> Using IGT_SRANDOM=1709057323 for randomisation
>>>> Opened device: /dev/dri/card0
>>>> [ 2566.741375] [IGT] kms_writeback: starting subtest dump-writeback
>>>> Starting subtest: dump-writeback
>>>> Subtest dump-writeback: SUCCESS (0.305s)[ 2567.053189] [IGT]
>>>> kms_writeback: finished subtest dump-writeback, SUCCESS
>>>>
>>>> [ 2567.064505] [IGT] kms_writeback: starting subtest dump-valid-clones
>>>> Starting subtest: dump-valid-clones
>>>> [ 2567.762793] Unable to handle kernel NULL pointer dereference at
>>>> virtual address 0000000000000010
>>>> [ 2567.771919] Mem abort info:
>>>> [ 2567.774888] ESR = 0x0000000096000006
>>>> [ 2567.778831] EC = 0x25: DABT (current EL), IL = 32 bits
>>>> [ 2567.784371] SET = 0, FnV = 0
>>>> [ 2567.787601] EA = 0, S1PTW = 0
>>>> [ 2567.790942] FSC = 0x06: level 2 translation fault
>>>> [ 2567.796044] Data abort info:
>>>> [ 2567.799083] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
>>>> [ 2567.804793] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>>>> [ 2567.810057] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>>>> [ 2567.815600] user pgtable: 4k pages, 48-bit VAs,
>>>> pgdp=00000008d60cf000
>>>> [ 2567.822290] [0000000000000010] pgd=08000008d6049003,
>>>> p4d=08000008d6049003, pud=080000089397e003, pmd=0000000000000000
>>>> [ 2567.833254] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
>>>> [ 2567.839747] Modules linked in: snd_soc_wsa884x q6prm_clocks
>>>> q6apm_lpass_dais snd_q6dsp_common q6apm_dai q6prm 8021q garp mrp stp
>>>> llc usb_f_fs libcomposite qrtr_mhi snd_soc_hdmi_codec ath12k
>>>> mac80211 libarc4 mhi panel_visionox_vtdr6130 snd_q6apm
>>>> pci_pwrctl_pwrseq pci_pwrctl_core rpmsg_ctrl apr fastrpc qrtr_smd
>>>> rpmsg_char wcd939x_usbss nb7vpq904m qcom_pd_mapper goodix_berlin_spi
>>>> goodix_berlin_core ucsi_glink typec_ucsi pmic_glink_altmode
>>>> aux_hpd_bridge qcom_battmgr leds_qcom_lpg msm ocmem drm_exec
>>>> hci_uart qcom_pbs gpu_sched led_class_multicolor btqca
>>>> phy_qcom_eusb2_repeater btbcm qcom_spmi_temp_alarm drm_dp_aux_bus
>>>> phy_qcom_qmp_combo crct10dif_ce bluetooth drm_display_helper sm3_ce
>>>> ecdh_generic aux_bridge sm3 snd_soc_sc8280xp pwrseq_qcom_wcn sha3_ce
>>>> snd_soc_qcom_sdw rtc_pm8xxx qcom_pon ecc nvmem_qcom_spmi_sdam
>>>> sha512_ce qcom_stats spi_geni_qcom snd_soc_qcom_common sha512_arm64
>>>> pwrseq_core i2c_qcom_geni cfg80211 drm_kms_helper dispcc_sm8550 gpi
>>>> ipa snd_soc_lpass_va_macro snd_soc_lpass_tx_macro soundwire_qcom
>>>> [ 2567.839860] pinctrl_sm8650_lpass_lpi snd_soc_lpass_wsa_macro
>>>> snd_soc_lpass_rx_macro rfkill slimbus phy_qcom_snps_eusb2
>>>> pinctrl_lpass_lpi gpucc_sm8650 snd_soc_lpass_macro_common
>>>> qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcrypto authenc icc_bwmon
>>>> qcom_sysmon qcom_common qrtr qcom_glink_smem phy_qcom_qmp_pcie
>>>> mdt_loader libdes llcc_qcom ufs_qcom phy_qcom_qmp_ufs pmic_glink
>>>> snd_soc_wcd939x rmtfs_mem pdr_interface snd_soc_wcd939x_sdw
>>>> regmap_sdw qcom_pdr_msg snd_soc_wcd_mbhc qmi_helpers
>>>> snd_soc_wcd_classh soundwire_bus typec nvmem_reboot_mode qcom_rng
>>>> socinfo fuse drm backlight ipv6
>>>> [ 2567.983445] CPU: 5 UID: 0 PID: 554 Comm: kms_writeback Tainted: G
>>>> S 6.12.0-rc1-00022-ge581f752bf79 #2
>>>> [ 2567.994390] Tainted: [S]=CPU_OUT_OF_SPEC
>>>> [ 2567.998483] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD
>>>> (DT)
>>>> [ 2568.005244] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS
>>>> BTYPE=--)
>>>> [ 2568.012455] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>>>> [ 2568.019009] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
>>>> [ 2568.025532] sp : ffff80008939b7e0
>>>> [ 2568.028999] x29: ffff80008939b810 x28: ffffcbcb66f26068 x27:
>>>> ffff37ad962cb080
>>>> [ 2568.036388] x26: ffff37ad9887ed80 x25: ffff80008939b878 x24:
>>>> ffff37ad43642a80
>>>> [ 2568.043775] x23: 0000000000000000 x22: ffff37ad42812080 x21:
>>>> ffff37ad43642a80
>>>> [ 2568.051163] x20: ffff37ad962cb080 x19: ffff37ad962c8080 x18:
>>>> 0000000000000001
>>>> [ 2568.058552] x17: 000000040044ffff x16: ffffcbcbb0fc8c64 x15:
>>>> 00003d08ffff9c00
>>>> [ 2568.065939] x14: 00000013519b2832 x13: ffff37ad9d392200 x12:
>>>> 000000000000000b
>>>> [ 2568.073325] x11: ffff37ad40dc56c0 x10: ffff37ad9d392200 x9 :
>>>> ffff37afbe7bba80
>>>> [ 2568.080712] x8 : ffff37ad42812718 x7 : 0000000000000004 x6 :
>>>> ffff37ad989ac798
>>>> [ 2568.088098] x5 : 0000000000000002 x4 : ffff80008939b7f8 x3 :
>>>> ffff37ad962cb150
>>>> [ 2568.095480] x2 : 0000000000000002 x1 : 0000000000000000 x0 :
>>>> 0000000000000001
>>>> [ 2568.102868] Call trace:
>>>> [ 2568.105446] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>>>> [ 2568.111608] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
>>>> [ 2568.117692] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
>>>> [ 2568.123233] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
>>>> [ 2568.129224] disable_outputs+0x108/0x32c [drm_kms_helper]
>>>> [ 2568.134858] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c
>>>> [drm_kms_helper]
>>>> [ 2568.142614] msm_atomic_commit_tail+0x188/0x514 [msm]
>>>> [ 2568.147894] commit_tail+0xa4/0x18c [drm_kms_helper]
>>>> [ 2568.153065] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
>>>> [ 2568.159482] drm_atomic_commit+0xb8/0xf4 [drm]
>>>> [ 2568.164176] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
>>>> [ 2568.169369] drm_ioctl_kernel+0xc0/0x128 [drm]
>>>> [ 2568.174039] drm_ioctl+0x218/0x49c [drm]
>>>> [ 2568.178165] __arm64_sys_ioctl+0xac/0xf0
>>>> [ 2568.182271] invoke_syscall+0x48/0x10c
>>>> [ 2568.186217] el0_svc_common.constprop.0+0xc0/0xe0
>>>> [ 2568.191109] do_el0_svc+0x1c/0x28
>>>> [ 2568.194576] el0_svc+0x34/0xd8
>>>> [ 2568.197788] el0t_64_sync_handler+0x120/0x12c
>>>> [ 2568.202321] el0t_64_sync+0x190/0x194
>>>> [ 2568.206157] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
>>>> [ 2568.212484] ---[ end trace 0000000000000000 ]---
>>>>
>>>> Neil
>>>>
>>>>> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
>>>>> + break;
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + /*
>>>>> + * The CWB mux supports using LM or DSPP as tap points. For now,
>>>>> + * always use LM tap point
>>>>> + */
>>>>> + cwb_cfg.input = INPUT_MODE_LM_OUT;
>>>>> +
>>>>> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>>>>> + hw_cwb = dpu_enc->hw_cwb[i];
>>>>> + if (!hw_cwb)
>>>>> + continue;
>>>>> +
>>>>> + cwb_cfg.pp_idx = rt_pp_idx[i];
>>>>> +
>>>>> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
>>>>> + }
>>>>> +}
>>>>> +
>>>>> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys
>>>>> *phys_enc,
>>>>> const struct msm_format *dpu_fmt,
>>>>> u32 output_type)
>>>>> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode
>>>>> dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
>>>>> return INTF_MODE_NONE;
>>>>> }
>>>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys
>>>>> *phys_enc)
>>>>> +{
>>>>> + struct drm_encoder *encoder = phys_enc->parent;
>>>>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
>>>>> +
>>>>> + return dpu_enc->cwb_mask;
>>>>> +}
>>>>> +
>>>>> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys
>>>>> *phys_enc)
>>>>> {
>>>>> struct drm_encoder *encoder = phys_enc->parent;
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/
>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>>> index e77ebe3a68da..d7a02d1f8053 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>>> @@ -1,6 +1,6 @@
>>>>> /* SPDX-License-Identifier: GPL-2.0-only */
>>>>> /*
>>>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
>>>>> reserved.
>>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All
>>>>> rights reserved.
>>>>> * Copyright (c) 2015-2018 The Linux Foundation. All rights
>>>>> reserved.
>>>>> */
>>>>> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode
>>>>> dpu_encoder_helper_get_3d_blend_mode(
>>>>> return BLEND_3D_NONE;
>>>>> }
>>>>> +/**
>>>>> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU
>>>>> encoder
>>>>> + * @phys_enc: Pointer to physical encoder structure
>>>>> + */
>>>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys
>>>>> *phys_enc);
>>>>> +
>>>>> /**
>>>>> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU
>>>>> encoder
>>>>> * This helper function is used by physical encoder to get DSC
>>>>> blocks mask
>>>>> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct
>>>>> dpu_encoder_phys *phys_enc,
>>>>> */
>>>>> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys
>>>>> *phys_enc);
>>>>> +/**
>>>>> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
>>>>> + * @phys_enc: Pointer to physical encoder structure
>>>>> + * @enable: Enable CWB mux
>>>>> + */
>>>>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys
>>>>> *phys_enc,
>>>>> + bool enable);
>>>>> +
>>>>> /**
>>>>> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling
>>>>> block
>>>>> * @phys_enc: Pointer to physical encoder
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/
>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>>> index 882c717859ce..e88c4d91041f 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>>> @@ -1,6 +1,6 @@
>>>>> // SPDX-License-Identifier: GPL-2.0-only
>>>>> /*
>>>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
>>>>> reserved.
>>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All
>>>>> rights reserved.
>>>>> */
>>>>> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
>>>>> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>>>>> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt,
>>>>> CDM_CDWN_OUTPUT_WB);
>>>>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
>>>>> +
>>>>> dpu_encoder_phys_wb_setup_ctl(phys_enc);
>>>>> }
>>>>>
>>>>
>>>
>>
>
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder
2024-10-08 12:25 ` Jessica Zhang
@ 2024-10-09 7:46 ` neil.armstrong
0 siblings, 0 replies; 64+ messages in thread
From: neil.armstrong @ 2024-10-09 7:46 UTC (permalink / raw)
To: Jessica Zhang, Rob Clark, Dmitry Baryshkov, quic_abhinavk,
Sean Paul, Marijn Suijten, David Airlie, Daniel Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä
On 08/10/2024 14:25, Jessica Zhang wrote:
>
>
> On 10/8/2024 1:00 AM, Neil Armstrong wrote:
>> Hi,
>>
>> On 01/10/2024 09:37, neil.armstrong@linaro.org wrote:
>>> Hi,
>>>
>>> On 30/09/2024 21:19, Jessica Zhang wrote:
>>>>
>>>>
>>>> On 9/30/2024 7:17 AM, neil.armstrong@linaro.org wrote:
>>>>> On 25/09/2024 00:59, Jessica Zhang wrote:
>>
>> <snip>
>>
>>>>>
>>>>> When running igt-test on QRD8650, I get:
>>>>> # IGT_FRAME_DUMP_PATH=$PWD FRAME_PNG_FILE_NAME=pwet /usr/libexec/ igt- gpu-tools/kms_writeback -d
>>>>
>>>> Hi Neil,
>>>>
>>>> Thanks for reporting this. Unfortunately, I'm not able to recreate this on the MTP8650.
>>>>
<snip>
Thanks for the fix, Indeed it fixes the crash, but the igt test tries to use the Disconnected and fails:
Starting subtest: dump-valid-clones
(kms_writeback:521) igt_kms-CRITICAL: Test assertion failure function kmstest_dumb_create, file /usr/src/debug/igt-gpu-tools/1.28/lib/igt_kms.c:1301:
(kms_writeback:521) igt_kms-CRITICAL: Failed assertion: igt_ioctl((fd), ((((2U|1U) << (((0+8)+8)+14)) | ((('d')) << (0+8)) | (((0xB2)) << 0) | ((((sizeof(struct drm_mode_create_dumb)))) << ((0+8)+8)))), (&create)) == 0
(kms_writeback:521) igt_kms-CRITICAL: Last errno: 22, Invalid argument
(kms_writeback:521) igt_kms-CRITICAL: error: -1 != 0
Stack trace:
#0 [igt_nsec_elapsed+0x500]
Subtest dump-valid-clones failed.
**** DEBUG ****
(kms_writeback:521) DEBUG: Test requirement passed: !(!data.dump_check || data.list_modes)
(kms_writeback:521) DEBUG: Test requirement passed: !(!(data.supported_colors & XRGB8888))
(kms_writeback:521) DEBUG: Test requirement passed: fb_id > 0
(kms_writeback:521) igt_kms-DEBUG: display: DSI-1: set_pipe(A)
(kms_writeback:521) igt_kms-DEBUG: display: DSI-1: Selecting pipe A
(kms_writeback:521) igt_fb-DEBUG: igt_create_fb_with_bo_size(width=1080, height=2400, format=XR24(0x34325258), modifier=0x0, size=0)
(kms_writeback:521) igt_fb-DEBUG: igt_create_fb_with_bo_size(handle=3, pitch=4352)
(kms_writeback:521) ioctl_wrappers-DEBUG: Test requirement passed: igt_has_fb_modifiers(fd)
(kms_writeback:521) igt_fb-DEBUG: igt_create_fb_with_bo_size(width=1080, height=2400, format=XR24(0x34325258), modifier=0x0, size=0)
(kms_writeback:521) igt_fb-DEBUG: igt_create_fb_with_bo_size(handle=4, pitch=4352)
(kms_writeback:521) ioctl_wrappers-DEBUG: Test requirement passed: igt_has_fb_modifiers(fd)
(kms_writeback:521) DEBUG: Test requirement passed: fb_id > 0
(kms_writeback:521) igt_kms-DEBUG: display: A.0: plane_set_fb(110)
(kms_writeback:521) igt_kms-DEBUG: display: A.0: plane_set_size (1080x2400)
(kms_writeback:521) igt_kms-DEBUG: display: A.0: fb_set_position(0,0)
(kms_writeback:521) igt_kms-DEBUG: display: A.0: fb_set_size(1080x2400)
(kms_writeback:521) igt_kms-DEBUG: display: Writeback-1: output_set_writeback_fb(112)
(kms_writeback:521) igt_kms-DEBUG: display: commit {
(kms_writeback:521) igt_kms-DEBUG: Pipe A: Setting property "MODE_ID" to 0x6d/109
(kms_writeback:521) igt_kms-DEBUG: Pipe A: Setting property "ACTIVE" to 0x1/1
(kms_writeback:521) igt_kms-DEBUG: display: populating plane data: A.0, fb 110
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "SRC_X" to 0x0/0
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "SRC_Y" to 0x0/0
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "SRC_W" to 0x4380000/70778880
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "SRC_H" to 0x9600000/157286400
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "CRTC_W" to 0x438/1080
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "CRTC_H" to 0x960/2400
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "FB_ID" to 0x6e/110
(kms_writeback:521) igt_kms-DEBUG: plane A.0: Setting property "CRTC_ID" to 0x67/103
(kms_writeback:521) igt_kms-DEBUG: display: DSI-1: preparing atomic, pipe: A
(kms_writeback:521) igt_kms-DEBUG: DSI-1: Setting property "CRTC_ID" to 0x67/103
(kms_writeback:521) igt_kms-DEBUG: display: Writeback-1: preparing atomic, pipe: A
(kms_writeback:521) igt_kms-DEBUG: Writeback-1: Setting property "WRITEBACK_FB_ID" to 0x70/112
(kms_writeback:521) igt_kms-DEBUG: Writeback-1: Setting property "WRITEBACK_OUT_FENCE_PTR" to 0x3a4958f8/977885432
(kms_writeback:521) igt_kms-DEBUG: display: }
(kms_writeback:521) igt_fb-DEBUG: Test requirement passed: cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS
(kms_writeback:521) igt_kms-DEBUG: display: DSI-1: set_pipe(None)
(kms_writeback:521) igt_kms-DEBUG: display: DSI-1: Selecting pipe None
(kms_writeback:521) igt_kms-DEBUG: display: commit {
(kms_writeback:521) igt_kms-DEBUG: Pipe A: Setting property "MODE_ID" to 0x6b/107
(kms_writeback:521) igt_kms-DEBUG: display: DSI-1: preparing atomic, pipe: None
(kms_writeback:521) igt_kms-DEBUG: DSI-1: Setting property "CRTC_ID" to 0x0/0
(kms_writeback:521) igt_kms-DEBUG: display: }
(kms_writeback:521) igt_kms-DEBUG: display: DP-1: set_pipe(A)
(kms_writeback:521) igt_kms-DEBUG: display: DP-1: Selecting pipe A
(kms_writeback:521) igt_fb-DEBUG: igt_create_fb_with_bo_size(width=0, height=0, format=XR24(0x34325258), modifier=0x0, size=0)
(kms_writeback:521) igt_kms-CRITICAL: Test assertion failure function kmstest_dumb_create, file /usr/src/debug/igt-gpu-tools/1.28/lib/igt_kms.c:1301:
(kms_writeback:521) igt_kms-CRITICAL: Failed assertion: igt_ioctl((fd), ((((2U|1U) << (((0+8)+8)+14)) | ((('d')) << (0+8)) | (((0xB2)) << 0) | ((((sizeof(struct drm_mode_create_dumb)))) << ((0+8)+8)))), (&create)) == 0
(kms_writeback:521) igt_kms-CRITICAL: Last errno: 22, Invalid argument
(kms_writeback:521) igt_kms-CRITICAL: error: -1 != 0
(kms_writeback:521) igt_core-INFO: Stack trace:
(kms_writeback:521) igt_core-INFO: #0 [igt_nsec_elapsed+0x500]
**** END ****
I'll try with an enabled DP connector.
Neil
>
>
> Thanks,
>
> Jessica Zhang
>
>>
>> Thanks,
>> Neil
>>
>>>
>>> Neil
>>>
>>>>
>>>> Also, can you share the IGT debug logs?
>>>>
>>>> FWIW, I haven't had the chance to test with DP yet so that might be why you're hitting this issue and I'm not.
>>>>
>>>> Thanks,
>>>>
>>>> Jessica Zhang
>>>>
>>>>> [ 2566.668998] Console: switching to colour dummy device 80x25
>>>>> IGT-Version: 1.29-1.28 (aarch64) (Linux: 6.12.0-rc1-00022- ge581f752bf79 aarch64)
>>>>> [ 2566.674859] [IGT] kms_writeback: executing
>>>>> Using IGT_SRANDOM=1709057323 for randomisation
>>>>> Opened device: /dev/dri/card0
>>>>> [ 2566.741375] [IGT] kms_writeback: starting subtest dump-writeback
>>>>> Starting subtest: dump-writeback
>>>>> Subtest dump-writeback: SUCCESS (0.305s)[ 2567.053189] [IGT] kms_writeback: finished subtest dump-writeback, SUCCESS
>>>>>
>>>>> [ 2567.064505] [IGT] kms_writeback: starting subtest dump-valid-clones
>>>>> Starting subtest: dump-valid-clones
>>>>> [ 2567.762793] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
>>>>> [ 2567.771919] Mem abort info:
>>>>> [ 2567.774888] ESR = 0x0000000096000006
>>>>> [ 2567.778831] EC = 0x25: DABT (current EL), IL = 32 bits
>>>>> [ 2567.784371] SET = 0, FnV = 0
>>>>> [ 2567.787601] EA = 0, S1PTW = 0
>>>>> [ 2567.790942] FSC = 0x06: level 2 translation fault
>>>>> [ 2567.796044] Data abort info:
>>>>> [ 2567.799083] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
>>>>> [ 2567.804793] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>>>>> [ 2567.810057] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>>>>> [ 2567.815600] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008d60cf000
>>>>> [ 2567.822290] [0000000000000010] pgd=08000008d6049003, p4d=08000008d6049003, pud=080000089397e003, pmd=0000000000000000
>>>>> [ 2567.833254] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
>>>>> [ 2567.839747] Modules linked in: snd_soc_wsa884x q6prm_clocks q6apm_lpass_dais snd_q6dsp_common q6apm_dai q6prm 8021q garp mrp stp llc usb_f_fs libcomposite qrtr_mhi snd_soc_hdmi_codec ath12k mac80211 libarc4 mhi panel_visionox_vtdr6130 snd_q6apm pci_pwrctl_pwrseq pci_pwrctl_core rpmsg_ctrl apr fastrpc qrtr_smd rpmsg_char wcd939x_usbss nb7vpq904m qcom_pd_mapper goodix_berlin_spi goodix_berlin_core ucsi_glink typec_ucsi pmic_glink_altmode aux_hpd_bridge qcom_battmgr leds_qcom_lpg msm ocmem drm_exec hci_uart qcom_pbs gpu_sched led_class_multicolor btqca phy_qcom_eusb2_repeater btbcm qcom_spmi_temp_alarm drm_dp_aux_bus phy_qcom_qmp_combo crct10dif_ce bluetooth drm_display_helper sm3_ce ecdh_generic aux_bridge sm3 snd_soc_sc8280xp pwrseq_qcom_wcn sha3_ce snd_soc_qcom_sdw rtc_pm8xxx qcom_pon ecc nvmem_qcom_spmi_sdam sha512_ce qcom_stats spi_geni_qcom snd_soc_qcom_common sha512_arm64 pwrseq_core i2c_qcom_geni cfg80211 drm_kms_helper dispcc_sm8550 gpi ipa
>>>>> snd_soc_lpass_va_macro snd_soc_lpass_tx_macro soundwire_qcom
>>>>> [ 2567.839860] pinctrl_sm8650_lpass_lpi snd_soc_lpass_wsa_macro snd_soc_lpass_rx_macro rfkill slimbus phy_qcom_snps_eusb2 pinctrl_lpass_lpi gpucc_sm8650 snd_soc_lpass_macro_common qcom_q6v5_pas qcom_pil_info qcom_q6v5 qcrypto authenc icc_bwmon qcom_sysmon qcom_common qrtr qcom_glink_smem phy_qcom_qmp_pcie mdt_loader libdes llcc_qcom ufs_qcom phy_qcom_qmp_ufs pmic_glink snd_soc_wcd939x rmtfs_mem pdr_interface snd_soc_wcd939x_sdw regmap_sdw qcom_pdr_msg snd_soc_wcd_mbhc qmi_helpers snd_soc_wcd_classh soundwire_bus typec nvmem_reboot_mode qcom_rng socinfo fuse drm backlight ipv6
>>>>> [ 2567.983445] CPU: 5 UID: 0 PID: 554 Comm: kms_writeback Tainted: G S 6.12.0-rc1-00022-ge581f752bf79 #2
>>>>> [ 2567.994390] Tainted: [S]=CPU_OUT_OF_SPEC
>>>>> [ 2567.998483] Hardware name: Qualcomm Technologies, Inc. SM8650 QRD (DT)
>>>>> [ 2568.005244] pstate: 81400005 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
>>>>> [ 2568.012455] pc : dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>>>>> [ 2568.019009] lr : dpu_encoder_helper_phys_setup_cwb+0x88/0x1ec [msm]
>>>>> [ 2568.025532] sp : ffff80008939b7e0
>>>>> [ 2568.028999] x29: ffff80008939b810 x28: ffffcbcb66f26068 x27: ffff37ad962cb080
>>>>> [ 2568.036388] x26: ffff37ad9887ed80 x25: ffff80008939b878 x24: ffff37ad43642a80
>>>>> [ 2568.043775] x23: 0000000000000000 x22: ffff37ad42812080 x21: ffff37ad43642a80
>>>>> [ 2568.051163] x20: ffff37ad962cb080 x19: ffff37ad962c8080 x18: 0000000000000001
>>>>> [ 2568.058552] x17: 000000040044ffff x16: ffffcbcbb0fc8c64 x15: 00003d08ffff9c00
>>>>> [ 2568.065939] x14: 00000013519b2832 x13: ffff37ad9d392200 x12: 000000000000000b
>>>>> [ 2568.073325] x11: ffff37ad40dc56c0 x10: ffff37ad9d392200 x9 : ffff37afbe7bba80
>>>>> [ 2568.080712] x8 : ffff37ad42812718 x7 : 0000000000000004 x6 : ffff37ad989ac798
>>>>> [ 2568.088098] x5 : 0000000000000002 x4 : ffff80008939b7f8 x3 : ffff37ad962cb150
>>>>> [ 2568.095480] x2 : 0000000000000002 x1 : 0000000000000000 x0 : 0000000000000001
>>>>> [ 2568.102868] Call trace:
>>>>> [ 2568.105446] dpu_encoder_helper_phys_setup_cwb+0xb8/0x1ec [msm]
>>>>> [ 2568.111608] dpu_encoder_helper_phys_cleanup+0x328/0x3c4 [msm]
>>>>> [ 2568.117692] dpu_encoder_phys_wb_disable+0x80/0xac [msm]
>>>>> [ 2568.123233] dpu_encoder_virt_atomic_disable+0xb4/0x160 [msm]
>>>>> [ 2568.129224] disable_outputs+0x108/0x32c [drm_kms_helper]
>>>>> [ 2568.134858] drm_atomic_helper_commit_modeset_disables+0x1c/0x4c [drm_kms_helper]
>>>>> [ 2568.142614] msm_atomic_commit_tail+0x188/0x514 [msm]
>>>>> [ 2568.147894] commit_tail+0xa4/0x18c [drm_kms_helper]
>>>>> [ 2568.153065] drm_atomic_helper_commit+0x17c/0x194 [drm_kms_helper]
>>>>> [ 2568.159482] drm_atomic_commit+0xb8/0xf4 [drm]
>>>>> [ 2568.164176] drm_mode_atomic_ioctl+0xad4/0xd88 [drm]
>>>>> [ 2568.169369] drm_ioctl_kernel+0xc0/0x128 [drm]
>>>>> [ 2568.174039] drm_ioctl+0x218/0x49c [drm]
>>>>> [ 2568.178165] __arm64_sys_ioctl+0xac/0xf0
>>>>> [ 2568.182271] invoke_syscall+0x48/0x10c
>>>>> [ 2568.186217] el0_svc_common.constprop.0+0xc0/0xe0
>>>>> [ 2568.191109] do_el0_svc+0x1c/0x28
>>>>> [ 2568.194576] el0_svc+0x34/0xd8
>>>>> [ 2568.197788] el0t_64_sync_handler+0x120/0x12c
>>>>> [ 2568.202321] el0t_64_sync+0x190/0x194
>>>>> [ 2568.206157] Code: 910063e1 f8607822 f8607861 b9401042 (b9401021)
>>>>> [ 2568.212484] ---[ end trace 0000000000000000 ]---
>>>>>
>>>>> Neil
>>>>>
>>>>>> + rt_pp_idx[i] = enable ? hw_pp->idx : PINGPONG_NONE;
>>>>>> + break;
>>>>>> + }
>>>>>> + }
>>>>>> + }
>>>>>> +
>>>>>> + /*
>>>>>> + * The CWB mux supports using LM or DSPP as tap points. For now,
>>>>>> + * always use LM tap point
>>>>>> + */
>>>>>> + cwb_cfg.input = INPUT_MODE_LM_OUT;
>>>>>> +
>>>>>> + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>>>>>> + hw_cwb = dpu_enc->hw_cwb[i];
>>>>>> + if (!hw_cwb)
>>>>>> + continue;
>>>>>> +
>>>>>> + cwb_cfg.pp_idx = rt_pp_idx[i];
>>>>>> +
>>>>>> + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
>>>>>> + }
>>>>>> +}
>>>>>> +
>>>>>> void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
>>>>>> const struct msm_format *dpu_fmt,
>>>>>> u32 output_type)
>>>>>> @@ -2557,6 +2630,14 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
>>>>>> return INTF_MODE_NONE;
>>>>>> }
>>>>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc)
>>>>>> +{
>>>>>> + struct drm_encoder *encoder = phys_enc->parent;
>>>>>> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
>>>>>> +
>>>>>> + return dpu_enc->cwb_mask;
>>>>>> +}
>>>>>> +
>>>>>> unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
>>>>>> {
>>>>>> struct drm_encoder *encoder = phys_enc->parent;
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>>>> index e77ebe3a68da..d7a02d1f8053 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>>>>> @@ -1,6 +1,6 @@
>>>>>> /* SPDX-License-Identifier: GPL-2.0-only */
>>>>>> /*
>>>>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>> * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
>>>>>> */
>>>>>> @@ -331,6 +331,12 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
>>>>>> return BLEND_3D_NONE;
>>>>>> }
>>>>>> +/**
>>>>>> + * dpu_encoder_helper_get_cwb - get CWB blocks mask for the DPU encoder
>>>>>> + * @phys_enc: Pointer to physical encoder structure
>>>>>> + */
>>>>>> +unsigned int dpu_encoder_helper_get_cwb(struct dpu_encoder_phys *phys_enc);
>>>>>> +
>>>>>> /**
>>>>>> * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
>>>>>> * This helper function is used by physical encoder to get DSC blocks mask
>>>>>> @@ -400,6 +406,14 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
>>>>>> */
>>>>>> void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
>>>>>> +/**
>>>>>> + * dpu_encoder_helper_phys_setup_cwb - helper to configure CWB muxes
>>>>>> + * @phys_enc: Pointer to physical encoder structure
>>>>>> + * @enable: Enable CWB mux
>>>>>> + */
>>>>>> +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
>>>>>> + bool enable);
>>>>>> +
>>>>>> /**
>>>>>> * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
>>>>>> * @phys_enc: Pointer to physical encoder
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>>>> index 882c717859ce..e88c4d91041f 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
>>>>>> @@ -1,6 +1,6 @@
>>>>>> // SPDX-License-Identifier: GPL-2.0-only
>>>>>> /*
>>>>>> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>> */
>>>>>> #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
>>>>>> @@ -342,6 +342,8 @@ static void dpu_encoder_phys_wb_setup(
>>>>>> dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
>>>>>> + dpu_encoder_helper_phys_setup_cwb(phys_enc, true);
>>>>>> +
>>>>>> dpu_encoder_phys_wb_setup_ctl(phys_enc);
>>>>>> }
>>>>>>
>>>>>
>>>>
>>>
>>
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 17/22] drm/msm/dpu: Support CWB in dpu_hw_ctl
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (15 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 16/22] drm/msm/dpu: Configure CWB in writeback encoder Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 18/22] drm/msm/dpu: Adjust writeback phys encoder setup for CWB Jessica Zhang
` (4 subsequent siblings)
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
The CWB mux has a pending flush bit and *_active register.
Add support for configuring them within the dpu_hw_ctl layer.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 13 ++++++++++
.../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 30 +++++++++++++++++++++-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 15 ++++++++++-
4 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 2628f2d55cb3..7337bb3ae7ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2108,6 +2108,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
intf_cfg.stream_sel = 0; /* Don't care value for video mode */
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
+ intf_cfg.cwb = dpu_enc->cwb_mask;
if (phys_enc->hw_intf)
intf_cfg.intf = phys_enc->hw_intf->idx;
@@ -2130,6 +2131,7 @@ void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
struct dpu_hw_cwb *hw_cwb;
+ struct dpu_hw_ctl *hw_ctl;
struct dpu_hw_cwb_setup_cfg cwb_cfg;
struct dpu_kms *dpu_kms;
@@ -2140,6 +2142,14 @@ void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
if (!phys_enc || !phys_enc->hw_wb || !dpu_enc->cwb_mask)
return;
+ hw_ctl = phys_enc->hw_ctl;
+
+ if (!phys_enc->hw_ctl) {
+ DPU_DEBUG("[wb:%d] no ctl assigned\n",
+ phys_enc->hw_wb->idx - WB_0);
+ return;
+ }
+
dpu_kms = phys_enc->dpu_kms;
global_state = dpu_kms_get_existing_global_state(dpu_kms);
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
@@ -2184,6 +2194,9 @@ void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
cwb_cfg.pp_idx = rt_pp_idx[i];
hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
+
+ if (hw_ctl->ops.update_pending_flush_cwb)
+ hw_ctl->ops.update_pending_flush_cwb(hw_ctl, hw_cwb->idx);
}
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index e88c4d91041f..d0bf23d4da5f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -236,6 +236,7 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)
intf_cfg.intf = DPU_NONE;
intf_cfg.wb = hw_wb->idx;
+ intf_cfg.cwb = dpu_encoder_helper_get_cwb(phys_enc);
if (mode_3d && hw_pp && hw_pp->merge_3d)
intf_cfg.merge_3d = hw_pp->merge_3d->idx;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 2e50049f2f85..792687b010ee 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/delay.h>
@@ -31,12 +31,14 @@
#define CTL_MERGE_3D_ACTIVE 0x0E4
#define CTL_DSC_ACTIVE 0x0E8
#define CTL_WB_ACTIVE 0x0EC
+#define CTL_CWB_ACTIVE 0x0F0
#define CTL_INTF_ACTIVE 0x0F4
#define CTL_CDM_ACTIVE 0x0F8
#define CTL_FETCH_PIPE_ACTIVE 0x0FC
#define CTL_MERGE_3D_FLUSH 0x100
#define CTL_DSC_FLUSH 0x104
#define CTL_WB_FLUSH 0x108
+#define CTL_CWB_FLUSH 0x10C
#define CTL_INTF_FLUSH 0x110
#define CTL_CDM_FLUSH 0x114
#define CTL_PERIPH_FLUSH 0x128
@@ -53,6 +55,7 @@
#define PERIPH_IDX 30
#define INTF_IDX 31
#define WB_IDX 16
+#define CWB_IDX 28
#define DSPP_IDX 29 /* From DPU hw rev 7.x.x */
#define CTL_INVALID_BIT 0xffff
#define CTL_DEFAULT_GROUP_ID 0xf
@@ -110,6 +113,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
ctx->pending_flush_mask = 0x0;
ctx->pending_intf_flush_mask = 0;
ctx->pending_wb_flush_mask = 0;
+ ctx->pending_cwb_flush_mask = 0;
ctx->pending_merge_3d_flush_mask = 0;
ctx->pending_dsc_flush_mask = 0;
ctx->pending_cdm_flush_mask = 0;
@@ -144,6 +148,9 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
if (ctx->pending_flush_mask & BIT(WB_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
ctx->pending_wb_flush_mask);
+ if (ctx->pending_flush_mask & BIT(CWB_IDX))
+ DPU_REG_WRITE(&ctx->hw, CTL_CWB_FLUSH,
+ ctx->pending_cwb_flush_mask);
if (ctx->pending_flush_mask & BIT(DSPP_IDX))
for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) {
@@ -310,6 +317,13 @@ static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
ctx->pending_flush_mask |= BIT(WB_IDX);
}
+static void dpu_hw_ctl_update_pending_flush_cwb_v1(struct dpu_hw_ctl *ctx,
+ enum dpu_cwb cwb)
+{
+ ctx->pending_cwb_flush_mask |= BIT(cwb - CWB_0);
+ ctx->pending_flush_mask |= BIT(CWB_IDX);
+}
+
static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx,
enum dpu_intf intf)
{
@@ -547,6 +561,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
u32 intf_active = 0;
u32 dsc_active = 0;
u32 wb_active = 0;
+ u32 cwb_active = 0;
u32 mode_sel = 0;
/* CTL_TOP[31:28] carries group_id to collate CTL paths
@@ -561,6 +576,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
+ cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE);
dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);
if (cfg->intf)
@@ -569,12 +585,16 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
if (cfg->wb)
wb_active |= BIT(cfg->wb - WB_0);
+ if (cfg->cwb)
+ cwb_active |= cfg->cwb;
+
if (cfg->dsc)
dsc_active |= cfg->dsc;
DPU_REG_WRITE(c, CTL_TOP, mode_sel);
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
+ DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active);
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
if (cfg->merge_3d)
@@ -624,6 +644,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 intf_active = 0;
u32 wb_active = 0;
+ u32 cwb_active = 0;
u32 merge3d_active = 0;
u32 dsc_active;
u32 cdm_active;
@@ -651,6 +672,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
}
+ if (cfg->cwb) {
+ cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE);
+ cwb_active &= ~cfg->cwb;
+ DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active);
+ }
+
if (cfg->wb) {
wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
wb_active &= ~BIT(cfg->wb - WB_0);
@@ -703,6 +730,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->update_pending_flush_merge_3d =
dpu_hw_ctl_update_pending_flush_merge_3d_v1;
ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
+ ops->update_pending_flush_cwb = dpu_hw_ctl_update_pending_flush_cwb_v1;
ops->update_pending_flush_dsc =
dpu_hw_ctl_update_pending_flush_dsc_v1;
ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 4401fdc0f3e4..45c1bcb737fa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _DPU_HW_CTL_H
@@ -42,6 +42,7 @@ struct dpu_hw_stage_cfg {
* @cdm: CDM block used
* @stream_sel: Stream selection for multi-stream interfaces
* @dsc: DSC BIT masks used
+ * @cwb: CWB BIT masks used
*/
struct dpu_hw_intf_cfg {
enum dpu_intf intf;
@@ -51,6 +52,7 @@ struct dpu_hw_intf_cfg {
enum dpu_ctl_mode_sel intf_mode_sel;
enum dpu_cdm cdm;
int stream_sel;
+ unsigned int cwb;
unsigned int dsc;
};
@@ -114,6 +116,15 @@ struct dpu_hw_ctl_ops {
void (*update_pending_flush_wb)(struct dpu_hw_ctl *ctx,
enum dpu_wb blk);
+ /**
+ * OR in the given flushbits to the cached pending_(cwb_)flush_mask
+ * No effect on hardware
+ * @ctx : ctl path ctx pointer
+ * @blk : concurrent writeback block index
+ */
+ void (*update_pending_flush_cwb)(struct dpu_hw_ctl *ctx,
+ enum dpu_cwb blk);
+
/**
* OR in the given flushbits to the cached pending_(intf_)flush_mask
* No effect on hardware
@@ -258,6 +269,7 @@ struct dpu_hw_ctl_ops {
* @pending_flush_mask: storage for pending ctl_flush managed via ops
* @pending_intf_flush_mask: pending INTF flush
* @pending_wb_flush_mask: pending WB flush
+ * @pending_cwb_flush_mask: pending CWB flush
* @pending_dsc_flush_mask: pending DSC flush
* @pending_cdm_flush_mask: pending CDM flush
* @ops: operation list
@@ -274,6 +286,7 @@ struct dpu_hw_ctl {
u32 pending_flush_mask;
u32 pending_intf_flush_mask;
u32 pending_wb_flush_mask;
+ u32 pending_cwb_flush_mask;
u32 pending_periph_flush_mask;
u32 pending_merge_3d_flush_mask;
u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 18/22] drm/msm/dpu: Adjust writeback phys encoder setup for CWB
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (16 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 17/22] drm/msm/dpu: Support CWB in dpu_hw_ctl Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 19/22] drm/msm/dpu: Start frame done timer after encoder kickoff Jessica Zhang
` (3 subsequent siblings)
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Adjust QoS remapper, OT limit, and CDP parameters to account for
concurrent writeback
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
index d0bf23d4da5f..2fe818d38118 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -68,7 +68,7 @@ static void dpu_encoder_phys_wb_set_ot_limit(
ot_params.num = hw_wb->idx - WB_0;
ot_params.width = phys_enc->cached_mode.hdisplay;
ot_params.height = phys_enc->cached_mode.vdisplay;
- ot_params.is_wfd = true;
+ ot_params.is_wfd = !dpu_encoder_helper_get_cwb(phys_enc);
ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
ot_params.vbif_idx = hw_wb->caps->vbif_idx;
ot_params.rd = false;
@@ -111,7 +111,7 @@ static void dpu_encoder_phys_wb_set_qos_remap(
qos_params.vbif_idx = hw_wb->caps->vbif_idx;
qos_params.xin_id = hw_wb->caps->xin_id;
qos_params.num = hw_wb->idx - WB_0;
- qos_params.is_rt = false;
+ qos_params.is_rt = dpu_encoder_helper_get_cwb(phys_enc);
DPU_DEBUG("[qos_remap] wb:%d vbif:%d xin:%d is_rt:%d\n",
qos_params.num,
@@ -174,6 +174,7 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
struct dpu_hw_wb *hw_wb;
struct dpu_hw_wb_cfg *wb_cfg;
+ u32 cdp_usage;
if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog) {
DPU_ERROR("invalid encoder\n");
@@ -182,6 +183,10 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
hw_wb = phys_enc->hw_wb;
wb_cfg = &wb_enc->wb_cfg;
+ if (dpu_encoder_helper_get_cwb(phys_enc))
+ cdp_usage = DPU_PERF_CDP_USAGE_RT;
+ else
+ cdp_usage = DPU_PERF_CDP_USAGE_NRT;
wb_cfg->intf_mode = phys_enc->intf_mode;
wb_cfg->roi.x1 = 0;
@@ -199,7 +204,7 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
const struct dpu_perf_cfg *perf = phys_enc->dpu_kms->catalog->perf;
hw_wb->ops.setup_cdp(hw_wb, wb_cfg->dest.format,
- perf->cdp_cfg[DPU_PERF_CDP_USAGE_NRT].wr_enable);
+ perf->cdp_cfg[cdp_usage].wr_enable);
}
if (hw_wb->ops.setup_outaddress)
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 19/22] drm/msm/dpu: Start frame done timer after encoder kickoff
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (17 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 18/22] drm/msm/dpu: Adjust writeback phys encoder setup for CWB Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 20/22] drm/msm/dpu: Skip trigger flush and start for CWB Jessica Zhang
` (2 subsequent siblings)
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Starting the frame done timer before the encoder is finished kicking off
can lead to unnecessary frame done timeouts when the device is
experiencing heavy load (ex. when debug logs are enabled).
Thus, create a separate API for starting the encoder frame done timer and
call it after the encoder kickoff is finished
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 +++-
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 ++++++++++++++++++-------
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 4 +++-
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index f20e44e9fc05..e8c80ea12866 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -970,8 +970,10 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
dpu_vbif_clear_errors(dpu_kms);
- drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
+ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) {
dpu_encoder_kickoff(encoder);
+ dpu_encoder_start_frame_done_timer(encoder);
+ }
reinit_completion(&dpu_crtc->frame_done_comp);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 7337bb3ae7ca..ac3ff13b65c3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1941,18 +1941,16 @@ bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc)
return true;
}
-void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
+/**
+ * dpu_encoder_start_frame_done_timer - Start the encoder frame done timer
+ * @drm_enc: Pointer to drm encoder structure
+ */
+void dpu_encoder_start_frame_done_timer(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc;
- struct dpu_encoder_phys *phys;
unsigned long timeout_ms;
- unsigned int i;
- DPU_ATRACE_BEGIN("encoder_kickoff");
dpu_enc = to_dpu_encoder_virt(drm_enc);
-
- trace_dpu_enc_kickoff(DRMID(drm_enc));
-
timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 /
drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode);
@@ -1960,6 +1958,19 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
mod_timer(&dpu_enc->frame_done_timer,
jiffies + msecs_to_jiffies(timeout_ms));
+}
+
+void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
+{
+ struct dpu_encoder_virt *dpu_enc;
+ struct dpu_encoder_phys *phys;
+ unsigned int i;
+
+ DPU_ATRACE_BEGIN("encoder_kickoff");
+ dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+ trace_dpu_enc_kickoff(DRMID(drm_enc));
+
/* All phys encs are ready to go, trigger the kickoff */
_dpu_encoder_kickoff_phys(dpu_enc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 0d27e50384f0..deaa0463b289 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
@@ -210,4 +210,6 @@ void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
*/
bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc);
+void dpu_encoder_start_frame_done_timer(struct drm_encoder *drm_enc);
+
#endif /* __DPU_ENCODER_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 20/22] drm/msm/dpu: Skip trigger flush and start for CWB
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (18 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 19/22] drm/msm/dpu: Start frame done timer after encoder kickoff Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:43 ` Dmitry Baryshkov
2024-09-24 22:59 ` [PATCH v2 21/22] drm/msm/dpu: Reorder encoder kickoff " Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 22/22] drm/msm/dpu: Set possible clones for all encoders Jessica Zhang
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
For concurrent writeback, the real time encoder is responsible for
trigger flush and trigger start. Return early for trigger start and
trigger flush for the concurrent writeback encoders.
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index ac3ff13b65c3..87eaaf1196c2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1488,6 +1488,7 @@ static void dpu_encoder_off_work(struct work_struct *work)
static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phys, uint32_t extra_flush_bits)
{
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
struct dpu_hw_ctl *ctl;
int pending_kickoff_cnt;
u32 ret = UINT_MAX;
@@ -1505,6 +1506,15 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc,
pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys);
+ /* Return early if encoder is writeback and in clone mode */
+ if (drm_enc->encoder_type == DRM_MODE_ENCODER_VIRTUAL &&
+ dpu_enc->cwb_mask) {
+ DPU_DEBUG("encoder %d skip flush for concurrent writeback encoder\n",
+ DRMID(drm_enc));
+ return;
+ }
+
+
if (extra_flush_bits && ctl->ops.update_pending_flush)
ctl->ops.update_pending_flush(ctl, extra_flush_bits);
@@ -1527,6 +1537,8 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc,
*/
static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys)
{
+ struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys->parent);
+
if (!phys) {
DPU_ERROR("invalid argument(s)\n");
return;
@@ -1537,6 +1549,12 @@ static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys)
return;
}
+ if (phys->parent->encoder_type == DRM_MODE_ENCODER_VIRTUAL &&
+ dpu_enc->cwb_mask) {
+ DPU_DEBUG("encoder %d CWB enabled, skipping\n", DRMID(phys->parent));
+ return;
+ }
+
if (phys->ops.trigger_start && phys->enable_state != DPU_ENC_DISABLED)
phys->ops.trigger_start(phys);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 20/22] drm/msm/dpu: Skip trigger flush and start for CWB
2024-09-24 22:59 ` [PATCH v2 20/22] drm/msm/dpu: Skip trigger flush and start for CWB Jessica Zhang
@ 2024-09-24 23:43 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:43 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:36PM GMT, Jessica Zhang wrote:
> For concurrent writeback, the real time encoder is responsible for
> trigger flush and trigger start. Return early for trigger start and
> trigger flush for the concurrent writeback encoders.
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v2 21/22] drm/msm/dpu: Reorder encoder kickoff for CWB
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (19 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 20/22] drm/msm/dpu: Skip trigger flush and start for CWB Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 22:59 ` [PATCH v2 22/22] drm/msm/dpu: Set possible clones for all encoders Jessica Zhang
21 siblings, 0 replies; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Add a helper that will handle the correct order of the encoder kickoffs
for concurrent writeback.
For concurrent writeback, the realtime encoder must always kickoff last
as it will call the trigger flush and start.
This avoids the following scenario where the writeback encoder
increments the pending kickoff count after the WB_DONE interrupt is
fired:
If the realtime encoder is kicked off first, the encoder kickoff will
flush/start the encoder and increment the pending kickoff count. The
WB_DONE interrupt then fires (before the writeback encoder is kicked
off). When the writeback encoder enters its kickoff, it will skip the
flush/start (due to CWB being enabled) and hit a frame done timeout
as the frame was kicked off (and the WB_DONE interrupt fired) without
the pending kickoff count being incremented.
In addition, the writeback timer should only start after the realtime
encoder is kicked off to ensure that we don't get timeouts when the
system has a heavy load (ex. when debug logs are enabled)
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 74 ++++++++++++++++++++++++++------
1 file changed, 60 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e8c80ea12866..4365e9cf609d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -928,6 +928,45 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc)
return rc;
}
+static int dpu_crtc_kickoff_clone_mode(struct drm_crtc *crtc)
+{
+ struct drm_encoder *encoder;
+ struct drm_encoder *rt_encoder = NULL, *wb_encoder;
+ struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+
+ /* Find encoder for real time display */
+ drm_for_each_encoder_mask(encoder, crtc->dev,
+ crtc->state->encoder_mask) {
+ if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
+ wb_encoder = encoder;
+ else
+ rt_encoder = encoder;
+ }
+
+ if (!rt_encoder || !wb_encoder) {
+ DRM_DEBUG_ATOMIC("real time or wb encoder not found\n");
+ return -EINVAL;
+ }
+
+ dpu_encoder_prepare_for_kickoff(wb_encoder);
+ dpu_encoder_prepare_for_kickoff(rt_encoder);
+
+ dpu_vbif_clear_errors(dpu_kms);
+
+ /*
+ * Kickoff real time encoder last as it's the encoder that
+ * will do the flush
+ */
+ dpu_encoder_kickoff(wb_encoder);
+ dpu_encoder_kickoff(rt_encoder);
+
+ /* Don't start frame done timers until the kickoffs have finished */
+ dpu_encoder_start_frame_done_timer(wb_encoder);
+ dpu_encoder_start_frame_done_timer(rt_encoder);
+
+ return 0;
+}
+
void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
{
struct drm_encoder *encoder;
@@ -952,13 +991,27 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
goto end;
}
}
- /*
- * Encoder will flush/start now, unless it has a tx pending. If so, it
- * may delay and flush at an irq event (e.g. ppdone)
- */
- drm_for_each_encoder_mask(encoder, crtc->dev,
- crtc->state->encoder_mask)
- dpu_encoder_prepare_for_kickoff(encoder);
+
+ if (drm_crtc_in_clone_mode(crtc->state)) {
+ if (dpu_crtc_kickoff_clone_mode(crtc))
+ goto end;
+ } else {
+ /*
+ * Encoder will flush/start now, unless it has a tx pending.
+ * If so, it may delay and flush at an irq event (e.g. ppdone)
+ */
+ drm_for_each_encoder_mask(encoder, crtc->dev,
+ crtc->state->encoder_mask)
+ dpu_encoder_prepare_for_kickoff(encoder);
+
+ dpu_vbif_clear_errors(dpu_kms);
+
+ drm_for_each_encoder_mask(encoder, crtc->dev,
+ crtc->state->encoder_mask) {
+ dpu_encoder_kickoff(encoder);
+ dpu_encoder_start_frame_done_timer(encoder);
+ }
+ }
if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) {
/* acquire bandwidth and other resources */
@@ -968,13 +1021,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
dpu_crtc->play_count++;
- dpu_vbif_clear_errors(dpu_kms);
-
- drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) {
- dpu_encoder_kickoff(encoder);
- dpu_encoder_start_frame_done_timer(encoder);
- }
-
reinit_completion(&dpu_crtc->frame_done_comp);
end:
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* [PATCH v2 22/22] drm/msm/dpu: Set possible clones for all encoders
2024-09-24 22:59 [PATCH v2 00/22] drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ Jessica Zhang
` (20 preceding siblings ...)
2024-09-24 22:59 ` [PATCH v2 21/22] drm/msm/dpu: Reorder encoder kickoff " Jessica Zhang
@ 2024-09-24 22:59 ` Jessica Zhang
2024-09-24 23:44 ` Dmitry Baryshkov
21 siblings, 1 reply; 64+ messages in thread
From: Jessica Zhang @ 2024-09-24 22:59 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, quic_abhinavk, Sean Paul,
Marijn Suijten, David Airlie, Daniel Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann
Cc: quic_ebharadw, linux-arm-msm, dri-devel, freedreno, linux-kernel,
Rob Clark, Ville Syrjälä, Jessica Zhang
Set writeback encoders as possible clones for non-writeback encoders and
vice versa.
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 32 +++++++++++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 2 ++
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 7 +++++--
3 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 87eaaf1196c2..39dabb9eb39a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2409,6 +2409,38 @@ static int dpu_encoder_virt_add_phys_encs(
return 0;
}
+/**
+ * dpu_encoder_get_clones - Calculate the possible_clones for DPU encoder
+ * @drm_enc: DRM encoder pointer
+ * Returns: possible_clones mask
+ */
+uint32_t dpu_encoder_get_clones(struct drm_encoder *drm_enc)
+{
+ struct drm_encoder *curr;
+ int type = drm_enc->encoder_type;
+ uint32_t clone_mask = drm_encoder_mask(drm_enc);
+
+ /*
+ * Set writeback as possible clones of real-time encoders and real-time
+ * encoders as clones of writeback.
+ *
+ * Writeback encoders can't be clones of each other and real-time
+ * encoders can't be clones of each other.
+ */
+ drm_for_each_encoder(curr, drm_enc->dev) {
+ if (type == DRM_MODE_ENCODER_VIRTUAL &&
+ curr->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
+ continue;
+ if (type != DRM_MODE_ENCODER_VIRTUAL &&
+ curr->encoder_type != DRM_MODE_ENCODER_VIRTUAL)
+ continue;
+
+ clone_mask |= drm_encoder_mask(curr);
+ }
+
+ return clone_mask;
+}
+
static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
struct msm_display_info *disp_info)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index deaa0463b289..1692e7de079d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -98,6 +98,8 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder);
*/
void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder);
+uint32_t dpu_encoder_get_clones(struct drm_encoder *drm_enc);
+
/**
* dpu_encoder_init - initialize virtual encoder object
* @dev: Pointer to drm device structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 47e304b357e8..5effa108f328 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2013 Red Hat
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Author: Rob Clark <robdclark@gmail.com>
*/
@@ -793,8 +793,11 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
return ret;
num_encoders = 0;
- drm_for_each_encoder(encoder, dev)
+ drm_for_each_encoder(encoder, dev) {
num_encoders++;
+ if (catalog->cwb_count > 0)
+ encoder->possible_clones = dpu_encoder_get_clones(encoder);
+ }
max_crtc_count = min(catalog->mixer_count, num_encoders);
--
2.34.1
^ permalink raw reply related [flat|nested] 64+ messages in thread* Re: [PATCH v2 22/22] drm/msm/dpu: Set possible clones for all encoders
2024-09-24 22:59 ` [PATCH v2 22/22] drm/msm/dpu: Set possible clones for all encoders Jessica Zhang
@ 2024-09-24 23:44 ` Dmitry Baryshkov
0 siblings, 0 replies; 64+ messages in thread
From: Dmitry Baryshkov @ 2024-09-24 23:44 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, quic_abhinavk, Sean Paul, Marijn Suijten, David Airlie,
Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, quic_ebharadw, linux-arm-msm, dri-devel,
freedreno, linux-kernel, Rob Clark, Ville Syrjälä
On Tue, Sep 24, 2024 at 03:59:38PM GMT, Jessica Zhang wrote:
> Set writeback encoders as possible clones for non-writeback encoders and
> vice versa.
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 32 +++++++++++++++++++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 2 ++
> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 7 +++++--
> 3 files changed, 39 insertions(+), 2 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 64+ messages in thread