[PATCH v3] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread jiadong.zhu
From: Jiadong Zhu 

The job's embedded fence is dma_fence which shall not be conversed
to amdgpu_fence. The start timestamp shall be saved on job for
hw_fence.

v2: optimize get_fence_start_time.
v3: set start time only when mcbp enabled.

Signed-off-by: Jiadong Zhu 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 32 ---
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2f24a6aa13bf..8a2fdf5a310c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -88,6 +88,31 @@ static inline struct amdgpu_fence *to_amdgpu_fence(struct 
dma_fence *f)
return NULL;
 }
 
+static inline void set_fence_start_time(struct dma_fence *f, ktime_t 
start_timestamp)
+{
+   if (f->ops == &amdgpu_fence_ops) {
+   struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, 
base);
+
+   __f->start_timestamp = start_timestamp;
+   } else if (f->ops == &amdgpu_job_fence_ops) {
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job, 
hw_fence);
+
+   job->start_timestamp = start_timestamp;
+   }
+}
+
+static inline ktime_t get_fence_start_time(struct dma_fence *f)
+{
+   if (unlikely(f->ops == &amdgpu_fence_ops)) {
+   struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, 
base);
+
+   return __f->start_timestamp;
+   }
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence);
+
+   return job->start_timestamp;
+}
+
 /**
  * amdgpu_fence_write - write a fence value
  *
@@ -197,7 +222,8 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct 
dma_fence **f, struct amd
}
}
 
-   to_amdgpu_fence(fence)->start_timestamp = ktime_get();
+   if (adev->gfx.mcbp)
+   set_fence_start_time(fence, ktime_get());
 
/* This function can't be called concurrently anyway, otherwise
 * emitting the fence would mess up the hardware ring buffer.
@@ -428,7 +454,7 @@ u64 amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring 
*ring)
return 0;
 
return ktime_us_delta(ktime_get(),
-   to_amdgpu_fence(fence)->start_timestamp);
+   get_fence_start_time(fence));
 }
 
 /**
@@ -451,7 +477,7 @@ void amdgpu_fence_update_start_timestamp(struct amdgpu_ring 
*ring, uint32_t seq,
if (!fence)
return;
 
-   to_amdgpu_fence(fence)->start_timestamp = timestamp;
+   set_fence_start_time(fence, timestamp);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index a963a25ddd62..3a73fe11a1ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -73,6 +73,9 @@ struct amdgpu_job {
uint64_tgds_va;
boolinit_shadow;
 
+   /* start timestamp for hw_fence*/
+   ktime_t start_timestamp;
+
/* job_run_counter >= 1 means a resubmit job */
uint32_tjob_run_counter;
 
-- 
2.25.1



回复:va range based memory management discussion (was: 回复:回复:Re:Proposal to add CRIU support to DRM render nodes)

2024-07-10 Thread 周春明(日月)
--
发件人:Felix Kuehling 
发送时间:2024年7月11日(星期四) 07:47
收件人:周春明(日月) ; Tvrtko Ursulin ; 
dri-de...@lists.freedesktop.org ; 
amd-gfx@lists.freedesktop.org ; Dave Airlie 
; Daniel Vetter ; criu 
抄 送:"Errabolu, Ramesh" ; "Christian König" 
; 张伦强(张尘) 
主 题:Re: va range based memory management discussion (was: 回复:回复:Re:Proposal to 
add CRIU support to DRM render nodes)
>On 2024-07-09 22:38, 周春明(日月) wrote:
>>
>>
>>
>>
>>
>>
>> --
>> 发件人:Felix Kuehling 
>> 发送时间:2024年7月10日(星期三) 01:07
>> 收件人:周春明(日月) ; Tvrtko Ursulin 
>> ; dri-de...@lists.freedesktop.org 
>> ; amd-gfx@lists.freedesktop.org 
>> ; Dave Airlie ; 
>> Daniel Vetter ; criu 
>> 抄 送:"Errabolu, Ramesh" ; "Christian König" 
>> 
>> 主 题:Re: 回复:Re:Proposal to add CRIU support to DRM render nodes
>>
>>
>>
>> On 2024-07-09 5:30, 周春明(日月) wrote:
>> >
>> >
>> >
>> >
>> >
>> >
>> > --
>> > 发件人:Felix Kuehling 
>> > 发送时间:2024年7月9日(星期二) 06:40
>> > 收件人:周春明(日月) ; Tvrtko Ursulin 
>> ; dri-de...@lists.freedesktop.org 
>> ; amd-gfx@lists.freedesktop.org 
>> ; Dave Airlie ; 
>> Daniel Vetter ; criu 
>> > 抄 送:"Errabolu, Ramesh" ; "Christian König" 
>> 
>> > 主 题:Re: Re:Proposal to add CRIU support to DRM render nodes
>> >
>> >
>> > On 2024-07-08 2:51, 周春明(日月) wrote:
>> >>
>> >>> Hi Felix,
>> >>>
>> >>> When I learn CRIU you introduced in 
>> https://github.com/checkpoint-restore/criu/tree/criu-dev/plugins/amdgpu 
>>  
>>  
>>  > 
>> > 
>> > > 
>>  
>>  > 
>> > 
>> > > 
>> > 
>> > > 
>> >> 
>> >> 
>> > 
>> , there is a sentence
>> >>> "ROCm manages memory in the form of buffer objects (BOs). We are 
>> also working on a new memory management API that will be based on 
>> virtual address ranges...",
>> >>> Out of curious, how about "new memory management based on virtual 
>> address ranges"? Any introduction for that?
> >>
> >>>Hi David,
>> >>
>> >>>This refers to the SVM API that has been in the upstream driver for 
>> a while now: 
>> https://elixir.bootlin.com/linux/v6.9.8/source/include/uapi/linux/kfd_ioctl.h#L732
>>  
>> >  > 
>> 
>>  
>> 
>>  > 
>> >
>>  
>> >
>>  >
>> >>
>> >> [David] Can all ROCm runtime memory management switch to use svm 
>> apis? No need BOs any more?
>>
>> >I had thought about that when I started working on SVM years ago. But 
>> I came to the conclusion that we need to use BOs for VRAM to support 
>> DMABuf exports and imports to support P2P and IPC features.
>>
>> [David] OK, I guessed you would say DMABuf and IPC factors, if we 
>> don't use dmabuf (as you know, dmabuf isn't popular in compute area) 
>> and implement a new ipc based on va ranges, is that possible to using 
>> svm api to cover all ROCm memory management?
>> When I tried memory pool used by cuda graph, seems that's OK.
>
>DMABuf and IPC are important for collective communications libraries 
>used by distributed applications. You could get away without it when 
>you're running a single-process application on a single machine. But 
>changing all memory allocations to SVM would probably cause some 
>performance regressions, because our BO allocators and memory mapping 
>functions are simpler and easier to optimize than for unified memory.
[David] Agree, BO allocators is simpler. If just for allocation, I think SVM 
can reach same perf as BOs.
>
>That leaves the question, what's the expected benefit or a compelling 
>reason for making such an invasive change?
[David] I just think va range is very like va management in CPU side, that can 
unify thinkings of theory 

RE: [PATCH] drm/amd/swsmu: enable Pstates profile levels for SMU v14.0.4

2024-07-10 Thread Huang, Tim
[Public]

This patch is,

Reviewed-by: Tim Huang 



> -Original Message-
> From: Alex Deucher 
> Sent: Wednesday, July 10, 2024 9:48 PM
> To: Ma, Li 
> Cc: amd-gfx@lists.freedesktop.org; Huang, Tim ;
> Deucher, Alexander ; Zhang, Yifan
> 
> Subject: Re: [PATCH] drm/amd/swsmu: enable Pstates profile levels for SMU
> v14.0.4
>
> On Wed, Jul 10, 2024 at 5:50 AM Li Ma  wrote:
> >
> > Enables following UMD stable Pstates profile levels of
> > power_dpm_force_performance_level for SMU v14.0.4.
> >
> > - profile_peak
> > - profile_min_mclk
> > - profile_min_sclk
> > - profile_standard
> >
> > Signed-off-by: Li Ma 
>
> Acked-by: Alex Deucher 
>
> > ---
> >  .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c   | 18
> +++---
> >  1 file changed, 15 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> > b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> > index 5d47d58944f6..8798ebfcea83 100644
> > --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> > +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> > @@ -69,6 +69,9 @@
> >  #define SMU_14_0_0_UMD_PSTATE_SOCCLK   678
> >  #define SMU_14_0_0_UMD_PSTATE_FCLK 1800
> >
> > +#define SMU_14_0_4_UMD_PSTATE_GFXCLK   938
> > +#define SMU_14_0_4_UMD_PSTATE_SOCCLK   938
> > +
> >  #define FEATURE_MASK(feature) (1ULL << feature)  #define
> > SMC_DPM_FEATURE ( \
> > FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ @@ -1296,19
> +1299,28 @@
> > static int smu_v14_0_common_get_dpm_profile_freq(struct smu_context
> *smu,
> > switch (clk_type) {
> > case SMU_GFXCLK:
> > case SMU_SCLK:
> > -   clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
> > +   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) ==
> IP_VERSION(14, 0, 4))
> > +   clk_limit = SMU_14_0_4_UMD_PSTATE_GFXCLK;
> > +   else
> > +   clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
> > if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
> >
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL,
> &clk_limit);
> > else if (level ==
> AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK)
> >
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &clk_limit,
> NULL);
> > break;
> > case SMU_SOCCLK:
> > -   clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
> > +   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) ==
> IP_VERSION(14, 0, 4))
> > +   clk_limit = SMU_14_0_4_UMD_PSTATE_SOCCLK;
> > +   else
> > +   clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
> > if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
> >
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL,
> &clk_limit);
> > break;
> > case SMU_FCLK:
> > -   clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
> > +   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) ==
> IP_VERSION(14, 0, 4))
> > +
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL,
> &clk_limit);
> > +   else
> > +   clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
> > if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
> >
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL,
> &clk_limit);
> > else if (level ==
> > AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK)
> > --
> > 2.25.1
> >


RE: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Zhu, Jiadong
[AMD Official Use Only - AMD Internal Distribution Only]

> -Original Message-
> From: Christian König 
> Sent: Wednesday, July 10, 2024 8:46 PM
> To: Zhu, Jiadong ; amd-gfx@lists.freedesktop.org;
> Deucher, Alexander 
> Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the
> right place
>
> Am 10.07.24 um 12:15 schrieb Zhu, Jiadong:
> > [AMD Official Use Only - AMD Internal Distribution Only]
> >
> >> -Original Message-
> >> From: Christian König 
> >> Sent: Wednesday, July 10, 2024 5:27 PM
> >> To: Zhu, Jiadong ;
> >> amd-gfx@lists.freedesktop.org; Deucher, Alexander
> >> 
> >> Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in
> >> the right place
> >>
> >> Am 10.07.24 um 09:54 schrieb Zhu, Jiadong:
> >>> [AMD Official Use Only - AMD Internal Distribution Only]
> >>>
>  -Original Message-
>  From: Christian König 
>  Sent: Wednesday, July 10, 2024 3:17 PM
>  To: Zhu, Jiadong ; amd-
> >> g...@lists.freedesktop.org
>  Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in
>  the right place
> 
>  Am 10.07.24 um 02:31 schrieb jiadong@amd.com:
> > From: Jiadong Zhu 
> >
> > The job's embedded fence is dma_fence which shall not be
> conversed
> > to amdgpu_fence.
>  Good catch.
> 
> > The start timestamp shall be saved on job for hw_fence.
>  But NAK to that approach. Why do we need the start time here in the
>  first place?
> 
>  Regards,
>  Christian.
> 
> >>> The start timestamp is used for ring mux to check if the fences are
> >> unsignaled for a period of time under mcbp scenarios (by calling
> >> amdgpu_fence_last_unsignaled_time_us).
> >>
> >> I can't find a reason for doing that in the first place. What is the
> >> background of this?
> >>
> >> Regards,
> >> Christian.
> >>
> > It is about os triggered mcbp on gfx9. When we are using software ring and
> ring mux on gfx9,  the ring mux checks the fence unsignaled time of the low
> priority context while high priority job comes. If the time duration exceeds a
> certain time, mux will trigger mcbp.
> > we could add adev->gfx.mcbp check when set start_timestamp for those
> fences.
>
> So you basically want to guarantee some forward progress?
this patch is to fix the memory overlap on job->hw_fence.  For the other part 
we leave it as it was.

> While this is nice to have I don't think we need that in the first place.
>
> I mean when I have two hardware queues the high priority one would starve
> the low priority one as well.
HWS has two levels to handle queue priority:  for priority mode, high priority 
queue will preempt low priority queue as long as it has some work. For quantum 
mode, all the queues are in the same priority, the queue would be preempted 
when it uses up its time slice.
The hardware team suggested OS to use quantum mode as it will not starve low 
priority queue. Our implementation partially referred to that design.

Thanks,
Jiadong

> Regards,
> Christian.
>
> >
> > Thanks,
> > Jiadong
> >
> >>> Thanks,
> >>> Jiadong
> > v2: optimize get_fence_start_time.
> > Signed-off-by: Jiadong Zhu 
> > ---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 31
>  ---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
> > 2 files changed, 31 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > index 2f24a6aa13bf..72bb007e48c8 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > @@ -88,6 +88,31 @@ static inline struct amdgpu_fence
>  *to_amdgpu_fence(struct dma_fence *f)
> >   return NULL;
> > }
> >
> > +static inline void set_fence_start_time(struct dma_fence *f,
> > +ktime_t
> > +start_timestamp) {
> > +   if (f->ops == &amdgpu_fence_ops) {
> > +   struct amdgpu_fence *__f = container_of(f, struct
>  amdgpu_fence,
> > +base);
> > +
> > +   __f->start_timestamp = start_timestamp;
> > +   } else if (f->ops == &amdgpu_job_fence_ops) {
> > +   struct amdgpu_job *job = container_of(f, struct
> > +amdgpu_job, hw_fence);
> > +
> > +   job->start_timestamp = start_timestamp;
> > +   }
> > +}
> > +
> > +static inline ktime_t get_fence_start_time(struct dma_fence *f) {
> > +   if (unlikely(f->ops == &amdgpu_fence_ops)) {
> > +   struct amdgpu_fence *__f = container_of(f, struct
>  amdgpu_fence,
> > +base);
> > +
> > +   return __f->start_timestamp;
> > +   }
> > +   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
> > +hw_fence);
> > +
> > +   return job->start_timestamp;
> > +}
> > +
> > /**
> >  * amdgpu_fence_write - write a fence value
> >>

Re: va range based memory management discussion (was: 回复:回复:Re:Proposal to add CRIU support to DRM render nodes)

2024-07-10 Thread Felix Kuehling

On 2024-07-09 22:38, 周春明(日月) wrote:







--
发件人:Felix Kuehling 
发送时间:2024年7月10日(星期三) 01:07
收件人:周春明(日月) ; Tvrtko Ursulin 
; dri-de...@lists.freedesktop.org 
; amd-gfx@lists.freedesktop.org 
; Dave Airlie ; 
Daniel Vetter ; criu 
抄 送:"Errabolu, Ramesh" ; "Christian König" 


主 题:Re: 回复:Re:Proposal to add CRIU support to DRM render nodes



On 2024-07-09 5:30, 周春明(日月) wrote:
>
>
>
>
>
>
> --
> 发件人:Felix Kuehling 
> 发送时间:2024年7月9日(星期二) 06:40
> 收件人:周春明(日月) ; Tvrtko Ursulin 
; dri-de...@lists.freedesktop.org 
; amd-gfx@lists.freedesktop.org 
; Dave Airlie ; 
Daniel Vetter ; criu 
> 抄 送:"Errabolu, Ramesh" ; "Christian König" 


> 主 题:Re: Re:Proposal to add CRIU support to DRM render nodes
>
>
> On 2024-07-08 2:51, 周春明(日月) wrote:
>>
>>> Hi Felix,
>>>
>>> When I learn CRIU you introduced in 
https://github.com/checkpoint-restore/criu/tree/criu-dev/plugins/amdgpu 
 
> 
 
> 
> 
>> 
, there is a sentence
>>> "ROCm manages memory in the form of buffer objects (BOs). We are 
also working on a new memory management API that will be based on 
virtual address ranges...",
>>> Out of curious, how about "new memory management based on virtual 
address ranges"? Any introduction for that?

>>
>>>Hi David,
>>
>>>This refers to the SVM API that has been in the upstream driver for 
a while now: 
https://elixir.bootlin.com/linux/v6.9.8/source/include/uapi/linux/kfd_ioctl.h#L732 
 
>

>>
>> [David] Can all ROCm runtime memory management switch to use svm 
apis? No need BOs any more?


>I had thought about that when I started working on SVM years ago. But 
I came to the conclusion that we need to use BOs for VRAM to support 
DMABuf exports and imports to support P2P and IPC features.


[David] OK, I guessed you would say DMABuf and IPC factors, if we 
don't use dmabuf (as you know, dmabuf isn't popular in compute area) 
and implement a new ipc based on va ranges, is that possible to using 
svm api to cover all ROCm memory management?

When I tried memory pool used by cuda graph, seems that's OK.


DMABuf and IPC are important for collective communications libraries 
used by distributed applications. You could get away without it when 
you're running a single-process application on a single machine. But 
changing all memory allocations to SVM would probably cause some 
performance regressions, because our BO allocators and memory mapping 
functions are simpler and easier to optimize than for unified memory.


That leaves the question, what's the expected benefit or a compelling 
reason for making such an invasive change?


Regards,
  Felix




Thanks,
-David

>Regards,
>  Felix


>
> Thanks,
> -David
>
> Regards,
>   Felix
>
>
>>
>> Thanks,
>> -David
>>
>> --
>>     发件人:Felix Kuehling 
>>     发送时间:2024年5月3日(星期五) 22:44
>>     收件人:Tvrtko Ursulin ; 
dri-de...@lists.freedesktop.org ; 
amd-gfx@lists.freedesktop.org ; Dave 
Airlie ; Daniel Vetter ; criu 

>>     抄 送:"Errabolu, Ramesh" ; "Christian 
König" 

>>     主 题:Re: Proposal to add CRIU support to DRM render nodes
>>
>>
>>
>>     On 2024-04-16 10:04, Tvrtko Ursulin wrote:
>>     >
>>     > On 01/04/2024 18:58, Felix Kuehling wrote:
>>     >>
>>     >> On 2024-04-01 12:56, Tvrtko Ursulin wrote:
>>     >>>
>>     >>> On 01/04/2024 17:37, Felix Kuehling wrote:
>>      On 2024-04-01 11:09, Tvrtko Ursulin wrote:
>>     >
>>     > On 28/03/2024 20:42, Felix Kuehling wrote:
>>     >>
>>     >> On 2024-03-28 12:03, Tvrtko Ursulin wrote:
>>     >>>
>>     >>> Hi Felix,
>>     >>>
>>     >>> I had one more thought while browsing around the amdgpu 
CRIU plugin. It appears it relies on the KFD support being compiled in 
and /dev/kfd present, correct? AFAICT at least, it relies on that to 
figure out the amdgpu DRM node.

>>     >>>
>>     >>> In would be probably good to consider designing things 
without that dependency. So that checkpointing an application which 
does not use /dev/kfd is possible. Or if the kernel does not even have 
the KFD support compiled in.

>>     >>
>>     >> Yeah, if we want to support graphics apps that don't use 
KFD, we should definitely do that. Currently we get a lot of topology 
information from KFD, not even from the /dev/kfd 

Re: [PATCH 2/2] drm/amd/display: use drm_crtc_set_vblank_offdelay()

2024-07-10 Thread Hamza Mahfooz

On 7/10/24 04:43, Daniel Vetter wrote:

On Tue, Jul 09, 2024 at 10:02:08AM -0400, Hamza Mahfooz wrote:

On 7/9/24 06:09, Daniel Vetter wrote:

On Tue, Jul 09, 2024 at 11:32:11AM +0200, Daniel Vetter wrote:

On Mon, Jul 08, 2024 at 04:29:07PM -0400, Hamza Mahfooz wrote:

Hook up drm_crtc_set_vblank_offdelay() in amdgpu_dm, so that we can
enable PSR more quickly for displays that support it.

Signed-off-by: Hamza Mahfooz 
---
   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 ++-
   1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index fdbc9b57a23d..ee6c31e9d3c4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8231,7 +8231,7 @@ static int amdgpu_dm_encoder_init(struct drm_device *dev,
   static void manage_dm_interrupts(struct amdgpu_device *adev,
 struct amdgpu_crtc *acrtc,
-bool enable)
+struct dm_crtc_state *acrtc_state)
   {
/*
 * We have no guarantee that the frontend index maps to the same
@@ -8239,12 +8239,25 @@ static void manage_dm_interrupts(struct amdgpu_device 
*adev,
 *
 * TODO: Use a different interrupt or check DC itself for the mapping.
 */
-   int irq_type =
-   amdgpu_display_crtc_idx_to_irq_type(
-   adev,
-   acrtc->crtc_id);
+   int irq_type = amdgpu_display_crtc_idx_to_irq_type(adev,
+  acrtc->crtc_id);
+   struct dc_crtc_timing *timing;
+   int offdelay;
+
+   if (acrtc_state) {
+   timing = &acrtc_state->stream->timing;
+
+   /* at least 2 frames */
+   offdelay = 2000 / div64_u64(div64_u64((timing->pix_clk_100hz *
+  (uint64_t)100),
+ timing->v_total),
+   timing->h_total) + 1;


Yeah, _especially_ when you have a this short timeout your really have to
instead fix the vblank driver code properly so you can enable
vblank_disable_immediate. This is just cheating :-)


Michel mentioned on irc that DC had immediate vblank disabling, but this
was reverted with f64e6e0b6afe ("Revert "drm/amdgpu/display: set
vblank_disable_immediate for DC"").

I haven't looked at the details of the bug report, but stuttering is
exactly what happens when the driver's vblank code has these races. Going
for a very low timeout instead of zero just means it's a bit harder to hit
the issue, and much, much harder to debug properly.

So yeah even more reasons to look at the underlying root-cause here I
think.
-Sima


The issue is that DMUB (display firmware) isn't able to keep up with all of
the requests that the driver is making. The issue is fairly difficult to
reproduce (I've only seen it once after letting the system run with a
program that would engage PSR every so often, after several hours).
It is also worth noting that we have the same 2 idle frame wait on the
windows
driver, for the same reasons. So, in all likelihood if it is your opinion
that
the series should be NAKed, we will probably have to move the wait into the
driver as a workaround.


Well that's an entirely different reason, and needs to be recorded in the
commit log that disabling/enabling vblank is too expensive and why. Also
would be good to record that windows does the same.


Point taken.



I'm also not entirely sure this is a good interface, so some
thoughts/question:

- is the issue only with psr, meaning that if we switch the panel to a
   different crtc, do we need to update the off delay.


I can't say definitively, but all of the public reports (that I've seen)
and my local repro are PSR related.



- there's still the question of why vblank_immediate_disable resulted in
   stuttering, is that the same bug? I think for consistency it'd be best
   if we enable immediate vblank disabling everywhere (for maximum
   testing), and then apply the 2 frame delay workaround only where needed
   explicitly. Otherwise if there's other issues than DMUB being slow, they
   might be mostly hidden and become really hard to track down when they
   show up.


Ya, I believe they are all DMUB related since the stuttering issues are
accompanied by the following dmesg log entry:

[drm:dc_dmub_srv_wait_idle [amdgpu]] *ERROR* Error waiting for DMUB 
idle: status=3


(which is pretty much an unspecified firmware timeout)

Also, setting vblank_immediate_disable unconditionally for amdgpu, while 
only
enabling the delay for cases that we know that we need it seems 
reasonable to me.




- I think an interface to set the right values in lockstep with the vblank
   on/off state would be best, so maybe a special drm_c

Re: [PATCH v4 0/2] Add support for 'power saving policy' property

2024-07-10 Thread Hamza Mahfooz

On 7/3/24 01:17, Mario Limonciello wrote:

During the Display Next hackfest 2024 one of the topics discussed
was the need for compositor to be able to relay intention to drivers
that color fidelity is preferred over power savings.

To accomplish this a new optional DRM property is being introduced called
"power saving policy".  This property is a bit mask that can be configured
with requests of "Require color accuracy" or "Require low latency"
that can be configured by the compositor.

When a driver advertises support for this property and the compositor
sets it to "Require color accuracy" then the driver will disable any power
saving features that can compromise color fidelity.

In practice the main feature this currently applies to is the
"Adaptive Backlight Modulation" feature within AMD DCN on eDP panels.

When the compositor has marked the property  "Require color accuracy" then
this feature will be disabled and any userspace that tries to turn it on
will get an -EBUSY return code.

Compositors can also request that low latency is critical which in
practice should cause PSR and PSR2 to be disabled.

When the compositor has restored the value back to no requirements then
the previous value that would have been programmed will be restored.


Applied, thanks!



v3->v4:
  * Fixup for Xaver's reported issue
v2->v3:
  * Updates from Leo's comments (see individual patches)

Mario Limonciello (2):
   drm: Introduce 'power saving policy' drm property
   drm/amd: Add power_saving_policy drm property to eDP connectors

  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  4 ++
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 +--
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
  drivers/gpu/drm/drm_connector.c   | 48 ++
  include/drm/drm_connector.h   |  2 +
  include/drm/drm_mode_config.h |  5 ++
  include/uapi/drm/drm_mode.h   |  7 +++
  7 files changed, 113 insertions(+), 5 deletions(-)


--
Hamza



[PATCH 2/2] drm/amdgpu/vcn: not pause dpg for unified queue

2024-07-10 Thread boyuan.zhang
From: Boyuan Zhang 

For unified queue, DPG pause for encoding is done inside VCN firmware,
so there is no need to pause dpg based on ring type in kernel.

For VCN3 and below, pausing DPG for encoding in kernel is still needed.

v2: add more comments
v3: update commit message

Signed-off-by: Boyuan Zhang 
Acked-by: Alex Deucher 
Reviewed-by: Ruijing Dong 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index f59e81be885d..00f3ac5f4572 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -412,7 +412,9 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct 
*work)
for (i = 0; i < adev->vcn.num_enc_rings; ++i)
fence[j] += 
amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
 
-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be 
handled by FW */
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;
 
if (fence[j] ||
@@ -458,7 +460,9 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
   AMD_PG_STATE_UNGATE);
 
-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled 
by FW */
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;
 
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
@@ -484,8 +488,12 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
 
 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
 {
+   struct amdgpu_device *adev = ring->adev;
+
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled 
by FW */
if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
-   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
+   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
+   !adev->vcn.using_unified_queue)

atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
 
atomic_dec(&ring->adev->vcn.total_submission_cnt);
-- 
2.34.1



[PATCH 1/2] drm/amdgpu/vcn: identify unified queue in sw init

2024-07-10 Thread boyuan.zhang
From: Boyuan Zhang 

Determine whether VCN using unified queue in sw_init, instead of calling
functions later on.

v2: fix coding style

Signed-off-by: Boyuan Zhang 
Acked-by: Alex Deucher 
Reviewed-by: Ruijing Dong 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 39 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h |  1 +
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index dad5f9722e14..f59e81be885d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -139,6 +139,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
}
}
 
+   /* from vcn4 and above, only unified queue is used */
+   adev->vcn.using_unified_queue =
+   amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0);
+
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
 
@@ -266,18 +270,6 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
return 0;
 }
 
-/* from vcn4 and above, only unified queue is used */
-static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)
-{
-   struct amdgpu_device *adev = ring->adev;
-   bool ret = false;
-
-   if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0))
-   ret = true;
-
-   return ret;
-}
-
 bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type 
type, uint32_t vcn_instance)
 {
bool ret = false;
@@ -747,12 +739,11 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
struct amdgpu_job *job;
struct amdgpu_ib *ib;
uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
uint32_t *ib_checksum;
uint32_t ib_pack_in_dw;
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -765,7 +756,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
ib->length_dw = 0;
 
/* single queue headers */
-   if (sq) {
+   if (adev->vcn.using_unified_queue) {
ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / 
sizeof(uint32_t)
+ 4 + 2; /* engine info + 
decoding ib in dw */
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 
ib_pack_in_dw, false);
@@ -784,7 +775,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 
ib_pack_in_dw);
 
r = amdgpu_job_submit_direct(job, ring, &f);
@@ -874,15 +865,15 @@ static int amdgpu_vcn_enc_get_create_msg(struct 
amdgpu_ring *ring, uint32_t hand
 struct dma_fence **fence)
 {
unsigned int ib_size_dw = 16;
+   struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct dma_fence *f = NULL;
uint32_t *ib_checksum = NULL;
uint64_t addr;
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -896,7 +887,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring 
*ring, uint32_t hand
 
ib->length_dw = 0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
 
ib->ptr[ib->length_dw++] = 0x0018;
@@ -918,7 +909,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring 
*ring, uint32_t hand
for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
 
r = amdgpu_job_submit_direct(job, ring, &f);
@@ -941,15 +932,15 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct 
amdgpu_ring *ring, uint32_t han
  struct dma_fence **fence)
 {
unsigned int ib_size_dw = 16;
+   struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct dma_fence *f = NULL;
uint32_t *ib_checksum = NULL;
uint64_t addr;
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -963,7 +954

Re: [PATCH v4 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors

2024-07-10 Thread Leo Li




On 2024-07-03 01:17, Mario Limonciello wrote:

When the `power_saving_policy` property is set to bit mask
"Require color accuracy" ABM should be disabled immediately and
any requests by sysfs to update will return an -EBUSY error.

When the `power_saving_policy` property is set to bit mask
"Require low latency" PSR should be disabled.

When the property is restored to an empty bit mask ABM and PSR
can be enabled again.

Signed-off-by: Mario Limonciello 


Reviewed-by: Leo Li 

Thanks!


---
v3->v4:
  * Fix enabling again after disable (Xaver)
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  4 ++
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 +--
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +
  3 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 3ecc7ef95172..cfb5220cf182 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1350,6 +1350,10 @@ int amdgpu_display_modeset_create_props(struct 
amdgpu_device *adev)
 "dither",
 amdgpu_dither_enum_list, sz);
  
+	if (adev->dc_enabled)

+   drm_mode_create_power_saving_policy_property(adev_to_drm(adev),
+
DRM_MODE_POWER_SAVING_POLICY_ALL);
+
return 0;
  }
  
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index f866a02f4f48..34da987350f5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6417,6 +6417,13 @@ int amdgpu_dm_connector_atomic_set_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
dm_new_state->underscan_enable = val;
ret = 0;
+   } else if (property == dev->mode_config.power_saving_policy) {
+   dm_new_state->abm_forbidden = val & 
DRM_MODE_REQUIRE_COLOR_ACCURACY;
+   dm_new_state->abm_level = (dm_new_state->abm_forbidden || 
!dm_old_state->abm_level) ?
+   ABM_LEVEL_IMMEDIATE_DISABLE :
+   dm_old_state->abm_level;
+   dm_new_state->psr_forbidden = val & 
DRM_MODE_REQUIRE_LOW_LATENCY;
+   ret = 0;
}
  
  	return ret;

@@ -6459,6 +6466,13 @@ int amdgpu_dm_connector_atomic_get_property(struct 
drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) {
*val = dm_state->underscan_enable;
ret = 0;
+   } else if (property == dev->mode_config.power_saving_policy) {
+   *val = 0;
+   if (dm_state->psr_forbidden)
+   *val |= DRM_MODE_REQUIRE_LOW_LATENCY;
+   if (dm_state->abm_forbidden)
+   *val |= DRM_MODE_REQUIRE_COLOR_ACCURACY;
+   ret = 0;
}
  
  	return ret;

@@ -6485,9 +6499,12 @@ static ssize_t panel_power_savings_show(struct device 
*device,
u8 val;
  
  	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);

-   val = to_dm_connector_state(connector->state)->abm_level ==
-   ABM_LEVEL_IMMEDIATE_DISABLE ? 0 :
-   to_dm_connector_state(connector->state)->abm_level;
+   if (to_dm_connector_state(connector->state)->abm_forbidden)
+   val = 0;
+   else
+   val = to_dm_connector_state(connector->state)->abm_level ==
+   ABM_LEVEL_IMMEDIATE_DISABLE ? 0 :
+   to_dm_connector_state(connector->state)->abm_level;
drm_modeset_unlock(&dev->mode_config.connection_mutex);
  
  	return sysfs_emit(buf, "%u\n", val);

@@ -6511,10 +6528,16 @@ static ssize_t panel_power_savings_store(struct device 
*device,
return -EINVAL;
  
  	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);

-   to_dm_connector_state(connector->state)->abm_level = val ?:
-   ABM_LEVEL_IMMEDIATE_DISABLE;
+   if (to_dm_connector_state(connector->state)->abm_forbidden)
+   ret = -EBUSY;
+   else
+   to_dm_connector_state(connector->state)->abm_level = val ?:
+   ABM_LEVEL_IMMEDIATE_DISABLE;
drm_modeset_unlock(&dev->mode_config.connection_mutex);
  
+	if (ret)

+   return ret;
+
drm_kms_helper_hotplug_event(dev);
  
  	return count;

@@ -7685,6 +7708,13 @@ void amdgpu_dm_connector_init_helper(struct 
amdgpu_display_manager *dm,
aconnector->base.state->max_bpc = 16;
aconnector->base.state->max_requested_bpc = 
aconnector->base.state->max_bpc;
  
+	if (connector_type == DRM_MODE_CONNECTOR_eDP &&

+   (dc_is_dmcu_initialized(adev->dm.dc) ||
+   

RE: [PATCH 2/2] drm/amdgpu/vcn: not pause dpg for unified queue

2024-07-10 Thread Dong, Ruijing
[AMD Official Use Only - AMD Internal Distribution Only]

Just change the commit messages from "For previous generations" to " For VCN3 
and before" to be more specific.

With that all patches are
Reviewed-by: Ruijing Dong 

Thanks,
Ruijing

-Original Message-
From: amd-gfx  On Behalf Of 
boyuan.zh...@amd.com
Sent: Wednesday, July 10, 2024 4:30 PM
To: amd-gfx@lists.freedesktop.org
Cc: Zhang, Boyuan ; Deucher, Alexander 

Subject: [PATCH 2/2] drm/amdgpu/vcn: not pause dpg for unified queue

From: Boyuan Zhang 

For unified queue, DPG pause for encoding is done inside VCN firmware, so there 
is no need to pause dpg based on ring type in kernel.

For previous generations, pausing DPG for encoding in kernel is still needed.

v2: add more comments

Signed-off-by: Boyuan Zhang 
Acked-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index f59e81be885d..00f3ac5f4572 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -412,7 +412,9 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct 
*work)
for (i = 0; i < adev->vcn.num_enc_rings; ++i)
fence[j] += 
amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);

-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be 
handled by FW */
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;

if (fence[j] ||
@@ -458,7 +460,9 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
   AMD_PG_STATE_UNGATE);

-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled 
by FW */
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;

if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) { @@ -484,8 
+488,12 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)

 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)  {
+   struct amdgpu_device *adev = ring->adev;
+
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be
+handled by FW */
if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
-   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
+   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
+   !adev->vcn.using_unified_queue)

atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);

atomic_dec(&ring->adev->vcn.total_submission_cnt);
--
2.34.1



[PATCH 1/2] drm/amdgpu/vcn: identify unified queue in sw init

2024-07-10 Thread boyuan.zhang
From: Boyuan Zhang 

Determine whether VCN using unified queue in sw_init, instead of calling
functions later on.

v2: fix coding style

Signed-off-by: Boyuan Zhang 
Acked-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 39 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h |  1 +
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index dad5f9722e14..f59e81be885d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -139,6 +139,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
}
}
 
+   /* from vcn4 and above, only unified queue is used */
+   adev->vcn.using_unified_queue =
+   amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0);
+
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
 
@@ -266,18 +270,6 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
return 0;
 }
 
-/* from vcn4 and above, only unified queue is used */
-static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)
-{
-   struct amdgpu_device *adev = ring->adev;
-   bool ret = false;
-
-   if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0))
-   ret = true;
-
-   return ret;
-}
-
 bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type 
type, uint32_t vcn_instance)
 {
bool ret = false;
@@ -747,12 +739,11 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
struct amdgpu_job *job;
struct amdgpu_ib *ib;
uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
uint32_t *ib_checksum;
uint32_t ib_pack_in_dw;
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -765,7 +756,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
ib->length_dw = 0;
 
/* single queue headers */
-   if (sq) {
+   if (adev->vcn.using_unified_queue) {
ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / 
sizeof(uint32_t)
+ 4 + 2; /* engine info + 
decoding ib in dw */
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 
ib_pack_in_dw, false);
@@ -784,7 +775,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 
ib_pack_in_dw);
 
r = amdgpu_job_submit_direct(job, ring, &f);
@@ -874,15 +865,15 @@ static int amdgpu_vcn_enc_get_create_msg(struct 
amdgpu_ring *ring, uint32_t hand
 struct dma_fence **fence)
 {
unsigned int ib_size_dw = 16;
+   struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct dma_fence *f = NULL;
uint32_t *ib_checksum = NULL;
uint64_t addr;
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -896,7 +887,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring 
*ring, uint32_t hand
 
ib->length_dw = 0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
 
ib->ptr[ib->length_dw++] = 0x0018;
@@ -918,7 +909,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring 
*ring, uint32_t hand
for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
 
r = amdgpu_job_submit_direct(job, ring, &f);
@@ -941,15 +932,15 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct 
amdgpu_ring *ring, uint32_t han
  struct dma_fence **fence)
 {
unsigned int ib_size_dw = 16;
+   struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct dma_fence *f = NULL;
uint32_t *ib_checksum = NULL;
uint64_t addr;
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -963,7 +954,7 @@ static int amdgpu_vcn

[PATCH 2/2] drm/amdgpu/vcn: not pause dpg for unified queue

2024-07-10 Thread boyuan.zhang
From: Boyuan Zhang 

For unified queue, DPG pause for encoding is done inside VCN firmware,
so there is no need to pause dpg based on ring type in kernel.

For previous generations, pausing DPG for encoding in kernel is still needed.

v2: add more comments

Signed-off-by: Boyuan Zhang 
Acked-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index f59e81be885d..00f3ac5f4572 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -412,7 +412,9 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct 
*work)
for (i = 0; i < adev->vcn.num_enc_rings; ++i)
fence[j] += 
amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
 
-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be 
handled by FW */
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;
 
if (fence[j] ||
@@ -458,7 +460,9 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
   AMD_PG_STATE_UNGATE);
 
-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled 
by FW */
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;
 
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
@@ -484,8 +488,12 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
 
 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
 {
+   struct amdgpu_device *adev = ring->adev;
+
+   /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled 
by FW */
if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
-   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
+   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
+   !adev->vcn.using_unified_queue)

atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
 
atomic_dec(&ring->adev->vcn.total_submission_cnt);
-- 
2.34.1



Re: [PATCH v9 27/52] selftests-dyndbg: check KCONFIG_CONFIG to avoid silly fails

2024-07-10 Thread Helen Koike




On 02/07/2024 18:57, Jim Cromie wrote:

Several tests are dependent upon config choices. Lets avoid failing
where that is noise.

The KCONFIG_CONFIG var exists to convey the config-file around.  If
the var names a file, read it and extract the relevant CONFIG items,
and use them to skip the dependent tests, thus avoiding the fails that
would follow, and the disruption to whatever CI is running these
selftests.

If the envar doesn't name a config-file, ".config" is assumed.

CONFIG_DYNAMIC_DEBUG=y:

basic-tests() and comma-terminator-tests() test for the presence of
the builtin pr_debugs in module/main.c, which I deemed stable and
therefore safe to count.  That said, the test fails if only
CONFIG_DYNAMIC_DEBUG_CORE=y is set.  It could be rewritten to test
against test-dynamic-debug.ko, but that just trades one config
dependence for another.

CONFIG_TEST_DYNAMIC_DEBUG=m

As written, test_percent_splitting() modprobes test_dynamic_debug,
enables several classes, and count them.  It could be re-written to
work for the builtin module also, but builtin test modules are not a
common or desirable build/config.

CONFIG_TEST_DYNAMIC_DEBUG=m && CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m

test_mod_submod() recaps the bug found in DRM-CI where drivers werent


If this fixes any but listed in drm/ci/xfails folder, please update it too.

Regards,
Helen


enabled by drm.debug=.  It modprobes both test_dynamic_debug &
test_dynamic_debug_submod, so it depends on a loadable modules config.

It could be rewritten to work in a builtin parent config; DRM=y is
common enough to be pertinent, but testing that config also wouldn't
really test anything more fully than all-loadable modules, since they
default together.

Signed-off-by: Jim Cromie 

fixup-kconfig
---
  .../dynamic_debug/dyndbg_selftest.sh  | 45 ++-
  1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index fccd2012b548..d09ef26b2308 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -11,6 +11,30 @@ CYAN="\033[0;36m"
  NC="\033[0;0m"
  error_msg=""
  
+[ -e /proc/dynamic_debug/control ] || {

+echo -e "${RED}: this test requires CONFIG_DYNAMIC_DEBUG=y ${NC}"
+exit 0 # nothing to test here, no good reason to fail.
+}
+
+# need info to avoid failures due to untestable configs
+
+[ -f "$KCONFIG_CONFIG" ] || KCONFIG_CONFIG=".config"
+if [ -f "$KCONFIG_CONFIG" ]; then
+echo "# consulting KCONFIG_CONFIG: $KCONFIG_CONFIG"
+grep -q "CONFIG_DYNAMIC_DEBUG=y" $KCONFIG_CONFIG ; LACK_DD_BUILTIN=$?
+grep -q "CONFIG_TEST_DYNAMIC_DEBUG=m" $KCONFIG_CONFIG ; LACK_TMOD=$?
+grep -q "CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m" $KCONFIG_CONFIG ; 
LACK_TMOD_SUBMOD=$?
+if [ $V -eq 1 ]; then
+   echo LACK_DD_BUILTIN: $LACK_DD_BUILTIN
+   echo LACK_TMOD: $LACK_TMOD
+   echo LACK_TMOD_SUBMOD: $LACK_TMOD_SUBMOD
+fi
+else
+LACK_DD_BUILTIN=0
+LACK_TMOD=0
+LACK_TMOD_SUBMOD=0
+fi
+
  function vx () {
  echo $1 > /sys/module/dynamic_debug/parameters/verbose
  }
@@ -192,6 +216,10 @@ function check_err_msg() {
  
  function basic_tests {

  echo -e "${GREEN}# BASIC_TESTS ${NC}"
+if [ $LACK_DD_BUILTIN -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
  ddcmd =_ # zero everything (except class'd sites)
  check_match_ct =p 0
  # there are several main's :-/
@@ -214,6 +242,10 @@ EOF
  
  function comma_terminator_tests {

  echo -e "${GREEN}# COMMA_TERMINATOR_TESTS ${NC}"
+if [ $LACK_DD_BUILTIN -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
  # try combos of spaces & commas
  check_match_ct '\[params\]' 4 -r
  ddcmd module,params,=_# commas as spaces
@@ -226,9 +258,12 @@ function comma_terminator_tests {
  ddcmd =_
  }
  
-

  function test_percent_splitting {
  echo -e "${GREEN}# TEST_PERCENT_SPLITTING - multi-command splitting on % 
${NC}"
+if [ $LACK_TMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
  ifrmmod test_dynamic_debug_submod
  ifrmmod test_dynamic_debug
  ddcmd =_
@@ -248,6 +283,14 @@ function test_percent_splitting {
  
  function test_mod_submod {

  echo -e "${GREEN}# TEST_MOD_SUBMOD ${NC}"
+if [ $LACK_TMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
+if [ $LACK_TMOD_SUBMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
  ifrmmod test_dynamic_debug_submod
  ifrmmod test_dynamic_debug
  ddcmd =_


Re: [PATCH] drm/amd/display: Allow display DCC for DCN401

2024-07-10 Thread Aurabindo Pillai




On 7/10/24 4:12 PM, Marek Olšák wrote:

Can you also increase KMS_DRIVER_MINOR with a proper comment in
amdgpu_drv.c, which will be used by Mesa to tell whether display DCC
is supported on gfx12?


Sure, will do.

--

Thanks & Regards,
Aurabindo Pillai


Re: [PATCH] drm/amd/display: Allow display DCC for DCN401

2024-07-10 Thread Marek Olšák
Can you also increase KMS_DRIVER_MINOR with a proper comment in
amdgpu_drv.c, which will be used by Mesa to tell whether display DCC
is supported on gfx12?

Thanks,
Marek

On Wed, Jul 10, 2024 at 4:05 PM Aurabindo Pillai
 wrote:
>
>
>
> On 7/10/24 10:49 AM, Marek Olšák wrote:
> > This will enable display DCC for Wayland because Mesa already exposes
> > modifiers with DCC. Has it been tested?
>
> Yes, its working for most resolutions. Investigating issue with certain
> modes.
> >
> > Marek
>
> --
>
> Thanks & Regards,
> Aurabindo Pillai


Re: [PATCH] drm/amd/display: Allow display DCC for DCN401

2024-07-10 Thread Aurabindo Pillai




On 7/10/24 10:49 AM, Marek Olšák wrote:

This will enable display DCC for Wayland because Mesa already exposes
modifiers with DCC. Has it been tested?


Yes, its working for most resolutions. Investigating issue with certain 
modes.


Marek


--

Thanks & Regards,
Aurabindo Pillai


Re: [PATCH 29/50] drm/amd/display: Re-enable panel replay feature

2024-07-10 Thread Leo Li




On 2024-07-10 15:36, Fangzhi Zuo wrote:

From: Tom Chung 

[Why & How]
Fixed the replay issues and now re-enable the panel replay feature.

Reported-by: Arthur Borsboom 
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3344

Reviewed-by: Mario Limonciello 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Tom Chung 


Hi Jerry,

Please drop this patch as there's a known PSR SU regression caused by a patch 
that originally fixed the aforementioned replay issue.


Thanks,
Leo


---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ---
  1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index fe5a96e5c70a..864a66406f8a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4836,18 +4836,14 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
/* Determine whether to enable Replay support by default. */
if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
-/*
- * Disabled by default due to 
https://gitlab.freedesktop.org/drm/amd/-/issues/3344
- * case IP_VERSION(3, 1, 4):
- * case IP_VERSION(3, 1, 5):
- * case IP_VERSION(3, 1, 6):
- * case IP_VERSION(3, 2, 0):
- * case IP_VERSION(3, 2, 1):
- * case IP_VERSION(3, 5, 0):
- * case IP_VERSION(3, 5, 1):
- * replay_feature_enabled = true;
- * break;
- */
+   case IP_VERSION(3, 1, 4):
+   case IP_VERSION(3, 2, 0):
+   case IP_VERSION(3, 2, 1):
+   case IP_VERSION(3, 5, 0):
+   case IP_VERSION(3, 5, 1):
+   replay_feature_enabled = true;
+   break;
+
default:
replay_feature_enabled = amdgpu_dc_feature_mask & 
DC_REPLAY_MASK;
break;


[PATCH 50/50] drm/amd/display: 3.2.292

2024-07-10 Thread Fangzhi Zuo
From: Aric Cyr 

* FW Release 0.0.225.0
* DML2 fixes
* Re-enable panel replay feature
* Allow display DCC for DCN401
* Refactor DWB, OPP, MPC, MMHUBBUB
* Fix dscclk Programming issue on DCN401

Acked-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Aric Cyr 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 9d4b821ab219..036b23a6e324 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -55,7 +55,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.291"
+#define DC_VER "3.2.292"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 48/50] drm/amd/display: improve logic for addition of modifers

2024-07-10 Thread Fangzhi Zuo
From: Aurabindo Pillai 

Use an extra for loop to reduce duplicate code for adding modifiers

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Aurabindo Pillai 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 36 +--
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index dde4f1dda2e2..dc16d82aced4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -695,28 +695,26 @@ static void amdgpu_dm_plane_add_gfx12_modifiers(struct 
amdgpu_device *adev,
uint64_t mod_256b = ver | AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_TILE_GFX12_256B_2D);
uint64_t dcc = ver | AMD_FMT_MOD_SET(DCC, 1);
uint8_t max_comp_block[] = {1, 0};
-   uint64_t max_comp_block_mod[2] = {0};
-   uint8_t i = 0;
+   uint64_t max_comp_block_mod[ARRAY_SIZE(max_comp_block)] = {0};
+   uint8_t i = 0, j = 0;
+   uint64_t gfx12_modifiers[] = {mod_256k, mod_64k, mod_4k, mod_256b, 
DRM_FORMAT_MOD_LINEAR};
 
-   /* With DCC: Best choice should be kept first. Hence, add all 256k 
modifiers of different
-* max compressed blocks first and then move on to the next smaller 
sized layouts */
for (i = 0; i < 2; i++)
max_comp_block_mod[i] = 
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_comp_block[i]);
-   for (i = 0; i < 2; i++)
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_256k);
-   for (i = 0; i < 2; i++)
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_64k);
-   for (i = 0; i < 2; i++)
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_4k);
-   for (i = 0; i < 2; i++)
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_256b);
-
-   /* Without DCC: */
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_256k);
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_64k);
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_4k);
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_256b);
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, 
DRM_FORMAT_MOD_LINEAR);
+
+   /* With DCC: Best choice should be kept first. Hence, add all 256k 
modifiers of different
+* max compressed blocks first and then move on to the next smaller 
sized layouts.
+* Do not add the linear modifier here, and hence the condition of 
size-1 for the loop
+*/
+   for (j = 0; j < ARRAY_SIZE(gfx12_modifiers) - 1; j++)
+   for (i = 0; i < ARRAY_SIZE(max_comp_block); i++)
+   amdgpu_dm_plane_add_modifier(mods, size, capacity,
+ver | dcc | 
max_comp_block_mod[i] | gfx12_modifiers[j]);
+
+   /* Without DCC. Add all modifiers including linear at the end */
+   for (i = 0; i < ARRAY_SIZE(gfx12_modifiers); i++)
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, 
gfx12_modifiers[i]);
+
 }
 
 static int amdgpu_dm_plane_get_plane_modifiers(struct amdgpu_device *adev, 
unsigned int plane_type, uint64_t **mods)
-- 
2.34.1



[PATCH 49/50] drm/amd/display: Remove unused dml2_core_ip_params struct

2024-07-10 Thread Fangzhi Zuo
From: Rodrigo Siqueira 

Acked-by: Jerry Zuo 
Signed-off-by: Rodrigo Siqueira 
---
 .../dml2/dml21/src/dml2_core/dml2_core_dcn4.c | 78 ---
 1 file changed, 78 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
index 8c803b12404b..f5c6cd5cf5e9 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c
@@ -77,84 +77,6 @@ struct dml2_core_ip_params core_dcn4_ip_caps_base = {
.subvp_swath_height_margin_lines = 16,
 };
 
-struct dml2_core_ip_params core_dcn4sw_ip_caps_base = {
-   .vblank_nom_default_us = 668,
-   .remote_iommu_outstanding_translations = 256,
-   .rob_buffer_size_kbytes = 192,
-   .config_return_buffer_size_in_kbytes = 1280,
-   .config_return_buffer_segment_size_in_kbytes = 64,
-   .compressed_buffer_segment_size_in_kbytes = 64,
-   .dpte_buffer_size_in_pte_reqs_luma = 68,
-   .dpte_buffer_size_in_pte_reqs_chroma = 36,
-   .pixel_chunk_size_kbytes = 8,
-   .alpha_pixel_chunk_size_kbytes = 4,
-   .min_pixel_chunk_size_bytes = 1024,
-   .writeback_chunk_size_kbytes = 8,
-   .line_buffer_size_bits = 1171920,
-   .max_line_buffer_lines = 32,
-   .writeback_interface_buffer_size_kbytes = 90,
-
-   //Number of pipes after DCN Pipe harvesting
-   .max_num_dpp = 4,
-   .max_num_otg = 4,
-   .max_num_wb = 1,
-   .max_dchub_pscl_bw_pix_per_clk = 4,
-   .max_pscl_lb_bw_pix_per_clk = 2,
-   .max_lb_vscl_bw_pix_per_clk = 4,
-   .max_vscl_hscl_bw_pix_per_clk = 4,
-   .max_hscl_ratio = 6,
-   .max_vscl_ratio = 6,
-   .max_hscl_taps = 8,
-   .max_vscl_taps = 8,
-   .dispclk_ramp_margin_percent = 1,
-   .dppclk_delay_subtotal = 47,
-   .dppclk_delay_scl = 50,
-   .dppclk_delay_scl_lb_only = 16,
-   .dppclk_delay_cnvc_formatter = 28,
-   .dppclk_delay_cnvc_cursor = 6,
-   .cursor_buffer_size = 24,
-   .cursor_chunk_size = 2,
-   .dispclk_delay_subtotal = 125,
-   .max_inter_dcn_tile_repeaters = 8,
-   .writeback_max_hscl_ratio = 1,
-   .writeback_max_vscl_ratio = 1,
-   .writeback_min_hscl_ratio = 1,
-   .writeback_min_vscl_ratio = 1,
-   .writeback_max_hscl_taps = 1,
-   .writeback_max_vscl_taps = 1,
-   .writeback_line_buffer_buffer_size = 0,
-   .num_dsc = 4,
-   .maximum_dsc_bits_per_component = 12,
-   .maximum_pixels_per_line_per_dsc_unit = 5760,
-   .dsc422_native_support = true,
-   .dcc_supported = true,
-   .ptoi_supported = false,
-
-   .cursor_64bpp_support = true,
-   .dynamic_metadata_vm_enabled = false,
-
-   .max_num_hdmi_frl_outputs = 1,
-   .max_num_dp2p0_outputs = 4,
-   .max_num_dp2p0_streams = 4,
-   .imall_supported = 1,
-   .max_flip_time_us = 80,
-   .words_per_channel = 16,
-
-   .subvp_fw_processing_delay_us = 15,
-   .subvp_pstate_allow_width_us = 20,
-   .subvp_swath_height_margin_lines = 16,
-
-   .dcn_mrq_present = 1,
-   .zero_size_buffer_entries = 512,
-   .compbuf_reserved_space_zs = 64,
-   .dcc_meta_buffer_size_bytes = 6272,
-   .meta_chunk_size_kbytes = 2,
-   .min_meta_chunk_size_bytes = 256,
-
-   .dchub_arb_to_ret_delay = 102,
-   .hostvm_mode = 1,
-};
-
 static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities 
*ip_caps, const struct dml2_core_ip_params *ip_params)
 {
ip_caps->pipe_count = ip_params->max_num_dpp;
-- 
2.34.1



[PATCH 47/50] drm/amd/display: Allow display DCC for DCN401

2024-07-10 Thread Fangzhi Zuo
From: Aurabindo Pillai 

To enable mesa to use display dcc, DM should expose them in the
supported modifiers. Add the best (most efficient) modifiers first.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Aurabindo Pillai 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 29 ---
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 0320200dae94..dde4f1dda2e2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -689,12 +689,33 @@ static void amdgpu_dm_plane_add_gfx12_modifiers(struct 
amdgpu_device *adev,
  uint64_t **mods, uint64_t *size, uint64_t *capacity)
 {
uint64_t ver = AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE_VERSION, 
AMD_FMT_MOD_TILE_VER_GFX12);
+   uint64_t mod_256k = ver | AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_TILE_GFX12_256K_2D);
+   uint64_t mod_64k = ver | AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_TILE_GFX12_64K_2D);
+   uint64_t mod_4k = ver | AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_TILE_GFX12_4K_2D);
+   uint64_t mod_256b = ver | AMD_FMT_MOD_SET(TILE, 
AMD_FMT_MOD_TILE_GFX12_256B_2D);
+   uint64_t dcc = ver | AMD_FMT_MOD_SET(DCC, 1);
+   uint8_t max_comp_block[] = {1, 0};
+   uint64_t max_comp_block_mod[2] = {0};
+   uint8_t i = 0;
+
+   /* With DCC: Best choice should be kept first. Hence, add all 256k 
modifiers of different
+* max compressed blocks first and then move on to the next smaller 
sized layouts */
+   for (i = 0; i < 2; i++)
+   max_comp_block_mod[i] = 
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_comp_block[i]);
+   for (i = 0; i < 2; i++)
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_256k);
+   for (i = 0; i < 2; i++)
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_64k);
+   for (i = 0; i < 2; i++)
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_4k);
+   for (i = 0; i < 2; i++)
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | dcc | 
max_comp_block_mod[i] | mod_256b);
 
/* Without DCC: */
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_256K_2D));
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_64K_2D));
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_4K_2D));
-   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_256B_2D));
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_256k);
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_64k);
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_4k);
+   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | mod_256b);
amdgpu_dm_plane_add_modifier(mods, size, capacity, 
DRM_FORMAT_MOD_LINEAR);
 }
 
-- 
2.34.1



[PATCH 46/50] drm/amd/display: Remove unnecessary DSC power gating for DCN401

2024-07-10 Thread Fangzhi Zuo
From: Joshua Aberback 

[Why]
In some cases during topology changes, a pipe that was used to drive a
stream being removed can be re-assigned to drive a different stream. In
these cases, DSC power gating is not handled properly, leading to
situations where DSC is being setup while power gated.

[How]
 - remove enable_stream_gating and disable_stream_gating for DCN401

Reviewed-by: Wenjing Liu 
Signed-off-by: Jerry Zuo 
Signed-off-by: Joshua Aberback 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index 6a768702c7bd..1439f07f0b64 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -115,8 +115,6 @@ static const struct hwseq_private_funcs 
dcn401_private_funcs = {
.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap,
.enable_stream_timing = dcn401_enable_stream_timing,
.edp_backlight_control = dce110_edp_backlight_control,
-   .disable_stream_gating = dcn20_disable_stream_gating,
-   .enable_stream_gating = dcn20_enable_stream_gating,
.setup_vupdate_interrupt = dcn20_setup_vupdate_interrupt,
.did_underflow_occur = dcn10_did_underflow_occur,
.init_blank = dcn32_init_blank,
-- 
2.34.1



[PATCH 45/50] drm/amd/display: free bo used for dmub bounding box

2024-07-10 Thread Fangzhi Zuo
From: Aurabindo Pillai 

fix a memleak introduced by not removing the buffer object for use with
early dmub bounding box value storage

Fixes: 25a40071e ("drm/amd/display: Enable copying of bounding box data from 
VBIOS DMUB")

Reviewed-by: Rodrigo Siqueira 
Reviewed-by: Alex Hung 
Signed-off-by: Jerry Zuo 
Signed-off-by: Aurabindo Pillai 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 864a66406f8a..d6be73d74b95 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1740,7 +1740,7 @@ static struct dml2_soc_bb 
*dm_dmub_get_vbios_bounding_box(struct amdgpu_device *
/* Send the chunk */
ret = dm_dmub_send_vbios_gpint_command(adev, send_addrs[i], 
chunk, 3);
if (ret != DMUB_STATUS_OK)
-   /* No need to free bb here since it shall be done 
unconditionally  */
+   /* No need to free bb here since it shall be done in 
dm_sw_fini() */
return NULL;
}
 
@@ -2465,8 +2465,17 @@ static int dm_sw_init(void *handle)
 static int dm_sw_fini(void *handle)
 {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+   struct dal_allocation *da;
+
+   list_for_each_entry(da, &adev->dm.da_list, list) {
+   if (adev->dm.bb_from_dmub == (void *) da->cpu_ptr) {
+   amdgpu_bo_free_kernel(&da->bo, &da->gpu_addr, 
&da->cpu_ptr);
+   list_del(&da->list);
+   kfree(da);
+   break;
+   }
+   }
 
-   kfree(adev->dm.bb_from_dmub);
adev->dm.bb_from_dmub = NULL;
 
kfree(adev->dm.dmub_fb_info);
-- 
2.34.1



[PATCH 43/50] drm/amd/display: Set Cursor Matrix to bypass instead of Input Plane

2024-07-10 Thread Fangzhi Zuo
From: Daniel Sa 

why:
When the cursor disappears/reappears on fullscreen video, there is a
short transitional period where the cursor's color matrix is using the
same format as the video plane. This sets the cursor to the wrong color
momentarily before the UI plane appears, correcting the color.

how:
Instead of defaulting to using the color space from the input plane,
default to bypass mode.

Reviewed-by: Nevenko Stupar 
Signed-off-by: Jerry Zuo 
Signed-off-by: Daniel Sa 
---
 .../drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c  | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c 
b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
index d0f8c9ff5232..92b34fe47f74 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
@@ -246,16 +246,6 @@ void dpp401_set_cursor_matrix(
enum dc_color_space color_space,
struct dc_csc_transform cursor_csc_color_matrix)
 {
-   struct dpp_input_csc_matrix cursor_tbl_entry;
-   unsigned int i;
-
-   if (cursor_csc_color_matrix.enable_adjustment == true) {
-   for (i = 0; i < 12; i++)
-   cursor_tbl_entry.regval[i] = 
cursor_csc_color_matrix.matrix[i];
-
-   cursor_tbl_entry.color_space = color_space;
-   dpp401_program_cursor_csc(dpp_base, color_space, 
&cursor_tbl_entry);
-   } else {
-   dpp401_program_cursor_csc(dpp_base, color_space, NULL);
-   }
+   //Since we don't have cursor matrix information, force bypass mode by 
passing in unknown color space
+   dpp401_program_cursor_csc(dpp_base, COLOR_SPACE_UNKNOWN, NULL);
 }
-- 
2.34.1



[PATCH 44/50] drm/amd/display: Add visual confirm for Idle State

2024-07-10 Thread Fangzhi Zuo
From: Duncan Ma 

[Why]
Visual Confirm would tell us if it ever
entered idle state.

[How]
Add debug option for IPS visual confirm

Reviewed-by: Ovidiu Bunea 
Signed-off-by: Jerry Zuo 
Signed-off-by: Duncan Ma 
---
 drivers/gpu/drm/amd/display/dc/dc.h  | 1 +
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c| 1 +
 drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c | 2 ++
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h  | 4 
 4 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 83fe13f5a367..9d4b821ab219 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1056,6 +1056,7 @@ struct dc_debug_options {
unsigned int force_sharpness;
unsigned int force_lls;
bool notify_dpia_hr_bw;
+   bool enable_ips_visual_confirm;
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c 
b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index ccf153b7a467..0f3d15126a1e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -363,6 +363,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
copy_settings_data->debug.bitfields.visual_confirm  = 
dc->dc->debug.visual_confirm == VISUAL_CONFIRM_PSR;
copy_settings_data->debug.bitfields.use_hw_lock_mgr = 1;
copy_settings_data->debug.bitfields.force_full_frame_update = 0;
+   copy_settings_data->debug.bitfields.enable_ips_visual_confirm = 
dc->dc->debug.enable_ips_visual_confirm;
 
if (psr_context->su_granularity_required == 0)
copy_settings_data->su_y_granularity = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c 
b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
index 2a21bcf5224f..44df9e2351c2 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
@@ -167,6 +167,8 @@ static bool dmub_replay_copy_settings(struct dmub_replay 
*dmub,
copy_settings_data->smu_optimizations_en= 
link->replay_settings.replay_smu_opt_enable;
copy_settings_data->replay_timing_sync_supported = 
link->replay_settings.config.replay_timing_sync_supported;
 
+   copy_settings_data->debug.bitfields.enable_ips_visual_confirm = 
dc->dc->debug.enable_ips_visual_confirm;
+
copy_settings_data->flags.u32All = 0;
copy_settings_data->flags.bitfields.fec_enable_status = 
(link->fec_state == dc_link_fec_enabled);
copy_settings_data->flags.bitfields.dsc_enable_status = 
(pipe_ctx->stream->timing.flags.DSC == 1);
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 5ff0a865705f..7c3838362c49 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -336,6 +336,10 @@ union dmub_psr_debug_flags {
 */
uint32_t back_to_back_flip : 1;
 
+   /**
+* Enable visual confirm for IPS
+*/
+   uint32_t enable_ips_visual_confirm : 1;
} bitfields;
 
/**
-- 
2.34.1



[PATCH 42/50] drm/amd/display: Check stream pointer is initialized before accessing

2024-07-10 Thread Fangzhi Zuo
From: Sung Joon Kim 

[why & how]
We calculate static screen wait frames based
on the current timing info in the active stream.
If stream is not initialized, then we should skip
the calculation and go with the default values.

Reviewed-by: Gabe Teeger 
Signed-off-by: Jerry Zuo 
Signed-off-by: Sung Joon Kim 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index ddf0807db627..ac1e3331a77c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -1461,10 +1461,9 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
 
for (i = 0; i < num_pipes; i++) {
if ((pipe_ctx[i]->stream_res.tg != NULL) && 
pipe_ctx[i]->stream_res.tg->funcs) {
-   struct dc_crtc_timing *timing = 
&pipe_ctx[i]->stream->timing;
-   struct dc *dc = pipe_ctx[i]->stream->ctx->dc;
-
-   if (dc->debug.static_screen_wait_frames) {
+   if (pipe_ctx[i]->stream && 
pipe_ctx[i]->stream->ctx->dc->debug.static_screen_wait_frames) {
+   struct dc_crtc_timing *timing = 
&pipe_ctx[i]->stream->timing;
+   struct dc *dc = pipe_ctx[i]->stream->ctx->dc;
unsigned int frame_rate = timing->pix_clk_100hz 
/ (timing->h_total * timing->v_total);
 
if (frame_rate >= 120 && dc->caps.ips_support &&
-- 
2.34.1



[PATCH 39/50] drm/amd/display: add dmcub support check

2024-07-10 Thread Fangzhi Zuo
From: Fudongwang 

[Why & How]
For DCN harvest case, if there is no dmcub support, we should return false
to avoid bugcheck later.

Reviewed-by: Aric Cyr 
Signed-off-by: Jerry Zuo 
Signed-off-by: Fudongwang 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 9897e322e2d5..f07b13ad4ead 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -5574,6 +5574,9 @@ void 
dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
  */
 bool dc_is_dmub_outbox_supported(struct dc *dc)
 {
+   if (!dc->caps.dmcub_support)
+   return false;
+
switch (dc->ctx->asic_id.chip_family) {
 
case FAMILY_YELLOW_CARP:
-- 
2.34.1



[PATCH 41/50] drm/amd/display: Export additional FAMS2 global configuration options from DML

2024-07-10 Thread Fangzhi Zuo
From: Dillon Varone 

[WHY&HOW]
Some global configuration options were previously hardcoded in DC, now they are
exported by DML and sent to FW.

Reviewed-by: Martin Leung 
Signed-off-by: Jerry Zuo 
Signed-off-by: Dillon Varone 
---
 .../gpu/drm/amd/display/dc/core/dc_state.c|   4 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |  34 ++---
 .../amd/display/dc/dml2/dml21/dml21_utils.c   | 143 ++
 .../dml2/dml21/src/dml2_core/dml2_core_dcn4.c |   1 +
 .../src/dml2_core/dml2_core_dcn4_calcs.c  |  17 ++-
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c |   4 +-
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   2 +-
 7 files changed, 110 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
index 665157f8d4cb..2597e3fd562b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -967,10 +967,10 @@ bool dc_state_is_fams2_in_use(
bool is_fams2_in_use = false;
 
if (state)
-   is_fams2_in_use |= state->bw_ctx.bw.dcn.fams2_stream_count > 0;
+   is_fams2_in_use |= 
state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
 
if (dc->current_state)
-   is_fams2_in_use |= 
dc->current_state->bw_ctx.bw.dcn.fams2_stream_count > 0;
+   is_fams2_in_use |= 
dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
 
return is_fams2_in_use;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index ded13026c8ff..fb3391854eed 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1672,22 +1672,17 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
global_cmd->header.sub_type = DMUB_CMD__FAMS2_CONFIG;
global_cmd->header.payload_bytes = sizeof(struct dmub_rb_cmd_fams2) - 
sizeof(struct dmub_cmd_header);
 
-   /* send global configuration parameters */
-   global_cmd->config.global.max_allow_delay_us = 100 * 1000; //100ms
-   global_cmd->config.global.lock_wait_time_us = 5000; //5ms
-   global_cmd->config.global.recovery_timeout_us = 5000; //5ms
-   global_cmd->config.global.hwfq_flip_programming_delay_us = 100; //100us
-
-   /* copy static feature configuration */
-   global_cmd->config.global.features.all = dc->debug.fams2_config.all;
+   if (enable) {
+   /* send global configuration parameters */
+   memcpy(&global_cmd->config.global, 
&context->bw_ctx.bw.dcn.fams2_global_config, sizeof(struct 
dmub_cmd_fams2_global_config));
 
-   /* apply feature configuration based on current driver state */
-   global_cmd->config.global.features.bits.enable_visual_confirm = 
dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS2;
-   global_cmd->config.global.features.bits.enable = enable;
+   /* copy static feature configuration overrides */
+   global_cmd->config.global.features.bits.enable_stall_recovery = 
dc->debug.fams2_config.bits.enable_stall_recovery;
+   global_cmd->config.global.features.bits.enable_debug = 
dc->debug.fams2_config.bits.enable_debug;
+   global_cmd->config.global.features.bits.enable_offload_flip = 
dc->debug.fams2_config.bits.enable_offload_flip;
 
-   /* construct per-stream configs */
-   if (enable) {
-   for (i = 0; i < context->bw_ctx.bw.dcn.fams2_stream_count; i++) 
{
+   /* construct per-stream configs */
+   for (i = 0; i < 
context->bw_ctx.bw.dcn.fams2_global_config.num_streams; i++) {
struct dmub_rb_cmd_fams2 *stream_cmd = 
&cmd[i+1].fams2_config;
 
/* configure command header */
@@ -1702,12 +1697,15 @@ void dc_dmub_srv_fams2_update_config(struct dc *dc,
}
}
 
-   if (enable && context->bw_ctx.bw.dcn.fams2_stream_count) {
+   /* apply feature configuration based on current driver state */
+   global_cmd->config.global.features.bits.enable_visual_confirm = 
dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS2;
+   global_cmd->config.global.features.bits.enable = enable;
+
+   if (enable && 
context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) {
/* set multi pending for global, and unset for last stream cmd 
*/
-   global_cmd->config.global.num_streams = 
context->bw_ctx.bw.dcn.fams2_stream_count;
global_cmd->header.multi_cmd_pending = 1;
-   
cmd[context->bw_ctx.bw.dcn.fams2_stream_count].fams2_config.header.multi_cmd_pending
 = 0;
-   num_cmds += context->bw_ctx.bw.dcn.fams2_stream_count;
+   
cmd[context->bw_ctx.bw.dcn.fams2_global_config.num_streams].fams2_config.header.multi_cmd_pending
 = 0;
+   num_cmds += 
context->bw_ctx.bw.dcn.fams2_global_config.num_stre

[PATCH 40/50] drm/amd/display: Refactoring DWB related files from dcn30 Files

2024-07-10 Thread Fangzhi Zuo
From: Mudimela 

[Why]
To refactor DWB related files from dcn30 Files

[How]
Moved DWB related files from dcn30 to specific DWB folder and
updated Makefiles to fix Compilation.

Reviewed-by: Martin Leung 
Signed-off-by: Jerry Zuo 
Signed-off-by: Mudimela 
---
 drivers/gpu/drm/amd/display/dc/dcn30/Makefile| 2 --
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c   | 2 +-
 drivers/gpu/drm/amd/display/dc/dwb/Makefile  | 9 +
 .../drm/amd/display/dc/{ => dwb}/dcn30/dcn30_cm_common.h | 0
 .../gpu/drm/amd/display/dc/{ => dwb}/dcn30/dcn30_dwb.c   | 0
 .../gpu/drm/amd/display/dc/{ => dwb}/dcn30/dcn30_dwb.h   | 0
 .../drm/amd/display/dc/{ => dwb}/dcn30/dcn30_dwb_cm.c| 0
 drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c | 1 -
 8 files changed, 10 insertions(+), 4 deletions(-)
 rename drivers/gpu/drm/amd/display/dc/{ => dwb}/dcn30/dcn30_cm_common.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dwb}/dcn30/dcn30_dwb.c (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dwb}/dcn30/dcn30_dwb.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dwb}/dcn30/dcn30_dwb_cm.c (100%)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
index 804851247acc..ccb4b21338b9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
@@ -25,8 +25,6 @@
 
 DCN30 := dcn30_vpg.o \
dcn30_afmt.o \
-   dcn30_dwb.o \
-   dcn30_dwb_cm.o \
dcn30_cm_common.o \
dcn30_mmhubbub.o \
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
index b8327237ed44..685702321d32 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
@@ -28,7 +28,7 @@
 #include "reg_helper.h"
 #include "dcn30/dcn30_dpp.h"
 #include "basics/conversion.h"
-#include "dcn30_cm_common.h"
+#include "dcn30/dcn30_cm_common.h"
 #include "custom_float.h"
 
 #define REG(reg) reg
diff --git a/drivers/gpu/drm/amd/display/dc/dwb/Makefile 
b/drivers/gpu/drm/amd/display/dc/dwb/Makefile
index 16f7a454fed9..3952ba4cd508 100644
--- a/drivers/gpu/drm/amd/display/dc/dwb/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dwb/Makefile
@@ -24,6 +24,15 @@
 #
 
 ifdef CONFIG_DRM_AMD_DC_FP
+###
+# DCN30
+###
+DWB_DCN30 = dcn30_dwb.o dcn30_dwb_cm.o
+
+AMD_DAL_DWB_DCN30 = $(addprefix $(AMDDALPATH)/dc/dwb/dcn30/,$(DWB_DCN30))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DWB_DCN30)
+
 ###
 # DCN35
 ###
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.h 
b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.h
rename to drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c 
b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c
rename to drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h 
b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h
rename to drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c 
b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
rename to drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c
diff --git a/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c 
b/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c
index b23a80ed..d5e8294f5a16 100644
--- a/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c
+++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn35/dcn35_dwb.c
@@ -21,7 +21,6 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  */
-
 #include "reg_helper.h"
 #include "dcn35_dwb.h"
 
-- 
2.34.1



[PATCH 38/50] drm/amd/display: Increase array size of dummy_boolean

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHY]
dml2_core_shared_mode_support and dml_core_mode_support access the third
element of dummy_boolean, i.e. hw_debug5 = &s->dummy_boolean[2], when
dummy_boolean has size of 2. Any assignment to hw_debug5 causes an
OVERRUN.

[HOW]
Increase dummy_boolean's array size to 3.

This fixes 2 OVERRUN issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 .../dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h| 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
index 02498c0e3282..317008eff61b 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -866,7 +866,7 @@ struct dml2_core_calcs_mode_support_locals {
unsigned int dpte_row_bytes_per_row_l[DML2_MAX_PLANES];
unsigned int dpte_row_bytes_per_row_c[DML2_MAX_PLANES];
 
-   bool dummy_boolean[2];
+   bool dummy_boolean[3];
unsigned int dummy_integer[3];
unsigned int dummy_integer_array[36][DML2_MAX_PLANES];
enum dml2_odm_mode dummy_odm_mode[DML2_MAX_PLANES];
-- 
2.34.1



[PATCH 37/50] drm/amd/display: Check null pointers before multiple uses

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
Poniters, such as stream_enc and dc->bw_vbios, are null checked previously
in the same function, so Coverity warns "implies that stream_enc and
dc->bw_vbios might be null". They are used multiple times in the
subsequent code and need to be checked.

This fixes 10 FORWARD_NULL issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 .../drm/amd/display/dc/core/dc_hw_sequencer.c | 96 ++-
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  8 +-
 .../display/dc/link/accessories/link_dp_cts.c |  5 +-
 .../amd/display/dc/link/hwss/link_hwss_dio.c  |  5 +-
 .../dc/resource/dce112/dce112_resource.c  |  5 +-
 .../dc/resource/dcn32/dcn32_resource.c|  3 +
 .../resource/dcn32/dcn32_resource_helpers.c   | 10 +-
 7 files changed, 76 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 9e42a0128baa..5f9b6e8ef428 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -636,57 +636,59 @@ void hwss_build_fast_sequence(struct dc *dc,
while (current_pipe) {
current_mpc_pipe = current_pipe;
while (current_mpc_pipe) {
-   if (dc->hwss.set_flip_control_gsl && 
current_mpc_pipe->plane_state && 
current_mpc_pipe->plane_state->update_flags.raw) {
-   
block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = 
current_mpc_pipe;
-   
block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = 
current_mpc_pipe->plane_state->flip_immediate;
-   block_sequence[*num_steps].func = 
HUBP_SET_FLIP_CONTROL_GSL;
-   (*num_steps)++;
-   }
-   if (dc->hwss.program_triplebuffer && 
dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
-   
block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
-   
block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = 
current_mpc_pipe;
-   
block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer
 = current_mpc_pipe->plane_state->triplebuffer_flips;
-   block_sequence[*num_steps].func = 
HUBP_PROGRAM_TRIPLEBUFFER;
-   (*num_steps)++;
-   }
-   if (dc->hwss.update_plane_addr && 
current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
-   if (resource_is_pipe_type(current_mpc_pipe, 
OTG_MASTER) &&
-   
stream_status->mall_stream_config.type == SUBVP_MAIN) {
-   
block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = 
dc->ctx->dmub_srv;
-   
block_sequence[*num_steps].params.subvp_save_surf_addr.addr = 
¤t_mpc_pipe->plane_state->address;
-   
block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = 
current_mpc_pipe->subvp_index;
-   block_sequence[*num_steps].func = 
DMUB_SUBVP_SAVE_SURF_ADDR;
+   if (current_mpc_pipe->plane_state) {
+   if (dc->hwss.set_flip_control_gsl && 
current_mpc_pipe->plane_state->update_flags.raw) {
+   
block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = 
current_mpc_pipe;
+   
block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = 
current_mpc_pipe->plane_state->flip_immediate;
+   block_sequence[*num_steps].func = 
HUBP_SET_FLIP_CONTROL_GSL;
+   (*num_steps)++;
+   }
+   if (dc->hwss.program_triplebuffer && 
dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
+   
block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
+   
block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = 
current_mpc_pipe;
+   
block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer
 = current_mpc_pipe->plane_state->triplebuffer_flips;
+   block_sequence[*num_steps].func = 
HUBP_PROGRAM_TRIPLEBUFFER;
+   (*num_steps)++;
+   }
+   if (dc->hwss.update_plane_addr && 
cur

[PATCH 36/50] drm/amd/display: Check null pointers before used

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
Poniters, such as dc->clk_mgr, are null checked previously in the same
function, so Coverity warns "implies that "dc->clk_mgr" might be null".
As a result, these pointers need to be checked when used again.

This fixes 10 FORWARD_NULL issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 .../drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c| 2 +-
 drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c| 3 ++-
 drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c| 3 ++-
 drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 5 +++--
 drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c   | 4 ++--
 drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c   | 4 ++--
 drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c   | 8 
 .../amd/display/dc/link/protocols/link_dp_capability.c| 2 +-
 8 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
index 78df96882d6e..f8409453434c 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
@@ -195,7 +195,7 @@ void dce11_pplib_apply_display_requirements(
 * , then change minimum memory clock based on real-time bandwidth
 * limitation.
 */
-   if ((dc->ctx->asic_id.chip_family == FAMILY_AI) &&
+   if (dc->bw_vbios && (dc->ctx->asic_id.chip_family == FAMILY_AI) &&
 ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && 
(context->stream_count >= 2)) {
pp_display_cfg->min_memory_clock_khz = 
max(pp_display_cfg->min_memory_clock_khz,
   (uint32_t) div64_s64(
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
index bf399819ca80..22ac2b7e49ae 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
@@ -749,7 +749,8 @@ bool hubp1_is_flip_pending(struct hubp *hubp)
if (flip_pending)
return true;
 
-   if (earliest_inuse_address.grph.addr.quad_part != 
hubp->request_address.grph.addr.quad_part)
+   if (hubp &&
+   earliest_inuse_address.grph.addr.quad_part != 
hubp->request_address.grph.addr.quad_part)
return true;
 
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
index 6bba020ad6fb..0637e4c552d8 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
@@ -927,7 +927,8 @@ bool hubp2_is_flip_pending(struct hubp *hubp)
if (flip_pending)
return true;
 
-   if (earliest_inuse_address.grph.addr.quad_part != 
hubp->request_address.grph.addr.quad_part)
+   if (hubp &&
+   earliest_inuse_address.grph.addr.quad_part != 
hubp->request_address.grph.addr.quad_part)
return true;
 
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 849b41f886d3..4593fb2a0536 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -949,7 +949,7 @@ void dce110_edp_backlight_control(
 {
struct dc_context *ctx = link->ctx;
struct bp_transmitter_control cntl = { 0 };
-   uint8_t pwrseq_instance;
+   uint8_t pwrseq_instance = 0;
unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
unsigned int post_T7_delay = OLED_POST_T7_DELAY;
 
@@ -1002,7 +1002,8 @@ void dce110_edp_backlight_control(
 */
/* dc_service_sleep_in_milliseconds(50); */
/*edp 1.2*/
-   pwrseq_instance = link->panel_cntl->pwrseq_inst;
+   if (link->panel_cntl)
+   pwrseq_instance = link->panel_cntl->pwrseq_inst;
 
if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
if (!link->dc->config.edp_no_power_sequencing)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index 4846601c612d..212576dbc336 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -1553,7 +1553,7 @@ void dcn10_init_hw(struct dc *dc)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
 
/* Align bw context with hw config when system resume. */
-   if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz 
!= 0) {
+   if (dc->clk_mgr && dc->clk_mgr->clks.dispclk_khz != 0 && 
dc->clk_mgr->clks.dppclk_khz != 

[PATCH 35/50] drm/amd/display: Check link_res->hpo_dp_link_enc before using it

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
Functions dp_enable_link_phy and dp_disable_link_phy can pass link_res
without initializing hpo_dp_link_enc and it is necessary to check for
null before dereferencing.

This fixes 2 FORWARD_NULL issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c| 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c 
b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
index e1257404357b..d0148f10dfc0 100644
--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
@@ -28,6 +28,8 @@
 #include "dccg.h"
 #include "clk_mgr.h"
 
+#define DC_LOGGER link->ctx->logger
+
 void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
struct fixed31_32 throttled_vcp_size)
 {
@@ -124,6 +126,11 @@ void disable_hpo_dp_link_output(struct dc_link *link,
const struct link_resource *link_res,
enum signal_type signal)
 {
+   if (!link_res->hpo_dp_link_enc) {
+   DC_LOG_ERROR("%s: invalid hpo_dp_link_enc\n", __func__);
+   return;
+   }
+

link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
link_res->hpo_dp_link_enc->funcs->disable_link_phy(
link_res->hpo_dp_link_enc, signal);
-- 
2.34.1



[PATCH 33/50] drm/amd/display: remove dc dependencies from SPL library

2024-07-10 Thread Fangzhi Zuo
From: Samson Tam 

[Why]
Make SPL library dc-independent so it can be reused by other
 components

[How]
Create separate set of fixed31_32 calls in SPL
Make all inputs and outputs to SPL use primitive types
For ratios and inits, return as uint32 from SPL.  So
 add conversion from uint32 back to fixed point in
 SPL-to-dc translate function

Reviewed-by: Relja Vojvodic 
Signed-off-by: Jerry Zuo 
Signed-off-by: Samson Tam 
---
 .../drm/amd/display/dc/basics/fixpt31_32.c|  27 +
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   2 -
 .../gpu/drm/amd/display/dc/dc_spl_translate.c |  43 +-
 drivers/gpu/drm/amd/display/dc/spl/Makefile   |   2 +-
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c   | 566 +-
 .../display/dc/spl/dc_spl_isharp_filters.c|  27 +-
 .../display/dc/spl/dc_spl_isharp_filters.h|   2 +-
 .../display/dc/spl/dc_spl_scl_easf_filters.c  |  81 +--
 .../display/dc/spl/dc_spl_scl_easf_filters.h  |  32 +-
 .../amd/display/dc/spl/dc_spl_scl_filters.c   |  69 +--
 .../amd/display/dc/spl/dc_spl_scl_filters.h   |  18 +-
 .../gpu/drm/amd/display/dc/spl/dc_spl_types.h |  39 +-
 .../gpu/drm/amd/display/dc/spl/spl_debug.h|  23 +
 .../drm/amd/display/dc/spl/spl_fixpt31_32.c   | 518 
 .../drm/amd/display/dc/spl/spl_fixpt31_32.h   | 546 +
 .../gpu/drm/amd/display/dc/spl/spl_os_types.h |  77 +++
 .../gpu/drm/amd/display/include/fixed31_32.h  |   6 +
 17 files changed, 1646 insertions(+), 432 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_debug.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_fixpt31_32.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/spl/spl_os_types.h

diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c 
b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 506f82cd5cc6..88d3f9d7dd55 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -486,3 +486,30 @@ int dc_fixpt_s4d19(struct fixed31_32 arg)
else
return ux_dy(arg.value, 4, 19);
 }
+
+struct fixed31_32 dc_fixpt_from_ux_dy(unsigned int value,
+   unsigned int integer_bits,
+   unsigned int fractional_bits)
+{
+   struct fixed31_32 fixpt_value = dc_fixpt_zero;
+   struct fixed31_32 fixpt_int_value = dc_fixpt_zero;
+   long long frac_mask = ((long long)1 << (long long)integer_bits) - 1;
+
+   fixpt_value.value = (long long)value << 
(FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+   frac_mask = frac_mask << fractional_bits;
+   fixpt_int_value.value = value & frac_mask;
+   fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - 
fractional_bits);
+   fixpt_value.value |= fixpt_int_value.value;
+   return fixpt_value;
+}
+
+struct fixed31_32 dc_fixpt_from_int_dy(unsigned int int_value,
+   unsigned int frac_value,
+   unsigned int integer_bits,
+   unsigned int fractional_bits)
+{
+   struct fixed31_32 fixpt_value = dc_fixpt_from_int(int_value);
+
+   fixpt_value.value |= (long long)frac_value << 
(FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits);
+   return fixpt_value;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 4f5b23520365..5c9091f2a8b2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1511,8 +1511,6 @@ bool resource_build_scaling_params(struct pipe_ctx 
*pipe_ctx)
pipe_ctx->plane_res.scl_data.lb_params.depth = 
LB_PIXEL_DEPTH_30BPP;
 
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = 
plane_state->per_pixel_alpha;
-   spl_out->scl_data.h_active = 
pipe_ctx->plane_res.scl_data.h_active;
-   spl_out->scl_data.v_active = 
pipe_ctx->plane_res.scl_data.v_active;
 
// Convert pipe_ctx to respective input params for SPL
translate_SPL_in_params_from_pipe_ctx(pipe_ctx, spl_in);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c 
b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
index 49ff59258c8d..339d092e711c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
@@ -42,26 +42,26 @@ static void populate_spltaps_from_taps(struct spl_taps 
*spl_scaling_quality,
 static void populate_taps_from_spltaps(struct scaling_taps *scaling_quality,
const struct spl_taps *spl_scaling_quality)
 {
-   scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c;
-   scaling_quality->h_taps = spl_scaling_quality->h_taps;
-   scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c;
-   scaling_quality->v_taps = spl_scaling_quality->v_taps;
+   scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c + 1;
+   scaling_quality->h_taps = sp

[PATCH 31/50] drm/amd/display: Calculate ODM width using odm slice rect, not recout

2024-07-10 Thread Fangzhi Zuo
From: Alvin Lee 

[Description]
There are scenarios where ODM4:1 is used but the
surface is entirely outside of the first and last
ODM slice. In this case the recout.width for the
first and last slice is 0 because there's no overlap
with the surface and that ODM slice, but this causes
the x_pos for the cursor in this scenario to be
calculated incorrectly. Instead we should use the
ODM slice width instead of the recout width.

Reviewed-by: Nevenko Stupar 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index b9378f18c020..31e0e9210dd7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1115,10 +1115,10 @@ void dcn401_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
.mirror = pipe_ctx->plane_state->horizontal_mirror,
.stream = pipe_ctx->stream
};
+   struct rect odm_slice_src = { 0 };
bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
(pipe_ctx->prev_odm_pipe != NULL);
int prev_odm_width = 0;
-   int prev_odm_offset = 0;
struct pipe_ctx *prev_odm_pipe = NULL;
bool mpc_combine_on = false;
int  bottom_pipe_x_pos = 0;
@@ -1183,12 +1183,12 @@ void dcn401_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
prev_odm_pipe = pipe_ctx->prev_odm_pipe;
 
while (prev_odm_pipe != NULL) {
-   prev_odm_width += 
prev_odm_pipe->plane_res.scl_data.recout.width;
-   prev_odm_offset += 
prev_odm_pipe->plane_res.scl_data.recout.x;
+   odm_slice_src = 
resource_get_odm_slice_src_rect(prev_odm_pipe);
+   prev_odm_width += odm_slice_src.width;
prev_odm_pipe = prev_odm_pipe->prev_odm_pipe;
}
 
-   x_pos -= (prev_odm_width + prev_odm_offset);
+   x_pos -= (prev_odm_width);
}
 
/* If the position is negative then we need to add to the hotspot
-- 
2.34.1



[PATCH 32/50] drm/amd/display: Issue with 3 or more mcaches per surface

2024-07-10 Thread Fangzhi Zuo
From: Nevenko Stupar 

[Why & How]
Current logic in mcache admissibility check has flaw if
calculated number of maches are 3 or more per surface,
so sometimes the check may pass when it should fail,
and sometimes may fail when it should pass, fix the
issue and also adding additional check to make sure that
required number of mcaches per surface cannot be
higher than number of pipes + 1, used on that surface.

Reviewed-by: Chaitanya Dhere 
Signed-off-by: Jerry Zuo 
Signed-off-by: Nevenko Stupar 
---
 .../dml2/dml21/src/dml2_top/dml_top_mcache.c  | 22 +--
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c
index e69f8ce97e24..a342ebfbe4e7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top_mcache.c
@@ -142,12 +142,12 @@ static unsigned int count_elements_in_span(int *array, 
unsigned int array_size,
 
while (span_start_index < array_size) {
for (i = span_start_index; i < array_size; i++) {
-   if (array[i] - span_start_value > span) {
+   if (array[i] - span_start_value <= span) {
if (i - span_start_index + 1 > 
greatest_element_count) {
greatest_element_count = i - 
span_start_index + 1;
}
+   } else
break;
-   }
}
 
span_start_index++;
@@ -207,9 +207,9 @@ bool dml2_top_mcache_validate_admissability(struct 
top_mcache_validate_admissabi
int temp, p0shift, p1shift;
unsigned int plane_index = 0;
unsigned int i;
-   char odm_combine_factor = 1;
-   char mpc_combine_factor = 1;
-   char num_dpps;
+   unsigned int odm_combine_factor;
+   unsigned int mpc_combine_factor;
+   unsigned int num_dpps;
unsigned int num_boundaries;
enum dml2_scaling_transform scaling_transform;
const struct dml2_plane_parameters *plane;
@@ -226,10 +226,10 @@ bool dml2_top_mcache_validate_admissability(struct 
top_mcache_validate_admissabi
plane = ¶ms->display_cfg->plane_descriptors[plane_index];
stream = 
¶ms->display_cfg->stream_descriptors[plane->stream_index];
 
-   odm_combine_factor = 
(char)params->cfg_support_info->stream_support_info[plane->stream_index].odms_used;
+   num_dpps = odm_combine_factor = 
params->cfg_support_info->stream_support_info[plane->stream_index].odms_used;
 
if (odm_combine_factor == 1)
-   mpc_combine_factor = 
(char)params->cfg_support_info->plane_support_info[plane_index].dpps_used;
+   num_dpps = mpc_combine_factor = (unsigned 
int)params->cfg_support_info->plane_support_info[plane_index].dpps_used;
else
mpc_combine_factor = 1;
 
@@ -259,13 +259,13 @@ bool dml2_top_mcache_validate_admissability(struct 
top_mcache_validate_admissabi
// The last element in the unshifted boundary array will always 
be the first pixel outside the
// plane, which means theres no mcache associated with it, so -1
num_boundaries = 
params->mcache_allocations[plane_index].num_mcaches_plane0 == 0 ? 0 : 
params->mcache_allocations[plane_index].num_mcaches_plane0 - 1;
-   if 
(count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane0,
-   num_boundaries, max_per_pipe_vp_p0) <= 1) {
+   if 
((count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane0,
+   num_boundaries, max_per_pipe_vp_p0) <= 1) && 
(num_boundaries <= num_dpps)) {
p0pass = true;
}
num_boundaries = 
params->mcache_allocations[plane_index].num_mcaches_plane1 == 0 ? 0 : 
params->mcache_allocations[plane_index].num_mcaches_plane1 - 1;
-   if 
(count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane1,
-   num_boundaries, max_per_pipe_vp_p1) <= 1) {
+   if 
((count_elements_in_span(params->mcache_allocations[plane_index].mcache_x_offsets_plane1,
+   num_boundaries, max_per_pipe_vp_p1) <= 1) && 
(num_boundaries <= num_dpps)) {
p1pass = true;
}
 
-- 
2.34.1



[PATCH 34/50] drm/amd/display: Add P-State Keepout to dcn401 Global Sync

2024-07-10 Thread Fangzhi Zuo
From: Dillon Varone 

[WHY&HOW]
OTG has new functionality to allow P-State relative to VStartup. Keepout region
for this should be configured based on DML outputs same as other global sync
params.

Reviewed-by: Alvin Lee 
Signed-off-by: Jerry Zuo 
Signed-off-by: Dillon Varone 
---
 .../dc/dce110/dce110_timing_generator.c   |  1 +
 .../dc/dce110/dce110_timing_generator.h   |  1 +
 .../dc/dce110/dce110_timing_generator_v.c |  1 +
 .../dc/dce120/dce120_timing_generator.c   |  1 +
 .../display/dc/dce60/dce60_timing_generator.c |  3 +-
 .../display/dc/dce80/dce80_timing_generator.c |  3 +-
 .../amd/display/dc/dml/display_mode_structs.h |  1 +
 .../dc/dml2/dml21/dml21_translation_helper.c  |  1 +
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  1 +
 .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c   |  4 ++-
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  7 ++--
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c |  1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/optc.h  |  5 ++-
 .../amd/display/dc/inc/hw/timing_generator.h  |  4 ++-
 .../amd/display/dc/optc/dcn10/dcn10_optc.c|  9 +++--
 .../amd/display/dc/optc/dcn10/dcn10_optc.h|  7 +++-
 .../amd/display/dc/optc/dcn401/dcn401_optc.c  | 36 ++-
 .../amd/display/dc/optc/dcn401/dcn401_optc.h  |  6 +++-
 .../dc/resource/dce110/dce110_resource.c  |  1 +
 .../dc/resource/dcn401/dcn401_resource.h  |  3 +-
 20 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c 
b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
index 49bcfe6ec999..fa422a8cbced 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
@@ -1955,6 +1955,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+   int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h 
b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
index 28c58f1dff2d..ee4de740aceb 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
@@ -261,6 +261,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+   int pstate_keepout,
const enum signal_type signal,
bool use_vbios);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c 
b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
index bf35dc65ca29..9837dec837ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
@@ -438,6 +438,7 @@ static void dce110_timing_generator_v_program_timing(struct 
timing_generator *tg
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+   int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c 
b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
index eb3557965781..fcf59348eb62 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
@@ -697,6 +697,7 @@ static void dce120_tg_program_timing(struct 
timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+   int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c 
b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
index c1a85ee374d9..e5fb0e8333e4 100644
--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
int vstartup_start,
int vupdate_offset,
int vupdate_width,
+   int pstate_keepout,
const enum signal_type signal,
bool use_vbios)
 {
if (!use_vbios)
program_pix_dur(tg, timing->pix_clk_100hz);
 
-   dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios);
+   dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
 }
 
 static void dce60_timing_generator_enable_advanced_request(
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c 
b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
index 2df4654858be..003a9330c286 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generato

[PATCH 30/50] drm/amd/display: Add blanked streams override to DML2.1

2024-07-10 Thread Fangzhi Zuo
From: Dillon Varone 

[WHY]
DML2.1 currently has no concept of a "blanked" stream. For cases like DPMS off,
things like UCLK p-state is always allowed, so PMO is not required to optimize
for it.

[HOW]
Add flag to DML2.1 display configuration to indicate all streams are blanked,
so certain operations and optimizations can be skipped for optimal programming
when displays are blanked.

Reviewed-by: Chaitanya Dhere 
Signed-off-by: Jerry Zuo 
Signed-off-by: Dillon Varone 
---
 .../amd/display/dc/dml2/dml21/dml21_translation_helper.c   | 7 +++
 1 file changed, 7 insertions(+)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
index 405544920f3b..e9647f068ee4 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
@@ -957,6 +957,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct 
dc *in_dc, struct dc_s
int stream_index, plane_index;
int disp_cfg_stream_location, disp_cfg_plane_location;
struct dml2_display_cfg *dml_dispcfg = &dml_ctx->v21.display_config;
+   unsigned int plane_count = 0;
 
memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct 
dml2_dml_to_dc_pipe_mapping));
 
@@ -1010,10 +1011,16 @@ bool dml21_map_dc_state_into_dml_display_cfg(const 
struct dc *in_dc, struct dc_s

dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy
 =

dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]);
}
+
+   plane_count++;
}
}
}
 
+   if (plane_count == 0) {
+   dml_dispcfg->overrides.all_streams_blanked = true;
+   }
+
return true;
 }
 
-- 
2.34.1



[PATCH 29/50] drm/amd/display: Re-enable panel replay feature

2024-07-10 Thread Fangzhi Zuo
From: Tom Chung 

[Why & How]
Fixed the replay issues and now re-enable the panel replay feature.

Reported-by: Arthur Borsboom 
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3344

Reviewed-by: Mario Limonciello 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Tom Chung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ---
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index fe5a96e5c70a..864a66406f8a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4836,18 +4836,14 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
/* Determine whether to enable Replay support by default. */
if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
-/*
- * Disabled by default due to 
https://gitlab.freedesktop.org/drm/amd/-/issues/3344
- * case IP_VERSION(3, 1, 4):
- * case IP_VERSION(3, 1, 5):
- * case IP_VERSION(3, 1, 6):
- * case IP_VERSION(3, 2, 0):
- * case IP_VERSION(3, 2, 1):
- * case IP_VERSION(3, 5, 0):
- * case IP_VERSION(3, 5, 1):
- * replay_feature_enabled = true;
- * break;
- */
+   case IP_VERSION(3, 1, 4):
+   case IP_VERSION(3, 2, 0):
+   case IP_VERSION(3, 2, 1):
+   case IP_VERSION(3, 5, 0):
+   case IP_VERSION(3, 5, 1):
+   replay_feature_enabled = true;
+   break;
+
default:
replay_feature_enabled = amdgpu_dc_feature_mask & 
DC_REPLAY_MASK;
break;
-- 
2.34.1



[PATCH 28/50] drm/amd/display: Fix VRR cannot enable

2024-07-10 Thread Fangzhi Zuo
From: Tom Chung 

[Why]
Sometimes the VRR cannot enable after login to the desktop.

User space may call the DRM_IOCTL_MODE_GETCONNECTOR right after
the DRM_IOCTL_MODE_RMFB.

After calling DRM_IOCTL_MODE_RMFB to remove all the frame buffer
and it will cause the driver to disable the crtc and disable the
link while calling the link_set_dpms_off().

It will cause the dpcd read failed in amdgpu_dm_update_freesync_caps()
while try to get the DP_MSA_TIMING_PAR_IGNORED capability and think
the sink side does not support VRR.

[How]
Use the dpcd_caps.allow_invalid_MSA_timing_param flag instead of
reading from dpcd directly.

dpcd_caps.allow_invalid_MSA_timing_param flag is updated during HPD.
It is safe to replace the original method.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Tom Chung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++-
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 18d6bb485cb1..fe5a96e5c70a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -11722,25 +11722,6 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
return ret;
 }
 
-static bool is_dp_capable_without_timing_msa(struct dc *dc,
-struct amdgpu_dm_connector 
*amdgpu_dm_connector)
-{
-   u8 dpcd_data;
-   bool capable = false;
-
-   if (amdgpu_dm_connector->dc_link &&
-   dm_helpers_dp_read_dpcd(
-   NULL,
-   amdgpu_dm_connector->dc_link,
-   DP_DOWN_STREAM_PORT_COUNT,
-   &dpcd_data,
-   sizeof(dpcd_data))) {
-   capable = (dpcd_data & DP_MSA_TIMING_PAR_IGNORED) ? true:false;
-   }
-
-   return capable;
-}
-
 static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
unsigned int offset,
unsigned int total_length,
@@ -12043,8 +12024,8 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
 sink->sink_signal == SIGNAL_TYPE_EDP)) {
bool edid_check_required = false;
 
-   if (is_dp_capable_without_timing_msa(adev->dm.dc,
-amdgpu_dm_connector)) {
+   if (amdgpu_dm_connector->dc_link &&
+   
amdgpu_dm_connector->dc_link->dpcd_caps.allow_invalid_MSA_timing_param) {
if (edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ) {
amdgpu_dm_connector->min_vfreq = 
connector->display_info.monitor_range.min_vfreq;
amdgpu_dm_connector->max_vfreq = 
connector->display_info.monitor_range.max_vfreq;
-- 
2.34.1



[PATCH 27/50] drm/amd/display: Refactoring MPC

2024-07-10 Thread Fangzhi Zuo
From: Mounika Adhuri 

[Why]
To refactor MPC files

[How]
Moved MPC files to respective folders and
updated makefiles appropriately.

Reviewed-by: Martin Leung 
Signed-off-by: Jerry Zuo 
Signed-off-by: Mounika Adhuri 
---
 drivers/gpu/drm/amd/display/dc/dcn10/Makefile |  1 -
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile |  3 +--
 drivers/gpu/drm/amd/display/dc/dcn30/Makefile |  2 +-
 drivers/gpu/drm/amd/display/dc/mpc/Makefile   | 27 +++
 .../display/dc/{ => mpc}/dcn10/dcn10_mpc.c|  0
 .../display/dc/{ => mpc}/dcn10/dcn10_mpc.h|  0
 .../display/dc/{ => mpc}/dcn20/dcn20_mpc.c|  0
 .../display/dc/{ => mpc}/dcn20/dcn20_mpc.h|  0
 .../display/dc/{ => mpc}/dcn30/dcn30_mpc.c|  2 +-
 .../display/dc/{ => mpc}/dcn30/dcn30_mpc.h|  0
 10 files changed, 30 insertions(+), 5 deletions(-)
 rename drivers/gpu/drm/amd/display/dc/{ => mpc}/dcn10/dcn10_mpc.c (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => mpc}/dcn10/dcn10_mpc.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => mpc}/dcn20/dcn20_mpc.c (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => mpc}/dcn20/dcn20_mpc.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => mpc}/dcn30/dcn30_mpc.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => mpc}/dcn30/dcn30_mpc.h (100%)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
index 75e088b479ea..e1f6623d4936 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
@@ -24,7 +24,6 @@
 
 DCN10 = dcn10_ipp.o \
dcn10_hw_sequencer_debug.o \
-   dcn10_mpc.o \
dcn10_cm_common.o \
 
 AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
index d92d2b4ee015..25ba0d310d46 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
@@ -1,8 +1,7 @@
 # SPDX-License-Identifier: MIT
 # Copyright © 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
 
-DCN20 = dcn20_mpc.o \
-   dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
+DCN20 = dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
 
 AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20))
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
index 4c43af867d86..804851247acc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile
@@ -23,7 +23,7 @@
 #
 #
 
-DCN30 := dcn30_mpc.o dcn30_vpg.o \
+DCN30 := dcn30_vpg.o \
dcn30_afmt.o \
dcn30_dwb.o \
dcn30_dwb_cm.o \
diff --git a/drivers/gpu/drm/amd/display/dc/mpc/Makefile 
b/drivers/gpu/drm/amd/display/dc/mpc/Makefile
index 7f7458c07e2a..5402c3529f5e 100644
--- a/drivers/gpu/drm/amd/display/dc/mpc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/mpc/Makefile
@@ -24,6 +24,33 @@
 #
 
 ifdef CONFIG_DRM_AMD_DC_FP
+###
+# DCN10
+###
+MPC_DCN10 = dcn10_mpc.o
+
+AMD_DAL_MPC_DCN10 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn10/,$(MPC_DCN10))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN10)
+
+###
+# DCN20
+###
+MPC_DCN20 = dcn20_mpc.o
+
+AMD_DAL_MPC_DCN20 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn20/,$(MPC_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN20)
+
+###
+# DCN30
+###
+MPC_DCN30 = dcn30_mpc.o
+
+AMD_DAL_MPC_DCN30 = $(addprefix $(AMDDALPATH)/dc/mpc/dcn30/,$(MPC_DCN30))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MPC_DCN30)
+
 ###
 # DCN32
 ###
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
rename to drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
rename to drivers/gpu/drm/amd/display/dc/mpc/dcn10/dcn10_mpc.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c 
b/drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
rename to drivers/gpu/drm/amd/display/dc/mpc/dcn20/dcn20_mpc.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_m

[PATCH 25/50] drm/amd/display: Do 1-to-1 mapping between OPP and DSC in DML2

2024-07-10 Thread Fangzhi Zuo
From: Sung Joon Kim 

[why]
To determine which block instance to power-gate,
we look at the available pipe resource for both plane
and stream. On MPO, DSC3 was falsely powered on even
though only 1 stream path was enabled because
the resource mapping was not done correctly.

[how]
Acquire the correct DSC instance to power on / off based
on the instance of OPP which determines the backend
pipe index.

Reviewed-by: Swapnil Patel 
Signed-off-by: Jerry Zuo 
Signed-off-by: Sung Joon Kim 
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 83aa3d8a997a..4f5b23520365 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -5166,7 +5166,7 @@ bool 
dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(
sec_pipe->stream_res.opp = 
sec_pipe->top_pipe->stream_res.opp;
if (sec_pipe->stream->timing.flags.DSC == 1) {
 #if defined(CONFIG_DRM_AMD_DC_FP)
-   dcn20_acquire_dsc(dc, &state->res_ctx, 
&sec_pipe->stream_res.dsc, pipe_idx);
+   dcn20_acquire_dsc(dc, &state->res_ctx, 
&sec_pipe->stream_res.dsc, sec_pipe->stream_res.opp->inst);
 #endif
ASSERT(sec_pipe->stream_res.dsc);
if (sec_pipe->stream_res.dsc == NULL)
-- 
2.34.1



[PATCH 24/50] drm/amd/display: Refactoring MMHUBBUB

2024-07-10 Thread Fangzhi Zuo
From: Revalla Hari Krishna 

[Why]
To refactor MMHUBBUB files

[How]
Moved mmhubbub files from dcn20 to /mmhubbub/ folder and
update makefile to fix compilation.

Reviewed-by: Martin Leung 
Signed-off-by: Jerry Zuo 
Signed-off-by: Revalla Hari Krishna 
---
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile| 2 +-
 drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile | 9 +
 .../amd/display/dc/{ => mmhubbub}/dcn20/dcn20_mmhubbub.c | 0
 .../amd/display/dc/{ => mmhubbub}/dcn20/dcn20_mmhubbub.h | 0
 4 files changed, 10 insertions(+), 1 deletion(-)
 rename drivers/gpu/drm/amd/display/dc/{ => mmhubbub}/dcn20/dcn20_mmhubbub.c 
(100%)
 rename drivers/gpu/drm/amd/display/dc/{ => mmhubbub}/dcn20/dcn20_mmhubbub.h 
(100%)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
index 744a6c4ac816..d92d2b4ee015 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: MIT
 # Copyright © 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
 
-DCN20 = dcn20_mpc.o dcn20_mmhubbub.o \
+DCN20 = dcn20_mpc.o \
dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
 
 AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20))
diff --git a/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile 
b/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile
index 505bc0517e08..eab196c57c6c 100644
--- a/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/mmhubbub/Makefile
@@ -24,6 +24,15 @@
 #
 
 ifdef CONFIG_DRM_AMD_DC_FP
+###
+# DCN20
+###
+MMHUBBUB_DCN20 = dcn20_mmhubbub.o
+
+AMD_DAL_MMHUBBUB_DCN20 = $(addprefix 
$(AMDDALPATH)/dc/mmhubbub/dcn20/,$(MMHUBBUB_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MMHUBBUB_DCN20)
+
 ###
 # DCN32
 ###
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c 
b/drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.c
rename to drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.h 
b/drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mmhubbub.h
rename to drivers/gpu/drm/amd/display/dc/mmhubbub/dcn20/dcn20_mmhubbub.h
-- 
2.34.1



[PATCH 22/50] drm/amd/display: Check stream before comparing them

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
amdgpu_dm can pass a null stream to dc_is_stream_unchanged. It is
necessary to check for null before dereferencing them.

This fixes 1 FORWARD_NULL issue reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index bcb5267b5a6b..83aa3d8a997a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -3241,6 +3241,8 @@ static bool are_stream_backends_same(
 bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
 {
+   if (!old_stream || !stream)
+   return false;
 
if (!are_stream_backends_same(old_stream, stream))
return false;
-- 
2.34.1



[PATCH 23/50] drm/amd/display: Deallocate DML memory if allocation fails

2024-07-10 Thread Fangzhi Zuo
From: Chris Park 

[Why]
When DC state create DML memory allocation fails, memory is not
deallocated subsequently, resulting in uninitialized structure
that is not NULL.

[How]
Deallocate memory if DML memory allocation fails.

Reviewed-by: Joshua Aberback 
Signed-off-by: Jerry Zuo 
Signed-off-by: Chris Park 
---
 drivers/gpu/drm/amd/display/dc/core/dc_state.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
index e990346e51f6..665157f8d4cb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -211,10 +211,16 @@ struct dc_state *dc_state_create(struct dc *dc, struct 
dc_state_create_params *p
 #ifdef CONFIG_DRM_AMD_DC_FP
if (dc->debug.using_dml2) {
dml2_opt->use_clock_dc_limits = false;
-   dml2_create(dc, dml2_opt, &state->bw_ctx.dml2);
+   if (!dml2_create(dc, dml2_opt, &state->bw_ctx.dml2)) {
+   dc_state_release(state);
+   return NULL;
+   }
 
dml2_opt->use_clock_dc_limits = true;
-   dml2_create(dc, dml2_opt, &state->bw_ctx.dml2_dc_power_source);
+   if (!dml2_create(dc, dml2_opt, 
&state->bw_ctx.dml2_dc_power_source)) {
+   dc_state_release(state);
+   return NULL;
+   }
}
 #endif
 
-- 
2.34.1



[PATCH 21/50] drm/amd/display: Check null pointers before using them

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
These pointers are null checked previously in the same function,
indicating they might be null as reported by Coverity. As a result,
they need to be checked when used again.

This fixes 3 FORWARD_NULL issue reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 44a80766380f..18d6bb485cb1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7195,6 +7195,9 @@ create_validate_stream_for_sink(struct 
amdgpu_dm_connector *aconnector,
int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8;
enum dc_status dc_result = DC_OK;
 
+   if (!dm_state)
+   return NULL;
+
do {
stream = create_stream_for_sink(connector, drm_mode,
dm_state, old_stream,
@@ -9302,7 +9305,7 @@ static void amdgpu_dm_commit_streams(struct 
drm_atomic_state *state,
if (acrtc)
old_crtc_state = drm_atomic_get_old_crtc_state(state, 
&acrtc->base);
 
-   if (!acrtc->wb_enabled)
+   if (!acrtc || !acrtc->wb_enabled)
continue;
 
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
@@ -9706,9 +9709,10 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
 
DRM_INFO("[HDCP_DM] hdcp_update_display 
enable_encryption = %x\n", enable_encryption);
 
-   hdcp_update_display(
-   adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index, aconnector,
-   new_con_state->hdcp_content_type, 
enable_encryption);
+   if (aconnector->dc_link)
+   hdcp_update_display(
+   adev->dm.hdcp_workqueue, 
aconnector->dc_link->link_index, aconnector,
+   new_con_state->hdcp_content_type, 
enable_encryption);
}
}
 
-- 
2.34.1



[PATCH 20/50] drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
"dcn20_validate_apply_pipe_split_flags" dereferences merge, and thus it
cannot be a null pointer. Let's pass a valid pointer to avoid null
dereference.

This fixes 2 FORWARD_NULL issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c | 3 ++-
 drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
index 5e7cfa8e8ec9..eea2b3b307cd 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
@@ -2040,6 +2040,7 @@ bool dcn20_fast_validate_bw(
 {
bool out = false;
int split[MAX_PIPES] = { 0 };
+   bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
 
ASSERT(pipes);
@@ -2064,7 +2065,7 @@ bool dcn20_fast_validate_bw(
if (vlevel > context->bw_ctx.dml.soc.num_states)
goto validate_fail;
 
-   vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, 
split, NULL);
+   vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, 
split, merge);
 
/*initialize pipe_just_split_from to invalid idx*/
for (i = 0; i < MAX_PIPES; i++)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
index 8663cbc3d1cf..347e6aaea582 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
@@ -774,6 +774,7 @@ bool dcn21_fast_validate_bw(struct dc *dc,
 {
bool out = false;
int split[MAX_PIPES] = { 0 };
+   bool merge[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
 
ASSERT(pipes);
@@ -816,7 +817,7 @@ bool dcn21_fast_validate_bw(struct dc *dc,
goto validate_fail;
}
 
-   vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, 
split, NULL);
+   vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, 
split, merge);
 
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-- 
2.34.1



[PATCH 19/50] drm/amd/display: Check phantom_stream before it is used

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

dcn32_enable_phantom_stream can return null, so returned value
must be checked before used.

This fixes 1 NULL_RETURNS issue reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index 3ed6d1fa0c44..ee009716d39b 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1717,6 +1717,9 @@ void dcn32_add_phantom_pipes(struct dc *dc, struct 
dc_state *context,
// be a valid candidate for SubVP (i.e. has a plane, stream, doesn't
// already have phantom pipe assigned, etc.) by previous checks.
phantom_stream = dcn32_enable_phantom_stream(dc, context, pipes, 
pipe_cnt, index);
+   if (!phantom_stream)
+   return;
+
dcn32_enable_phantom_plane(dc, context, phantom_stream, index);
 
for (i = 0; i < dc->res_pool->pipe_count; i++) {
-- 
2.34.1



[PATCH 18/50] drm/amd/display: Check null-initialized variables

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
drr_timing and subvp_pipe are initialized to null and they are not
always assigned new values. It is necessary to check for null before
dereferencing.

This fixes 2 FORWARD_NULL issues reported by Coverity.

Reviewed-by: Nevenko Stupar 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 9d399c4ce957..4cb0227bdd27 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -871,8 +871,9 @@ static bool subvp_drr_schedulable(struct dc *dc, struct 
dc_state *context)
 * for VBLANK: (VACTIVE region of the SubVP pipe can fit the MALL 
prefetch, VBLANK frame time,
 * and the max of (VBLANK blanking time, MALL region)).
 */
-   if (stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 
100 * 100 &&
-   subvp_active_us - prefetch_us - stretched_drr_us - 
max_vblank_mallregion > 0)
+   if (drr_timing &&
+   stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 
100 * 100 &&
+   subvp_active_us - prefetch_us - stretched_drr_us - 
max_vblank_mallregion > 0)
schedulable = true;
 
return schedulable;
@@ -937,7 +938,7 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct 
dc_state *context)
if (!subvp_pipe && pipe_mall_type == SUBVP_MAIN)
subvp_pipe = pipe;
}
-   if (found) {
+   if (found && subvp_pipe) {
phantom_stream = dc_state_get_paired_subvp_stream(context, 
subvp_pipe->stream);
main_timing = &subvp_pipe->stream->timing;
phantom_timing = &phantom_stream->timing;
-- 
2.34.1



[PATCH 16/50] drm/amd/display: Refactoring OPP

2024-07-10 Thread Fangzhi Zuo
From: Revalla Hari Krishna 

[Why]
To refactor OPP files

[How]
Moved opp related files to specific opp folder and
updated Makefiles.

Acked-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Revalla Hari Krishna 
---
 drivers/gpu/drm/amd/display/dc/dcn10/Makefile|  1 -
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile|  2 +-
 drivers/gpu/drm/amd/display/dc/opp/Makefile  | 16 
 .../amd/display/dc/{ => opp}/dcn10/dcn10_opp.c   |  0
 .../amd/display/dc/{ => opp}/dcn10/dcn10_opp.h   |  0
 .../amd/display/dc/{ => opp}/dcn20/dcn20_opp.c   |  0
 .../amd/display/dc/{ => opp}/dcn20/dcn20_opp.h   |  0
 7 files changed, 17 insertions(+), 2 deletions(-)
 rename drivers/gpu/drm/amd/display/dc/{ => opp}/dcn10/dcn10_opp.c (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => opp}/dcn10/dcn10_opp.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => opp}/dcn20/dcn20_opp.c (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => opp}/dcn20/dcn20_opp.h (100%)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
index 9923d0d620d4..75e088b479ea 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
@@ -24,7 +24,6 @@
 
 DCN10 = dcn10_ipp.o \
dcn10_hw_sequencer_debug.o \
-   dcn10_opp.o \
dcn10_mpc.o \
dcn10_cm_common.o \
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
index b3aeabc4d605..744a6c4ac816 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: MIT
 # Copyright © 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
 
-DCN20 = dcn20_mpc.o dcn20_opp.o dcn20_mmhubbub.o \
+DCN20 = dcn20_mpc.o dcn20_mmhubbub.o \
dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o
 
 AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20))
diff --git a/drivers/gpu/drm/amd/display/dc/opp/Makefile 
b/drivers/gpu/drm/amd/display/dc/opp/Makefile
index fbfb3c3ad819..1be76754db30 100644
--- a/drivers/gpu/drm/amd/display/dc/opp/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/opp/Makefile
@@ -25,6 +25,22 @@
 
 ifdef CONFIG_DRM_AMD_DC_FP
 ###
+# DCN10
+###
+OPP_DCN10 = dcn10_opp.o
+
+AMD_DAL_OPP_DCN10 = $(addprefix $(AMDDALPATH)/dc/opp/dcn10/,$(OPP_DCN10))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_OPP_DCN10)
+###
+# DCN20
+###
+OPP_DCN20 = dcn20_opp.o
+
+AMD_DAL_OPP_DCN20 = $(addprefix $(AMDDALPATH)/dc/opp/dcn20/,$(OPP_DCN20))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_OPP_DCN20)
+###
 # DCN35
 ###
 OPP_DCN35 = dcn35_opp.o
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c 
b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
rename to drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h 
b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
rename to drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c 
b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
rename to drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h 
b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h
rename to drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h
-- 
2.34.1



[PATCH 17/50] drm/amd/display: Initialize denominators' default to 1

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

[WHAT & HOW]
Variables used as denominators and maybe not assigned to other values,
should not be 0. Change their default to 1 so they are never 0.

This fixes 10 DIVIDE_BY_ZERO issues reported by Coverity.

Reviewed-by: Harry Wentland 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c | 2 +-
 drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c | 2 +-
 .../display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c| 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 7c56ad0f8812..e7019c95ba79 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib 
*mode_lib,
 
 static unsigned int get_bytes_per_element(enum source_format_class 
source_format, bool is_chroma)
 {
-   unsigned int ret_val = 0;
+   unsigned int ret_val = 1;
 
if (source_format == dm_444_16) {
if (!is_chroma)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c 
b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
index dae13f202220..d8bfc85e5dcd 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
@@ -39,7 +39,7 @@
 
 static unsigned int get_bytes_per_element(enum source_format_class 
source_format, bool is_chroma)
 {
-   unsigned int ret_val = 0;
+   unsigned int ret_val = 1;
 
if (source_format == dm_444_16) {
if (!is_chroma)
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c
index 81f0a6f19f87..679b20031903 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared.c
@@ -9386,8 +9386,8 @@ static void CalculateVMGroupAndRequestTimes(
double TimePerVMRequestVBlank[],
double TimePerVMRequestFlip[])
 {
-   unsigned int num_group_per_lower_vm_stage = 0;
-   unsigned int num_req_per_lower_vm_stage = 0;
+   unsigned int num_group_per_lower_vm_stage = 1;
+   unsigned int num_req_per_lower_vm_stage = 1;
 
 #ifdef __DML_VBA_DEBUG__
dml2_printf("DML::%s: NumberOfActiveSurfaces = %u\n", __func__, 
NumberOfActiveSurfaces);
-- 
2.34.1



[PATCH 15/50] drm/amd/display: Fix DP-DVI dongle hotplug

2024-07-10 Thread Fangzhi Zuo
From: Gabe Teeger 

[why]
Hotplugging with a DVI-DP dongle on pre-rdna embedded platform
working about half the time. The regression was found to be the
setting of link->type here.
[what]
Reverts feb0593 besides the logging added.

Reviewed-by: Wenjing Liu 
Signed-off-by: Jerry Zuo 
Signed-off-by: Gabe Teeger 
---
 drivers/gpu/drm/amd/display/dc/link/link_detection.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c 
b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index bba644024780..391dbe81534d 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -863,7 +863,6 @@ static bool detect_link_and_local_sink(struct dc_link *link,
struct dc_sink *prev_sink = NULL;
struct dpcd_caps prev_dpcd_caps;
enum dc_connection_type new_connection_type = dc_connection_none;
-   enum dc_connection_type pre_connection_type = link->type;
const uint32_t post_oui_delay = 30; // 30ms
 
DC_LOGGER_INIT(link->ctx->logger);
@@ -965,7 +964,6 @@ static bool detect_link_and_local_sink(struct dc_link *link,
}
 
if (!detect_dp(link, &sink_caps, reason)) {
-   link->type = pre_connection_type;
 
if (prev_sink)
dc_sink_release(prev_sink);
@@ -1299,8 +1297,7 @@ bool link_detect(struct dc_link *link, enum 
dc_detect_reason reason)
link->dpcd_caps.is_mst_capable)
is_delegated_to_mst_top_mgr = discover_dp_mst_topology(link, 
reason);
 
-   if (is_local_sink_detect_success &&
-   pre_link_type == dc_connection_mst_branch &&
+   if (pre_link_type == dc_connection_mst_branch &&
link->type != dc_connection_mst_branch)
is_delegated_to_mst_top_mgr = 
link_reset_cur_dp_mst_topology(link);
 
-- 
2.34.1



[PATCH 11/50] drm/amd/display: avoid disable otg when dig was disabled

2024-07-10 Thread Fangzhi Zuo
From: Jingwen Zhu 

[Why]
This is a workaround for an dcn3.1 hang that happens if otg dispclk
is ramped while otg is on and stream enc is off.
But this w/a should not trigger when we have a dig active.

[How]
Avoid disable otg when dig FE/BE FIFO was not switched.

Acked-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Jingwen Zhu 
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c   | 18 +++---
 .../dc/dio/dcn35/dcn35_dio_stream_encoder.c|  9 +
 .../drm/amd/display/dc/inc/hw/stream_encoder.h |  1 +
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 70ee0089a20d..248d22b23a6d 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -120,7 +120,6 @@ static int dcn35_get_active_display_cnt_wa(
 
return display_count;
 }
-
 static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state 
*context,
bool safe_to_lower, bool disable)
 {
@@ -128,14 +127,27 @@ static void dcn35_disable_otg_wa(struct clk_mgr 
*clk_mgr_base, struct dc_state *
int i;
 
for (i = 0; i < dc->res_pool->pipe_count; ++i) {
+   struct pipe_ctx *old_pipe = 
&dc->current_state->res_ctx.pipe_ctx[i];
+   struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *pipe = safe_to_lower
? &context->res_ctx.pipe_ctx[i]
: &dc->current_state->res_ctx.pipe_ctx[i];
-
+   bool stream_changed_otg_dig_on = false;
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
+   stream_changed_otg_dig_on = old_pipe->stream && 
new_pipe->stream &&
+   old_pipe->stream != new_pipe->stream &&
+   old_pipe->stream_res.tg == new_pipe->stream_res.tg &&
+   new_pipe->stream->link_enc && !new_pipe->stream->dpms_off &&
+   new_pipe->stream->link->link_enc->funcs->is_dig_enabled &&
+   new_pipe->stream->link->link_enc->funcs->is_dig_enabled(
+   new_pipe->stream->link->link_enc) &&
+   new_pipe->stream_res.stream_enc &&
+   new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled &&
+   
new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled(new_pipe->stream_res.stream_enc);
if (pipe->stream && (pipe->stream->dpms_off || 
dc_is_virtual_signal(pipe->stream->signal) ||
-!pipe->stream->link_enc)) {
+   !pipe->stream->link_enc) && !stream_changed_otg_dig_on) 
{
+   /* This w/a should not trigger when we have a dig 
active */
if (disable) {
if (pipe->stream_res.tg && 
pipe->stream_res.tg->funcs->disable_crtc)

pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
diff --git 
a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
index 6a179e5ab417..fcc88ef83e6a 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_stream_encoder.c
@@ -392,6 +392,14 @@ static void enc35_reset_fifo(struct stream_encoder *enc, 
bool reset)
udelay(10);
 }
 
+static bool enc35_is_fifo_enabled(struct stream_encoder *enc)
+{
+   struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+   uint32_t reset_val;
+
+   REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &reset_val);
+   return (reset_val == 0) ? false : true;
+}
 void enc35_disable_fifo(struct stream_encoder *enc)
 {
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
@@ -465,6 +473,7 @@ static const struct stream_encoder_funcs 
dcn35_str_enc_funcs = {
.set_input_mode = enc314_set_dig_input_mode,
.enable_fifo = enc35_enable_fifo,
.disable_fifo = enc35_disable_fifo,
+   .is_fifo_enabled = enc35_is_fifo_enabled,
.map_stream_to_link = enc35_stream_encoder_map_to_link,
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
index e5e11c84e9e2..6fe42120738d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
@@ -271,6 +271,7 @@ struct stream_encoder_funcs {
struct stream_encoder *enc, unsigned int pix_per_container);
void (*enable_fifo)(struct stream_encoder *enc);
void (*disable_fifo)(struct stream_encoder *enc);
+   bool (*is_fifo_enabled)(struct stream_encoder *enc);
void (*map_stream_to_link)(struct stream_encoder 

[PATCH 14/50] drm/amd/display: Disable subvp based on HW cursor requirement

2024-07-10 Thread Fangzhi Zuo
From: Alvin Lee 

[Description]
- There are situations where HW cursor is required
- In these scenarios we should disable subvp based on the HW cursor
  requirement

Reviewed-by: Dillon Varone 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c   | 7 +++
 drivers/gpu/drm/amd/display/dc/dc_stream.h | 3 +++
 .../amd/display/dc/dml2/dml21/dml21_translation_helper.c   | 2 +-
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index c35029c65223..9897e322e2d5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2717,6 +2717,10 @@ static enum surface_update_type 
check_update_surfaces_for_stream(
overall_type = UPDATE_TYPE_FULL;
}
 
+   if (stream_update && stream_update->hw_cursor_req) {
+   overall_type = UPDATE_TYPE_FULL;
+   }
+
/* some stream updates require passive update */
if (stream_update) {
union stream_update_flags *su_flags = 
&stream_update->stream->update_flags;
@@ -3012,6 +3016,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
if (update->vrr_infopacket)
stream->vrr_infopacket = *update->vrr_infopacket;
 
+   if (update->hw_cursor_req)
+   stream->hw_cursor_req = *update->hw_cursor_req;
+
if (update->allow_freesync)
stream->allow_freesync = *update->allow_freesync;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h 
b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 3d9ee4da7056..de9bd72ca514 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -266,6 +266,8 @@ struct dc_stream_state {
 
struct dc_cursor_attributes cursor_attributes;
struct dc_cursor_position cursor_position;
+   bool hw_cursor_req;
+
uint32_t sdr_white_level; // for boosting (SDR) cursor in HDR mode
 
/* from stream struct */
@@ -350,6 +352,7 @@ struct dc_stream_update {
 
struct dc_cursor_attributes *cursor_attributes;
struct dc_cursor_position *cursor_position;
+   bool *hw_cursor_req;
 };
 
 bool dc_is_stream_unchanged(
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
index 7c73efe19525..405544920f3b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
@@ -516,7 +516,7 @@ static void 
populate_dml21_stream_overrides_from_stream_state(
if (!stream->ctx->dc->debug.enable_single_display_2to1_odm_policy ||
stream->debug.force_odm_combine_segments > 0)
stream_desc->overrides.disable_dynamic_odm = true;
-   stream_desc->overrides.disable_subvp = 
stream->ctx->dc->debug.force_disable_subvp;
+   stream_desc->overrides.disable_subvp = 
stream->ctx->dc->debug.force_disable_subvp || stream->hw_cursor_req;
 }
 
 static enum dml2_swizzle_mode gfx_addr3_to_dml2_swizzle_mode(enum 
swizzle_mode_addr3_values addr3_mode)
-- 
2.34.1



[PATCH 13/50] drm/amd/display: When resync fifo ensure to use correct pipe ctx

2024-07-10 Thread Fangzhi Zuo
From: Alvin Lee 

We resync the FIFO after each pipe update in apply_ctx_to_hw.
However, this means that some pipes (in hardware) are based on the
new context and some are based on the current_state (since the pipes
are updated on at a time). In this case we must ensure to use the
pipe_ctx that's currently still configured in hardware when turning
off / on OTG's and reconfiguring ODM during the resync.

Reviewed-by: Nicholas Kazlauskas 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alvin Lee 
---
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  2 +-
 .../amd/display/dc/hwss/dcn314/dcn314_hwseq.c | 13 +---
 .../amd/display/dc/hwss/dcn314/dcn314_hwseq.h |  2 +-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   | 20 ++-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.h   |  2 +-
 .../display/dc/hwss/hw_sequencer_private.h|  3 ++-
 6 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 51c5195f8325..982b2d5bfb5f 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -2443,7 +2443,7 @@ enum dc_status dce110_apply_ctx_to_hw(
 
 #ifdef CONFIG_DRM_AMD_DC_FP
if (hws->funcs.resync_fifo_dccg_dio)
-   hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
+   hws->funcs.resync_fifo_dccg_dio(hws, dc, context, i);
 #endif
}
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
index 388404cdeeaa..4e93eeedfc1b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
@@ -355,14 +355,18 @@ void dcn314_calculate_pix_rate_divider(
}
 }
 
-void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct 
dc_state *context)
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct 
dc_state *context, unsigned int current_pipe_idx)
 {
unsigned int i;
struct pipe_ctx *pipe = NULL;
bool otg_disabled[MAX_PIPES] = {false};
 
for (i = 0; i < dc->res_pool->pipe_count; i++) {
-   pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+   if (i <= current_pipe_idx) {
+   pipe = &context->res_ctx.pipe_ctx[i];
+   } else {
+   pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+   }
 
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
@@ -377,7 +381,10 @@ void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, 
struct dc *dc, struct dc

hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
 
for (i = 0; i < dc->res_pool->pipe_count; i++) {
-   pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+   if (i <= current_pipe_idx)
+   pipe = &context->res_ctx.pipe_ctx[i];
+   else
+   pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 
if (otg_disabled[i]) {
int opp_inst[MAX_PIPES] = { pipe->stream_res.opp->inst 
};
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
index fb4f90f61b22..2305ad282f21 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.h
@@ -41,7 +41,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct 
pipe_ctx *pipe_ctx, unsig
 
 void dcn314_calculate_pix_rate_divider(struct dc *dc, struct dc_state 
*context, const struct dc_stream_state *stream);
 
-void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct 
dc_state *context);
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct 
dc_state *context, unsigned int current_pipe_idx);
 
 void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int 
dpp_inst, bool clock_on);
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index 4534843ba66a..7f41eccefe02 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -1201,20 +1201,27 @@ void dcn32_calculate_pix_rate_divider(
}
 }
 
-void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct 
dc_state *context)
+void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct 
dc_state *context, unsigned int current_pipe_idx)
 {
unsigned int i;
struct pipe_ctx *pipe = NULL;
bool otg_disabled[MAX_PIPES] = {false};
+   struct dc_state *dc_state = NULL;
 
for (i = 0; i < dc->res_pool->pipe_count; i+

[PATCH 12/50] drm/amd/display: Add option to allow transition when odm is forced

2024-07-10 Thread Fangzhi Zuo
From: Sridevi Arvindekar 

Added option to allow transition for forced odm.
Add the variation to the nightly run.

Reviewed-by: Wenjing Liu 
Signed-off-by: Jerry Zuo 
Signed-off-by: Sridevi Arvindekar 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c   | 3 ++-
 drivers/gpu/drm/amd/display/dc/dc_stream.h | 6 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 387b392f4c0d..c35029c65223 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4338,7 +4338,8 @@ static void 
backup_and_set_minimal_pipe_split_policy(struct dc *dc,
dc->debug.force_disable_subvp = true;
for (i = 0; i < context->stream_count; i++) {
policy->force_odm[i] = 
context->streams[i]->debug.force_odm_combine_segments;
-   context->streams[i]->debug.force_odm_combine_segments = 0;
+   if (context->streams[i]->debug.allow_transition_for_forced_odm)
+   context->streams[i]->debug.force_odm_combine_segments = 
0;
}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h 
b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 8ebd7e9e776e..3d9ee4da7056 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -159,6 +159,12 @@ struct test_pattern {
 
 struct dc_stream_debug_options {
char force_odm_combine_segments;
+   /*
+* When force_odm_combine_segments is non zero, allow dc to
+* temporarily transition to ODM bypass when minimal transition state
+* is required to prevent visual glitches showing on the screen
+*/
+   char allow_transition_for_forced_odm;
 };
 
 #define LUMINANCE_DATA_TABLE_SIZE 10
-- 
2.34.1



[PATCH 10/50] drm/amd/display: Implement bias and scale pre scl

2024-07-10 Thread Fangzhi Zuo
From: Relja Vojvodic 

why:
New scaler needs the input to be full range color space. This will also fix
issues that come up due to not having a predefined limited color space matrix
for certain color spaces

how:
Use bias and scale HW to expand the range of limited color spaces to full
before the scaler

Reviewed-by: Krunoslav Kovac 
Signed-off-by: Jerry Zuo 
Signed-off-by: Relja Vojvodic 
---
 .../drm/amd/display/dc/core/dc_hw_sequencer.c |  6 ++---
 drivers/gpu/drm/amd/display/dc/dc.h   |  2 +-
 .../drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c  | 27 ++-
 .../drm/amd/display/dc/dpp/dcn35/dcn35_dpp.h  |  3 +++
 .../amd/display/dc/dpp/dcn401/dcn401_dpp.c|  3 ++-
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  3 +--
 .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 13 -
 7 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 87e36d51c56d..9e42a0128baa 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -901,12 +901,12 @@ void hwss_program_bias_and_scale(union 
block_sequence_params *params)
struct pipe_ctx *pipe_ctx = 
params->program_bias_and_scale_params.pipe_ctx;
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-   struct dc_bias_and_scale bns_params = {0};
+   struct dc_bias_and_scale bns_params = plane_state->bias_and_scale;
 
//TODO :for CNVC set scale and bias registers if necessary
-   build_prescale_params(&bns_params, plane_state);
-   if (dpp->funcs->dpp_program_bias_and_scale)
+   if (dpp->funcs->dpp_program_bias_and_scale) {
dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params);
+   }
 }
 
 void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 4c9bb913125d..83fe13f5a367 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1292,7 +1292,7 @@ struct dc_plane_state {
 
struct dc_gamma gamma_correction;
struct dc_transfer_func in_transfer_func;
-   struct dc_bias_and_scale *bias_and_scale;
+   struct dc_bias_and_scale bias_and_scale;
struct dc_csc_transform input_csc_color_matrix;
struct fixed31_32 coeff_reduction_factor;
struct fixed31_32 hdr_mult;
diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c 
b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c
index e16274fee31d..8473c694bfdc 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c
@@ -59,6 +59,31 @@ void dpp35_dppclk_control(
DISPCLK_R_GATE_DISABLE, 0);
 }
 
+void dpp35_program_bias_and_scale_fcnv(
+   struct dpp *dpp_base,
+   struct dc_bias_and_scale *params)
+{
+   struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
+
+   if (!params->bias_and_scale_valid) {
+   REG_SET(FCNV_FP_BIAS_R, 0, FCNV_FP_BIAS_R, 0);
+   REG_SET(FCNV_FP_BIAS_G, 0, FCNV_FP_BIAS_G, 0);
+   REG_SET(FCNV_FP_BIAS_B, 0, FCNV_FP_BIAS_B, 0);
+
+   REG_SET(FCNV_FP_SCALE_R, 0, FCNV_FP_SCALE_R, 0x1F000);
+   REG_SET(FCNV_FP_SCALE_G, 0, FCNV_FP_SCALE_G, 0x1F000);
+   REG_SET(FCNV_FP_SCALE_B, 0, FCNV_FP_SCALE_B, 0x1F000);
+   } else {
+   REG_SET(FCNV_FP_BIAS_R, 0, FCNV_FP_BIAS_R, params->bias_red);
+   REG_SET(FCNV_FP_BIAS_G, 0, FCNV_FP_BIAS_G, params->bias_green);
+   REG_SET(FCNV_FP_BIAS_B, 0, FCNV_FP_BIAS_B, params->bias_blue);
+
+   REG_SET(FCNV_FP_SCALE_R, 0, FCNV_FP_SCALE_R, params->scale_red);
+   REG_SET(FCNV_FP_SCALE_G, 0, FCNV_FP_SCALE_G, 
params->scale_green);
+   REG_SET(FCNV_FP_SCALE_B, 0, FCNV_FP_SCALE_B, 
params->scale_blue);
+   }
+}
+
 static struct dpp_funcs dcn35_dpp_funcs = {
.dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
.dpp_read_state = dpp30_read_state,
@@ -81,7 +106,7 @@ static struct dpp_funcs dcn35_dpp_funcs = {
.dpp_program_shaper_lut = NULL, // CM SHAPER block is removed 
in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
.dpp_program_3dlut  = NULL, // CM 3DLUT block is 
removed in DCN3.2 DPP, (it is in MPCC, programmable before or after BLND)
 
-   .dpp_program_bias_and_scale = NULL,
+   .dpp_program_bias_and_scale = dpp35_program_bias_and_scale_fcnv,
.dpp_cnv_set_alpha_keyer= dpp2_cnv_set_alpha_keyer,
.set_cursor_attributes  = dpp3_set_cursor_attributes,
.set_cursor_position= dpp1_set_cursor_position,
diff --git a/drivers/gpu/drm/amd/displ

[PATCH 08/50] drm/amd/display: fix dscclk programming sequence on DCN401

2024-07-10 Thread Fangzhi Zuo
From: Wenjing Liu 

[why]
The mux to switch between refclk and dto_dsc_clk is non double buffered.
However dto dsc clk's phase and modulo divider registers are currently
configured as double buffered update. This causes a problem when we switch to
use dto dsc clk and program phase and modulo in the same sequence. In this
sequence dsc clk is switched to dto but the clock divider programming doesn't
take effect until next frame. When we try to program DSCC registers, SMN bus
will hang because dto dsc clk divider phase is set to 0.

[how]
Configure phase and modulo to take effect immediately. Always switch to dto dsc
clk before DSC clock is unagted. Switch back to refclk after DSC clock is gated.

Acked-by: Rodrigo Siqueira 
Reviewed-by: Jerry Zuo 
Signed-off-by: Wenjing Liu 
---
 .../amd/display/dc/dccg/dcn20/dcn20_dccg.h|  6 +--
 .../amd/display/dc/dccg/dcn401/dcn401_dccg.c  | 32 ++-
 .../amd/display/dc/dccg/dcn401/dcn401_dccg.h  |  4 --
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  2 +-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   | 21 +++---
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c |  6 +--
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |  5 +--
 .../gpu/drm/amd/display/dc/link/link_dpms.c   | 41 ---
 8 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h 
b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
index 1e0292861244..6ac2bd86c4db 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
@@ -346,11 +346,7 @@
type SYMCLK32_LE3_SRC_SEL;\
type SYMCLK32_LE2_EN;\
type SYMCLK32_LE3_EN;\
-   type DP_DTO_ENABLE[MAX_PIPES];\
-   type DSCCLK0_DTO_DB_EN;\
-   type DSCCLK1_DTO_DB_EN;\
-   type DSCCLK2_DTO_DB_EN;\
-   type DSCCLK3_DTO_DB_EN;
+   type DP_DTO_ENABLE[MAX_PIPES];
 
 struct dccg_shift {
DCCG_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
index 07f1f396ba52..0b889004509a 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
@@ -730,35 +730,35 @@ void dccg401_init(struct dccg *dccg)
}
 }
 
-static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst, bool 
enable)
+static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst)
 {
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
-   uint32_t phase = enable ? 1 : 0;
 
switch (inst) {
case 0:
-   REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK0_EN, 1, DSCCLK0_DTO_DB_EN, 
1);
REG_UPDATE_2(DSCCLK0_DTO_PARAM,
-   DSCCLK0_DTO_PHASE, phase,
+   DSCCLK0_DTO_PHASE, 1,
DSCCLK0_DTO_MODULO, 1);
+   REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 1);
+
break;
case 1:
-   REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1, DSCCLK1_DTO_DB_EN, 
1);
REG_UPDATE_2(DSCCLK1_DTO_PARAM,
-   DSCCLK1_DTO_PHASE, phase,
+   DSCCLK1_DTO_PHASE, 1,
DSCCLK1_DTO_MODULO, 1);
+   REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1);
break;
case 2:
-   REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1, DSCCLK2_DTO_DB_EN, 
1);
REG_UPDATE_2(DSCCLK2_DTO_PARAM,
-   DSCCLK2_DTO_PHASE, phase,
+   DSCCLK2_DTO_PHASE, 1,
DSCCLK2_DTO_MODULO, 1);
+   REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1);
break;
case 3:
-   REG_UPDATE_2(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1, DSCCLK3_DTO_DB_EN, 
1);
REG_UPDATE_2(DSCCLK3_DTO_PARAM,
-   DSCCLK3_DTO_PHASE, phase,
+   DSCCLK3_DTO_PHASE, 1,
DSCCLK3_DTO_MODULO, 1);
+   REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1);
break;
default:
BREAK_TO_DEBUGGER();
@@ -774,15 +774,27 @@ static void dccg401_set_ref_dscclk(struct dccg *dccg,
switch (dsc_inst) {
case 0:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 0);
+   REG_UPDATE_2(DSCCLK0_DTO_PARAM,
+   DSCCLK0_DTO_PHASE, 0,
+   DSCCLK0_DTO_MODULO, 0);
break;
case 1:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 0);
+   REG_UPDATE_2(DSCCLK1_DTO_PARAM,
+   DSCCLK1_DTO_PHASE, 0,
+   DSCCLK1_DTO_MODULO, 0);
break;
case 2:
REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 0);
+

[PATCH 09/50] drm/amd/display: apply vmin optimization even if it doesn't reach vmin level

2024-07-10 Thread Fangzhi Zuo
From: Wenjing Liu 

[why]
Based on power measurement result, in most cases when display clock is higher
than Vmin display clock, lowering display clock using dynamic ODM will improve
overall power consumption by 0 to 4 watts even if we can't reach Vmin.

[how]
Allow vmin optimization applied even if dispclk can't reach Vmin.

Reviewed-by: Jun Lei 
Signed-off-by: Jerry Zuo 
Signed-off-by: Wenjing Liu 
---
 .../dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c  | 14 +-
 .../display/dc/dml2/dml21/src/dml2_top/dml_top.c   | 13 +++--
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
index 603036df68ba..60a9faf81d3d 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
@@ -591,6 +591,8 @@ bool pmo_dcn4_fams2_init_for_vmin(struct 
dml2_pmo_init_for_vmin_in_out *in_out)
&in_out->base_display_config->display_config;
const struct dml2_core_mode_support_result *mode_support_result =
&in_out->base_display_config->mode_support_result;
+   struct dml2_optimization_stage4_state *state =
+   &in_out->base_display_config->stage4;
 
if (in_out->instance->options->disable_dyn_odm ||

(in_out->instance->options->disable_dyn_odm_for_multi_stream && 
display_config->num_streams > 1))
@@ -611,28 +613,30 @@ bool pmo_dcn4_fams2_init_for_vmin(struct 
dml2_pmo_init_for_vmin_in_out *in_out)
 */
if 
(mode_support_result->cfg_support_info.plane_support_info[i].dpps_used > 1 &&

mode_support_result->cfg_support_info.stream_support_info[display_config->plane_descriptors[i].stream_index].odms_used
 == 1)
-   
in_out->base_display_config->stage4.unoptimizable_streams[display_config->plane_descriptors[i].stream_index]
 = true;
+   
state->unoptimizable_streams[display_config->plane_descriptors[i].stream_index] 
= true;
 
for (i = 0; i < display_config->num_streams; i++) {
if 
(display_config->stream_descriptors[i].overrides.disable_dynamic_odm)
-   
in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+   state->unoptimizable_streams[i] = true;
else if 
(in_out->base_display_config->stage3.stream_svp_meta[i].valid &&

in_out->instance->options->disable_dyn_odm_for_stream_with_svp)
-   
in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+   state->unoptimizable_streams[i] = true;
/*
 * ODM Combine requires horizontal timing divisible by 2 so each
 * ODM segment has the same size.
 */
else if 
(!is_h_timing_divisible_by(&display_config->stream_descriptors[i].timing, 2))
-   
in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+   state->unoptimizable_streams[i] = true;
/*
 * Our hardware support seamless ODM transitions for DP encoders
 * only.
 */
else if 
(!is_dp_encoder(display_config->stream_descriptors[i].output.output_encoder))
-   
in_out->base_display_config->stage4.unoptimizable_streams[i] = true;
+   state->unoptimizable_streams[i] = true;
}
 
+   state->performed = true;
+
return true;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
index 2fb3e2f45e07..b25e9230adea 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
@@ -268,9 +268,18 @@ bool dml2_build_mode_programming(struct 
dml2_build_mode_programming_in_out *in_o
 
vmin_success = 
dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, 
&l->vmin_phase);
 
-   if (vmin_success) {
+   if (l->optimized_display_config_with_meta.stage4.performed) {
+   /*
+* when performed is true, optimization has applied to
+* optimized_display_config_with_meta and it has passed mode
+* support. However it may or may not pass the test function to
+* reach actual Vmin. As long as voltage is optimized even if it
+* doesn't reach Vmin level, there is still power benefit so in
+* this case we will still copy this optimization into base
+* display config.
+*/

[PATCH 07/50] drm/amd/display: Revert "Check HDCP returned status"

2024-07-10 Thread Fangzhi Zuo
From: Alex Hung 

This reverts commit d788be646098e6f4fc26763a213bd4fb94a04e13 due to a
power consumption regression.

Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alex Hung 
---
 .../amd/display/modules/hdcp/hdcp1_execution.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
index 1e495e884484..8bc377560787 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
@@ -432,18 +432,18 @@ static enum mod_hdcp_status authenticated_dp(struct 
mod_hdcp *hdcp,
goto out;
}
 
-   if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
+   mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
&input->bstatus_read, &status,
-   hdcp, "bstatus_read"))
-   goto out;
-   if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
+   hdcp, "bstatus_read");
+
+   mod_hdcp_execute_and_set(check_link_integrity_dp,
&input->link_integrity_check, &status,
-   hdcp, "link_integrity_check"))
-   goto out;
-   if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
+   hdcp, "link_integrity_check");
+
+   mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
&input->reauth_request_check, &status,
-   hdcp, "reauth_request_check"))
-   goto out;
+   hdcp, "reauth_request_check");
+
 out:
return status;
 }
-- 
2.34.1



[PATCH 06/50] drm/amd/display: Replace assert with error message in dp_retrieve_lttpr_cap()

2024-07-10 Thread Fangzhi Zuo
From: Roman Li 

[Why]
When assert in dp_retrieve_lttpr_cap() is hit, dmesg has traces like:

 RIP: 0010:dp_retrieve_lttpr_cap+0xcc/0x1a0 [amdgpu]
 Call Trace:
 
  dp_retrieve_lttpr_cap+0xcc/0x1a0 [amdgpu]
  report_bug+0x1e8/0x240
  handle_bug+0x46/0x80
  link_detect+0x35/0x580 [amdgpu]

It happens when LTTPRs fail to increment dpcd repeater count.
We have a recovery action in place for such cases.
Assert is misleading, an indicative error in dmesg is more useful.

[How]
Remove ASSERT and use DC_LOG_ERROR instead.

Reviewed-by: Michael Strauss 
Signed-off-by: Jerry Zuo 
Signed-off-by: Roman Li 
---
 .../drm/amd/display/dc/link/protocols/link_dp_capability.c  | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index 46bb7a855bc2..c257e733044a 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -1541,7 +1541,11 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link 
*link)
 * Override count to 1 if we receive a known bad count (0 or an invalid 
value) */
if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&

(dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == 
0)) {
-   ASSERT(0);
+   /* If you see this message consistently, either the host 
platform has FIXED_VS flag
+* incorrectly configured or the sink device is returning an 
invalid count.
+*/
+   DC_LOG_ERROR("lttpr_caps phy_repeater_cnt is 0x%x, forcing it 
to 0x80.",
+link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
link->dpcd_caps.lttpr_caps.phy_repeater_cnt = 0x80;
DC_LOG_DC("lttpr_caps forced phy_repeater_cnt = %d\n", 
link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
}
-- 
2.34.1



[PATCH 04/50] drm/amd/display: Don't consider cursor for no plane case in DML1

2024-07-10 Thread Fangzhi Zuo
From: Alvin Lee 

[Description]
For no plane scenarios we should not consider cursor as there cannot
be any cursor if  there's no planes. This fixes an issue where
dc_commit_streams fails due to prefetch bandwidth requirements
(the display config + dummy planes + cursor causes the prefetch
bandwidth to exceed what is possible).

Reviewed-by: Chaitanya Dhere 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
index 8a8efe408a9d..efe337ebf7c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
@@ -1562,6 +1562,8 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc,
pipes[pipe_cnt].pipe.src.surface_width_c = 
pipes[pipe_cnt].pipe.src.viewport_width;
pipes[pipe_cnt].pipe.src.data_pitch = 
((pipes[pipe_cnt].pipe.src.viewport_width + 255) / 256) * 256;
pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
+   pipes[pipe_cnt].pipe.src.cur0_src_width = 0;
+   pipes[pipe_cnt].pipe.src.cur1_src_width = 0;
pipes[pipe_cnt].pipe.dest.recout_width = 
pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
pipes[pipe_cnt].pipe.dest.recout_height = 
pipes[pipe_cnt].pipe.src.viewport_height; /*vp_height/vratio*/
pipes[pipe_cnt].pipe.dest.full_recout_width = 
pipes[pipe_cnt].pipe.dest.recout_width;  /*when is_hsplit != 1*/
-- 
2.34.1



[PATCH 02/50] drm/amd/display: Disable HBR audio for DP2 for certain ASICs

2024-07-10 Thread Fangzhi Zuo
From: Alvin Lee 

[Description]
Due to a HW bug, HBR audio is not supported for
DP2 encoders for certain ASICs.

Reviewed-by: Alvin Lee 
Signed-off-by: Jerry Zuo 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 1 +
 drivers/gpu/drm/amd/display/dc/dce/dce_audio.c  | 6 ++
 drivers/gpu/drm/amd/display/dc/dce/dce_audio.h  | 1 +
 drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c   | 5 +
 drivers/gpu/drm/amd/display/dc/inc/hw/audio.h   | 2 ++
 .../gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c  | 1 +
 .../gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c  | 1 +
 .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c| 1 +
 .../gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c  | 1 +
 9 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 73cdebcd9f37..4c9bb913125d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -466,6 +466,7 @@ struct dc_config {
bool use_assr_psp_message;
bool support_edp0_on_dp1;
unsigned int enable_fpo_flicker_detection;
+   bool disable_hbr_audio_dp2;
 };
 
 enum visual_confirm {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index cf5f84fb9c69..eeed840073fe 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -630,6 +630,11 @@ void dce_aud_az_enable(struct audio *audio)
audio->inst, value);
 }
 
+void dce_aud_az_disable_hbr_audio(struct audio *audio)
+{
+   set_high_bit_rate_capable(audio, false);
+}
+
 void dce_aud_az_disable(struct audio *audio)
 {
uint32_t value;
@@ -1293,6 +1298,7 @@ static const struct audio_funcs funcs = {
.az_enable = dce_aud_az_enable,
.az_disable = dce_aud_az_disable,
.az_configure = dce_aud_az_configure,
+   .az_disable_hbr_audio = dce_aud_az_disable_hbr_audio,
.destroy = dce_aud_destroy,
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h 
b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
index 539f881928d1..1b7b8b079af4 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h
@@ -166,6 +166,7 @@ void dce_aud_hw_init(struct audio *audio);
 
 void dce_aud_az_enable(struct audio *audio);
 void dce_aud_az_disable(struct audio *audio);
+void dce_aud_az_disable_hbr_audio(struct audio *audio);
 
 void dce_aud_az_configure(struct audio *audio,
enum signal_type signal,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 1f2eb2f727dc..51c5195f8325 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -1597,6 +1597,11 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
&audio_output.crtc_info,
&pipe_ctx->stream->audio_info,
&audio_output.dp_link_info);
+
+   if (dc->config.disable_hbr_audio_dp2)
+   if 
(pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio &&
+   
dc->link_srv->dp_is_128b_132b_signal(pipe_ctx))
+   
pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio(pipe_ctx->stream_res.audio);
}
 
/* make sure no pipes syncd to the pipe being enabled */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
index b6203253111c..8c18efc2aa70 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/audio.h
@@ -46,6 +46,8 @@ struct audio_funcs {
const struct audio_info *audio_info,
const struct audio_dp_link_info *dp_link_info);
 
+   void (*az_disable_hbr_audio)(struct audio *audio);
+
void (*wall_dto_setup)(struct audio *audio,
enum signal_type signal,
const struct audio_crtc_info *crtc_info,
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
index 5d1801dce273..ac8cb20e2e3b 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -1948,6 +1948,7 @@ static bool dcn31_resource_construct(
 
/* Use pipe context based otg sync logic */
dc->config.use_pipe_ctx_sync_logic = true;
+   dc->config.disable_hbr_audio_dp2 = true;
 
/* read VBIOS LTTPR caps */
{
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn

[PATCH 05/50] drm/amd/display: Added logging for automated DPM testing

2024-07-10 Thread Fangzhi Zuo
From: Ryan Seto 

[Why]
Added clock logs to automate DPM testing

[How]
Added logs and helper functions to output clocks

Co-authored-by: Ryan Seto 
Reviewed-by: Alvin Lee 
Signed-off-by: Jerry Zuo 
Signed-off-by: Ryan Seto 
---
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c| 250 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c  |   9 +-
 .../dc/dml2/dml21/dml21_translation_helper.c  |  27 ++
 .../dc/dml2/dml21/dml21_translation_helper.h  |   1 +
 .../amd/display/dc/dml2/dml21/dml21_utils.c   |   2 +
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |   1 +
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |   4 +-
 7 files changed, 237 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 45fe17a46890..c453c5f15ce7 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -14,6 +14,7 @@
 #include "core_types.h"
 #include "dm_helpers.h"
 #include "link.h"
+#include "dc_state_priv.h"
 #include "atomfirmware.h"
 
 #include "dcn401_smu14_driver_if.h"
@@ -29,6 +30,7 @@
 #define mmCLK01_CLK0_CLK2_DFS_CNTL  0x16E6F
 #define mmCLK01_CLK0_CLK3_DFS_CNTL  0x16E72
 #define mmCLK01_CLK0_CLK4_DFS_CNTL  0x16E75
+#define mmCLK20_CLK2_CLK2_DFS_CNTL  0x1B051
 
 #define CLK0_CLK_PLL_REQ__FbMult_int_MASK  0x01ffUL
 #define CLK0_CLK_PLL_REQ__PllSpineDiv_MASK 0xf000UL
@@ -302,6 +304,197 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base)
dcn401_build_wm_range_table(clk_mgr_base);
 }
 
+static void dcn401_dump_clk_registers(struct clk_state_registers_and_bypass 
*regs_and_bypass,
+   struct clk_mgr *clk_mgr_base, struct clk_log_info *log_info)
+{
+   struct clk_mgr_internal *clk_mgr = 
TO_CLK_MGR_INTERNAL(clk_mgr_base);
+   uint32_t dprefclk_did = 0;
+   uint32_t dcfclk_did = 0;
+   uint32_t dtbclk_did = 0;
+   uint32_t dispclk_did = 0;
+   uint32_t dppclk_did = 0;
+   uint32_t fclk_did = 0;
+   uint32_t target_div = 0;
+
+   /* DFS Slice 0 is used for DISPCLK */
+   dispclk_did = REG_READ(CLK0_CLK0_DFS_CNTL);
+   /* DFS Slice 1 is used for DPPCLK */
+   dppclk_did = REG_READ(CLK0_CLK1_DFS_CNTL);
+   /* DFS Slice 2 is used for DPREFCLK */
+   dprefclk_did = REG_READ(CLK0_CLK2_DFS_CNTL);
+   /* DFS Slice 3 is used for DCFCLK */
+   dcfclk_did = REG_READ(CLK0_CLK3_DFS_CNTL);
+   /* DFS Slice 4 is used for DTBCLK */
+   dtbclk_did = REG_READ(CLK0_CLK4_DFS_CNTL);
+   /* DFS Slice _ is used for FCLK */
+   fclk_did = REG_READ(CLK2_CLK2_DFS_CNTL);
+
+   /* Convert DISPCLK DFS Slice DID to divider*/
+   target_div = dentist_get_divider_from_did(dispclk_did);
+   //Get dispclk in khz
+   regs_and_bypass->dispclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+   * clk_mgr->base.dentist_vco_freq_khz) / 
target_div;
+
+   /* Convert DISPCLK DFS Slice DID to divider*/
+   target_div = dentist_get_divider_from_did(dppclk_did);
+   //Get dppclk in khz
+   regs_and_bypass->dppclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+   * clk_mgr->base.dentist_vco_freq_khz) / 
target_div;
+
+   /* Convert DPREFCLK DFS Slice DID to divider*/
+   target_div = dentist_get_divider_from_did(dprefclk_did);
+   //Get dprefclk in khz
+   regs_and_bypass->dprefclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+   * clk_mgr->base.dentist_vco_freq_khz) / 
target_div;
+
+   /* Convert DCFCLK DFS Slice DID to divider*/
+   target_div = dentist_get_divider_from_did(dcfclk_did);
+   //Get dcfclk in khz
+   regs_and_bypass->dcfclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+   * clk_mgr->base.dentist_vco_freq_khz) / 
target_div;
+
+   /* Convert DTBCLK DFS Slice DID to divider*/
+   target_div = dentist_get_divider_from_did(dtbclk_did);
+   //Get dtbclk in khz
+   regs_and_bypass->dtbclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+   * clk_mgr->base.dentist_vco_freq_khz) / 
target_div;
+
+   /* Convert DTBCLK DFS Slice DID to divider*/
+   target_div = dentist_get_divider_from_did(fclk_did);
+   //Get fclk in khz
+   regs_and_bypass->fclk = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+   * clk_mgr->base.dentist_vco_freq_khz) / 
target_div;
+}
+
+static bool dc

[PATCH 00/50] DC Patches July 10th, 2024

2024-07-10 Thread Fangzhi Zuo
This DC patchset brings improvements in multiple areas.

* FW Release 0.0.225.0
* DML2 fixes
* Re-enable panel replay feature
* Allow display DCC for DCN401
* Refactor DWB, OPP, MPC, MMHUBBUB
* Fix dscclk Programming issue on DCN401

Cc: Daniel Wheeler 

Alex Hung (11):
  drm/amd/display: Revert "Check HDCP returned status"
  drm/amd/display: Initialize denominators' default to 1
  drm/amd/display: Check null-initialized variables
  drm/amd/display: Check phantom_stream before it is used
  drm/amd/display: Pass non-null to
dcn20_validate_apply_pipe_split_flags
  drm/amd/display: Check null pointers before using them
  drm/amd/display: Check stream before comparing them
  drm/amd/display: Check link_res->hpo_dp_link_enc before using it
  drm/amd/display: Check null pointers before used
  drm/amd/display: Check null pointers before multiple uses
  drm/amd/display: Increase array size of dummy_boolean

Alvin Lee (5):
  drm/amd/display: Disable HBR audio for DP2 for certain ASICs
  drm/amd/display: Don't consider cursor for no plane case in DML1
  drm/amd/display: When resync fifo ensure to use correct pipe ctx
  drm/amd/display: Disable subvp based on HW cursor requirement
  drm/amd/display: Calculate ODM width using odm slice rect, not recout

Aric Cyr (1):
  drm/amd/display: 3.2.292

Aurabindo Pillai (3):
  drm/amd/display: free bo used for dmub bounding box
  drm/amd/display: Allow display DCC for DCN401
  drm/amd/display: improve logic for addition of modifers

Chaitanya Dhere (1):
  drm/amd/display: DML2.1 resynchronization

Chris Park (1):
  drm/amd/display: Deallocate DML memory if allocation fails

Daniel Sa (1):
  drm/amd/display: Set Cursor Matrix to bypass instead of Input Plane

Dillon Varone (3):
  drm/amd/display: Add blanked streams override to DML2.1
  drm/amd/display: Add P-State Keepout to dcn401 Global Sync
  drm/amd/display: Export additional FAMS2 global configuration options
from DML

Duncan Ma (1):
  drm/amd/display: Add visual confirm for Idle State

Fudongwang (1):
  drm/amd/display: add dmcub support check

Gabe Teeger (1):
  drm/amd/display: Fix DP-DVI dongle hotplug

Jingwen Zhu (1):
  drm/amd/display: avoid disable otg when dig was disabled

Joshua Aberback (1):
  drm/amd/display: Remove unnecessary DSC power gating for DCN401

Mounika Adhuri (1):
  drm/amd/display: Refactoring MPC

Mudimela (1):
  drm/amd/display: Refactoring DWB related files from dcn30 Files

Nevenko Stupar (1):
  drm/amd/display: Issue with 3 or more mcaches per surface

Relja Vojvodic (1):
  drm/amd/display: Implement bias and scale pre scl

Revalla Hari Krishna (2):
  drm/amd/display: Refactoring OPP
  drm/amd/display: Refactoring MMHUBBUB

Rodrigo Siqueira (1):
  drm/amd/display: Remove unused dml2_core_ip_params struct

Roman Li (1):
  drm/amd/display: Replace assert with error message in
dp_retrieve_lttpr_cap()

Ryan Seto (1):
  drm/amd/display: Added logging for automated DPM testing

Samson Tam (2):
  drm/amd/display: quality improvements for EASF and ISHARP
  drm/amd/display: remove dc dependencies from SPL library

Sridevi Arvindekar (1):
  drm/amd/display: Add option to allow transition when odm is forced

Sung Joon Kim (2):
  drm/amd/display: Do 1-to-1 mapping between OPP and DSC in DML2
  drm/amd/display: Check stream pointer is initialized before accessing

Tom Chung (3):
  drm/amd/display: Disable replay if VRR capability is false
  drm/amd/display: Fix VRR cannot enable
  drm/amd/display: Re-enable panel replay feature

Wenjing Liu (2):
  drm/amd/display: fix dscclk programming sequence on DCN401
  drm/amd/display: apply vmin optimization even if it doesn't reach vmin
level

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   74 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   12 +
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   |   31 +-
 .../drm/amd/display/dc/basics/fixpt31_32.c|   27 +
 .../dc/clk_mgr/dce110/dce110_clk_mgr.c|2 +-
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |   18 +-
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c|  250 ++-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |   22 +-
 .../drm/amd/display/dc/core/dc_hw_sequencer.c |  102 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |6 +-
 .../gpu/drm/amd/display/dc/core/dc_state.c|   14 +-
 drivers/gpu/drm/amd/display/dc/dc.h   |6 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   34 +-
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |7 -
 .../gpu/drm/amd/display/dc/dc_spl_translate.c |   48 +-
 .../gpu/drm/amd/display/dc/dc_spl_translate.h |1 +
 drivers/gpu/drm/amd/display/dc/dc_stream.h|9 +
 .../amd/display/dc/dccg/dcn20/dcn20_dccg.h|6 +-
 .../amd/display/dc/dccg/dcn401/dcn401_dccg.c  |   32 +-
 .../amd/display/dc/dccg/dcn401/dcn401_dccg.h  |4 -
 .../gpu/drm/amd/display/dc/dce/dce_audio.c|6 +
 .../gpu/drm/amd/display/dc/dce/dce_audio.h|1 +
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c |1 +
 .../gpu/drm/amd/display/dc

[PATCH 01/50] drm/amd/display: Disable replay if VRR capability is false

2024-07-10 Thread Fangzhi Zuo
From: Tom Chung 

[Why]
The VRR need to be supported for panel replay feature.
If VRR capability is false, panel replay capability also
need to be disabled.

[How]
After update the vrr capability, the panel replay capability
also need to be check if need.

Reviewed-by: Wayne Lin 
Signed-off-by: Jerry Zuo 
Signed-off-by: Tom Chung 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d1527c2e46a1..44a80766380f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -12146,6 +12146,12 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
if (dm_con_state)
dm_con_state->freesync_capable = freesync_capable;
 
+   if (connector->state && amdgpu_dm_connector->dc_link && 
!freesync_capable &&
+   
amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported) {
+   
amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported = false;
+   
amdgpu_dm_connector->dc_link->replay_settings.replay_feature_enabled = false;
+   }
+
if (connector->vrr_capable_property)
drm_connector_set_vrr_capable_property(connector,
   freesync_capable);
-- 
2.34.1



Re: [PATCH 1/2] drm/amdgpu/vcn: identify unified queue in sw init

2024-07-10 Thread Alex Deucher
On Wed, Jul 10, 2024 at 2:10 PM  wrote:
>
> From: Boyuan Zhang 
>
> Determine whether VCN using unified queue in sw_init, instead of calling
> functions later on.
>
> Signed-off-by: Boyuan Zhang 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 39 ++---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h |  1 +
>  2 files changed, 16 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> index dad5f9722e14..43bed7730bd1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> @@ -139,6 +139,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
> }
> }
>
> +   /* from vcn4 and above, only unified queue is used */
> +   adev->vcn.using_unified_queue =
> +   amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0) ? 
> true : false;

You can drop the "? true : false" part.  A lot of static checkers will
complain about that as it's not necessary.

With that fixed, the series is:
Acked-by: Alex Deucher 

> +
> hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
> adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
>
> @@ -266,18 +270,6 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
> return 0;
>  }
>
> -/* from vcn4 and above, only unified queue is used */
> -static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)
> -{
> -   struct amdgpu_device *adev = ring->adev;
> -   bool ret = false;
> -
> -   if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0))
> -   ret = true;
> -
> -   return ret;
> -}
> -
>  bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum 
> vcn_ring_type type, uint32_t vcn_instance)
>  {
> bool ret = false;
> @@ -747,12 +739,11 @@ static int amdgpu_vcn_dec_sw_send_msg(struct 
> amdgpu_ring *ring,
> struct amdgpu_job *job;
> struct amdgpu_ib *ib;
> uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
> -   bool sq = amdgpu_vcn_using_unified_queue(ring);
> uint32_t *ib_checksum;
> uint32_t ib_pack_in_dw;
> int i, r;
>
> -   if (sq)
> +   if (adev->vcn.using_unified_queue)
> ib_size_dw += 8;
>
> r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
> @@ -765,7 +756,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
> *ring,
> ib->length_dw = 0;
>
> /* single queue headers */
> -   if (sq) {
> +   if (adev->vcn.using_unified_queue) {
> ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / 
> sizeof(uint32_t)
> + 4 + 2; /* engine info + 
> decoding ib in dw */
> ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 
> ib_pack_in_dw, false);
> @@ -784,7 +775,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
> *ring,
> for (i = ib->length_dw; i < ib_size_dw; ++i)
> ib->ptr[i] = 0x0;
>
> -   if (sq)
> +   if (adev->vcn.using_unified_queue)
> amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 
> ib_pack_in_dw);
>
> r = amdgpu_job_submit_direct(job, ring, &f);
> @@ -874,15 +865,15 @@ static int amdgpu_vcn_enc_get_create_msg(struct 
> amdgpu_ring *ring, uint32_t hand
>  struct dma_fence **fence)
>  {
> unsigned int ib_size_dw = 16;
> +   struct amdgpu_device *adev = ring->adev;
> struct amdgpu_job *job;
> struct amdgpu_ib *ib;
> struct dma_fence *f = NULL;
> uint32_t *ib_checksum = NULL;
> uint64_t addr;
> -   bool sq = amdgpu_vcn_using_unified_queue(ring);
> int i, r;
>
> -   if (sq)
> +   if (adev->vcn.using_unified_queue)
> ib_size_dw += 8;
>
> r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
> @@ -896,7 +887,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct 
> amdgpu_ring *ring, uint32_t hand
>
> ib->length_dw = 0;
>
> -   if (sq)
> +   if (adev->vcn.using_unified_queue)
> ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, 
> true);
>
> ib->ptr[ib->length_dw++] = 0x0018;
> @@ -918,7 +909,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct 
> amdgpu_ring *ring, uint32_t hand
> for (i = ib->length_dw; i < ib_size_dw; ++i)
> ib->ptr[i] = 0x0;
>
> -   if (sq)
> +   if (adev->vcn.using_unified_queue)
> amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
>
> r = amdgpu_job_submit_direct(job, ring, &f);
> @@ -941,15 +932,15 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct 
> amdgpu_ring *ring, uint32_t han
>   struct dma_fence **fence)
>  {
> unsigned int ib_size_dw = 16;
> +   struct amdgpu_device *adev = ring->adev;
> st

[PATCH 2/2] drm/amdgpu/vcn: not pause dpg for unified queue

2024-07-10 Thread boyuan.zhang
From: Boyuan Zhang 

For unified queue, DPG pause for encoding is done inside VCN firmware,
so there is no need to pause dpg based on ring type in kernel.

For previous generations, pausing DPG for encoding in kernel is still needed.

Signed-off-by: Boyuan Zhang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 43bed7730bd1..13fbe4120959 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -412,7 +412,8 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct 
*work)
for (i = 0; i < adev->vcn.num_enc_rings; ++i)
fence[j] += 
amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
 
-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;
 
if (fence[j] ||
@@ -458,7 +459,8 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
   AMD_PG_STATE_UNGATE);
 
-   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG){
+   if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+   !adev->vcn.using_unified_queue) {
struct dpg_pause_state new_state;
 
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
@@ -484,8 +486,11 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
 
 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
 {
+   struct amdgpu_device *adev = ring->adev;
+
if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
-   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
+   ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
+   !adev->vcn.using_unified_queue)

atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
 
atomic_dec(&ring->adev->vcn.total_submission_cnt);
-- 
2.34.1



[PATCH 1/2] drm/amdgpu/vcn: identify unified queue in sw init

2024-07-10 Thread boyuan.zhang
From: Boyuan Zhang 

Determine whether VCN using unified queue in sw_init, instead of calling
functions later on. 

Signed-off-by: Boyuan Zhang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 39 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h |  1 +
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index dad5f9722e14..43bed7730bd1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -139,6 +139,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
}
}
 
+   /* from vcn4 and above, only unified queue is used */
+   adev->vcn.using_unified_queue =
+   amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0) ? 
true : false;
+
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
 
@@ -266,18 +270,6 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
return 0;
 }
 
-/* from vcn4 and above, only unified queue is used */
-static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)
-{
-   struct amdgpu_device *adev = ring->adev;
-   bool ret = false;
-
-   if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0))
-   ret = true;
-
-   return ret;
-}
-
 bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type 
type, uint32_t vcn_instance)
 {
bool ret = false;
@@ -747,12 +739,11 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
struct amdgpu_job *job;
struct amdgpu_ib *ib;
uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
uint32_t *ib_checksum;
uint32_t ib_pack_in_dw;
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -765,7 +756,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
ib->length_dw = 0;
 
/* single queue headers */
-   if (sq) {
+   if (adev->vcn.using_unified_queue) {
ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / 
sizeof(uint32_t)
+ 4 + 2; /* engine info + 
decoding ib in dw */
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 
ib_pack_in_dw, false);
@@ -784,7 +775,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring 
*ring,
for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 
ib_pack_in_dw);
 
r = amdgpu_job_submit_direct(job, ring, &f);
@@ -874,15 +865,15 @@ static int amdgpu_vcn_enc_get_create_msg(struct 
amdgpu_ring *ring, uint32_t hand
 struct dma_fence **fence)
 {
unsigned int ib_size_dw = 16;
+   struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct dma_fence *f = NULL;
uint32_t *ib_checksum = NULL;
uint64_t addr;
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -896,7 +887,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring 
*ring, uint32_t hand
 
ib->length_dw = 0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
 
ib->ptr[ib->length_dw++] = 0x0018;
@@ -918,7 +909,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring 
*ring, uint32_t hand
for (i = ib->length_dw; i < ib_size_dw; ++i)
ib->ptr[i] = 0x0;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
 
r = amdgpu_job_submit_direct(job, ring, &f);
@@ -941,15 +932,15 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct 
amdgpu_ring *ring, uint32_t han
  struct dma_fence **fence)
 {
unsigned int ib_size_dw = 16;
+   struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct dma_fence *f = NULL;
uint32_t *ib_checksum = NULL;
uint64_t addr;
-   bool sq = amdgpu_vcn_using_unified_queue(ring);
int i, r;
 
-   if (sq)
+   if (adev->vcn.using_unified_queue)
ib_size_dw += 8;
 
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -963,7 +954,7 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct 

[PATCH] drm/amd: Fail the suspend sequence if the GPU doesn't use S3 or S0i3

2024-07-10 Thread Mario Limonciello
As part of the S3 suspend sequence dGPUs will evict VRAM.  If there is
high memory pressure at this time, there is a chance this fails.

systemd has a policy to try to "fall back" from S3 to s2idle and see
if that works.  When under high memory pressure this also fails, and
harder.  Really we don't want this flow to be possible.

Fail the sequence if the dGPU won't be suspended using either method.

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3476
Link: https://github.com/systemd/systemd/issues/25151
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 802debd8d9f0..6a5a3e132319 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2562,7 +2562,7 @@ static int amdgpu_pmops_suspend(struct device *dev)
else if (amdgpu_acpi_is_s3_active(adev))
adev->in_s3 = true;
if (!adev->in_s0ix && !adev->in_s3)
-   return 0;
+   return -EINVAL;
return amdgpu_device_suspend(drm_dev, true);
 }
 
-- 
2.45.2



RE: [PATCH 2/2] drm/amdgpu/mes12: add missing opcode string

2024-07-10 Thread Zhang, Hawking
[AMD Official Use Only - AMD Internal Distribution Only]

Series is

Reviewed-by: Hawking Zhang 

Regards,
Hawking
-Original Message-
From: amd-gfx  On Behalf Of Alex Deucher
Sent: Tuesday, July 9, 2024 05:51
To: amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander 
Subject: [PATCH 2/2] drm/amdgpu/mes12: add missing opcode string

Fixes the indexing of the string array.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index 106eef1ff5cc..c9f74231ad59 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -99,6 +99,7 @@ static const char *mes_v12_0_opcodes[] = {
"SET_LOG_BUFFER",
"CHANGE_GANG_PRORITY",
"QUERY_SCHEDULER_STATUS",
+   "unused",
"SET_DEBUG_VMID",
"MISC",
"UPDATE_ROOT_PAGE_TABLE",
--
2.45.2



RE: [PATCH] drm/amdgpu: remove exp hw support check for gfx12

2024-07-10 Thread Zhang, Hawking
[AMD Official Use Only - AMD Internal Distribution Only]

Reviewed-by: Hawking Zhang 

Regards,
Hawking
-Original Message-
From: amd-gfx  On Behalf Of Alex Deucher
Sent: Wednesday, July 10, 2024 22:15
To: amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander 
Subject: [PATCH] drm/amdgpu: remove exp hw support check for gfx12

Enable it by default.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index f927ccd7ec45..b241f61fe9c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -2161,8 +2161,6 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct 
amdgpu_device *adev)
break;
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
-   if (!amdgpu_exp_hw_support)
-   return -EINVAL;
amdgpu_device_ip_block_add(adev, &gfx_v12_0_ip_block);
break;
default:
--
2.45.2



Re: [PATCH] drm/amd/display: Allow display DCC for DCN401

2024-07-10 Thread Marek Olšák
This will enable display DCC for Wayland because Mesa already exposes
modifiers with DCC. Has it been tested?

Marek

On Mon, Jul 8, 2024 at 12:06 PM Aurabindo Pillai
 wrote:
>
> To enable mesa to use display dcc, DM should expose them in the
> supported modifiers. Add the best (most efficient) modifiers first.
>
> Signed-off-by: Aurabindo Pillai 
> ---
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 31 +++
>  1 file changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> index 0320200dae94..a83bd0331c3b 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> @@ -689,13 +689,32 @@ static void amdgpu_dm_plane_add_gfx12_modifiers(struct 
> amdgpu_device *adev,
>   uint64_t **mods, uint64_t *size, uint64_t *capacity)
>  {
> uint64_t ver = AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE_VERSION, 
> AMD_FMT_MOD_TILE_VER_GFX12);
> +   uint64_t mod_256k = ver | AMD_FMT_MOD_SET(TILE, 
> AMD_FMT_MOD_TILE_GFX12_256K_2D);
> +   uint64_t mod_64k = ver | AMD_FMT_MOD_SET(TILE, 
> AMD_FMT_MOD_TILE_GFX12_64K_2D);
> +   uint64_t mod_4k = ver | AMD_FMT_MOD_SET(TILE, 
> AMD_FMT_MOD_TILE_GFX12_4K_2D);
> +   uint64_t mod_256b = ver | AMD_FMT_MOD_SET(TILE, 
> AMD_FMT_MOD_TILE_GFX12_256B_2D);
> +   uint64_t dcc = ver | AMD_FMT_MOD_SET(DCC, 1);
> +   uint8_t max_comp_block[] = {1, 0};
> +   uint64_t max_comp_block_mod[ARRAY_SIZE(max_comp_block)] = {0};
> +   uint8_t i = 0, j = 0;
> +   uint64_t gfx12_modifiers[] = {mod_256k, mod_64k, mod_4k, mod_256b, 
> DRM_FORMAT_MOD_LINEAR};
> +
> +   for (i = 0; i < ARRAY_SIZE(max_comp_block); i++)
> +   max_comp_block_mod[i] = 
> AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_comp_block[i]);
> +
> +   /* With DCC: Best choice should be kept first. Hence, add all 256k 
> modifiers of different
> +* max compressed blocks first and then move on to the next smaller 
> sized layouts.
> +* Do not add the linear modifier here, and hence the condition of 
> size-1 for the loop
> +*/
> +   for (j = 0; j < ARRAY_SIZE(gfx12_modifiers) - 1; j++)
> +   for (i = 0; i < ARRAY_SIZE(max_comp_block); i++)
> +   amdgpu_dm_plane_add_modifier(mods, size, capacity,
> +ver | dcc | 
> max_comp_block_mod[i] | gfx12_modifiers[j]);
> +
> +   /* Without DCC. Add all modifiers including linear at the end */
> +   for (i = 0; i < ARRAY_SIZE(gfx12_modifiers); i++)
> +   amdgpu_dm_plane_add_modifier(mods, size, capacity, 
> gfx12_modifiers[i]);
>
> -   /* Without DCC: */
> -   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_256K_2D));
> -   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_64K_2D));
> -   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_4K_2D));
> -   amdgpu_dm_plane_add_modifier(mods, size, capacity, ver | 
> AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_256B_2D));
> -   amdgpu_dm_plane_add_modifier(mods, size, capacity, 
> DRM_FORMAT_MOD_LINEAR);
>  }
>
>  static int amdgpu_dm_plane_get_plane_modifiers(struct amdgpu_device *adev, 
> unsigned int plane_type, uint64_t **mods)
> --
> 2.45.2
>


[PATCH] drm/amdgpu: remove exp hw support check for gfx12

2024-07-10 Thread Alex Deucher
Enable it by default.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index f927ccd7ec45..b241f61fe9c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -2161,8 +2161,6 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct 
amdgpu_device *adev)
break;
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
-   if (!amdgpu_exp_hw_support)
-   return -EINVAL;
amdgpu_device_ip_block_add(adev, &gfx_v12_0_ip_block);
break;
default:
-- 
2.45.2



Re: [PATCH] drm/amd/swsmu: enable Pstates profile levels for SMU v14.0.4

2024-07-10 Thread Alex Deucher
On Wed, Jul 10, 2024 at 5:50 AM Li Ma  wrote:
>
> Enables following UMD stable Pstates profile levels
> of power_dpm_force_performance_level for SMU v14.0.4.
>
> - profile_peak
> - profile_min_mclk
> - profile_min_sclk
> - profile_standard
>
> Signed-off-by: Li Ma 

Acked-by: Alex Deucher 

> ---
>  .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c   | 18 +++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c 
> b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> index 5d47d58944f6..8798ebfcea83 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
> @@ -69,6 +69,9 @@
>  #define SMU_14_0_0_UMD_PSTATE_SOCCLK   678
>  #define SMU_14_0_0_UMD_PSTATE_FCLK 1800
>
> +#define SMU_14_0_4_UMD_PSTATE_GFXCLK   938
> +#define SMU_14_0_4_UMD_PSTATE_SOCCLK   938
> +
>  #define FEATURE_MASK(feature) (1ULL << feature)
>  #define SMC_DPM_FEATURE ( \
> FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \
> @@ -1296,19 +1299,28 @@ static int 
> smu_v14_0_common_get_dpm_profile_freq(struct smu_context *smu,
> switch (clk_type) {
> case SMU_GFXCLK:
> case SMU_SCLK:
> -   clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
> +   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == 
> IP_VERSION(14, 0, 4))
> +   clk_limit = SMU_14_0_4_UMD_PSTATE_GFXCLK;
> +   else
> +   clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
> if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, 
> NULL, &clk_limit);
> else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK)
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, 
> &clk_limit, NULL);
> break;
> case SMU_SOCCLK:
> -   clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
> +   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == 
> IP_VERSION(14, 0, 4))
> +   clk_limit = SMU_14_0_4_UMD_PSTATE_SOCCLK;
> +   else
> +   clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
> if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
> smu_v14_0_common_get_dpm_ultimate_freq(smu, 
> SMU_SOCCLK, NULL, &clk_limit);
> break;
> case SMU_FCLK:
> -   clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
> +   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == 
> IP_VERSION(14, 0, 4))
> +   smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, 
> NULL, &clk_limit);
> +   else
> +   clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
> if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
> smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, 
> NULL, &clk_limit);
> else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK)
> --
> 2.25.1
>


Re: [PATCH 2/2] drm/amdgpu/mes12: add missing opcode string

2024-07-10 Thread Alex Deucher
Ping on this series?

Alex

On Mon, Jul 8, 2024 at 6:30 PM Alex Deucher  wrote:
>
> Fixes the indexing of the string array.
>
> Signed-off-by: Alex Deucher 
> ---
>  drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c 
> b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
> index 106eef1ff5cc..c9f74231ad59 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
> @@ -99,6 +99,7 @@ static const char *mes_v12_0_opcodes[] = {
> "SET_LOG_BUFFER",
> "CHANGE_GANG_PRORITY",
> "QUERY_SCHEDULER_STATUS",
> +   "unused",
> "SET_DEBUG_VMID",
> "MISC",
> "UPDATE_ROOT_PAGE_TABLE",
> --
> 2.45.2
>


Re: [PATCH] drm/buddy: Add start address support to trim function

2024-07-10 Thread Matthew Auld

On 10/07/2024 07:03, Paneer Selvam, Arunpravin wrote:

Thanks Alex.

Hi Matthew,
Any comments?


Do we not pass the required address alignment when allocating the pages 
in the first place?




Thanks,
Arun.

On 7/9/2024 1:42 AM, Alex Deucher wrote:

On Thu, Jul 4, 2024 at 4:40 AM Arunpravin Paneer Selvam
 wrote:

- Add a new start parameter in trim function to specify exact
   address from where to start the trimming. This would help us
   in situations like if drivers would like to do address alignment
   for specific requirements.

- Add a new flag DRM_BUDDY_TRIM_DISABLE. Drivers can use this
   flag to disable the allocator trimming part. This patch enables
   the drivers control trimming and they can do it themselves
   based on the application requirements.

v1:(Matthew)
   - check new_start alignment with min chunk_size
   - use range_overflows()

Signed-off-by: Arunpravin Paneer Selvam 


Series is:
Acked-by: Alex Deucher 

I'd like to take this series through the amdgpu tree if there are no
objections as it's required for display buffers on some chips and I'd
like to make sure it lands in 6.11.

Thanks,

Alex


---
  drivers/gpu/drm/drm_buddy.c  | 25 +++--
  drivers/gpu/drm/xe/xe_ttm_vram_mgr.c |  2 +-
  include/drm/drm_buddy.h  |  2 ++
  3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index 94f8c34fc293..8cebe1fa4e9d 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -851,6 +851,7 @@ static int __alloc_contig_try_harder(struct 
drm_buddy *mm,

   * drm_buddy_block_trim - free unused pages
   *
   * @mm: DRM buddy manager
+ * @start: start address to begin the trimming.
   * @new_size: original size requested
   * @blocks: Input and output list of allocated blocks.
   * MUST contain single block as input to be trimmed.
@@ -866,11 +867,13 @@ static int __alloc_contig_try_harder(struct 
drm_buddy *mm,

   * 0 on success, error code on failure.
   */
  int drm_buddy_block_trim(struct drm_buddy *mm,
+    u64 *start,
  u64 new_size,
  struct list_head *blocks)
  {
 struct drm_buddy_block *parent;
 struct drm_buddy_block *block;
+   u64 block_start, block_end;
 LIST_HEAD(dfs);
 u64 new_start;
 int err;
@@ -882,6 +885,9 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
  struct drm_buddy_block,
  link);

+   block_start = drm_buddy_block_offset(block);
+   block_end = block_start + drm_buddy_block_size(mm, block);
+
 if (WARN_ON(!drm_buddy_block_is_allocated(block)))
 return -EINVAL;

@@ -894,6 +900,20 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
 if (new_size == drm_buddy_block_size(mm, block))
 return 0;

+   new_start = block_start;
+   if (start) {
+   new_start = *start;
+
+   if (new_start < block_start)
+   return -EINVAL;
+
+   if (!IS_ALIGNED(new_start, mm->chunk_size))
+   return -EINVAL;
+
+   if (range_overflows(new_start, new_size, block_end))
+   return -EINVAL;
+   }
+
 list_del(&block->link);
 mark_free(mm, block);
 mm->avail += drm_buddy_block_size(mm, block);
@@ -904,7 +924,6 @@ int drm_buddy_block_trim(struct drm_buddy *mm,
 parent = block->parent;
 block->parent = NULL;

-   new_start = drm_buddy_block_offset(block);
 list_add(&block->tmp_link, &dfs);
 err =  __alloc_range(mm, &dfs, new_start, new_size, blocks, 
NULL);

 if (err) {
@@ -1066,7 +1085,8 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
 } while (1);

 /* Trim the allocated block to the required size */
-   if (original_size != size) {
+   if (!(flags & DRM_BUDDY_TRIM_DISABLE) &&
+   original_size != size) {
 struct list_head *trim_list;
 LIST_HEAD(temp);
 u64 trim_size;
@@ -1083,6 +1103,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
 }

 drm_buddy_block_trim(mm,
+    NULL,
  trim_size,
  trim_list);

diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c 
b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c

index fe3779fdba2c..423b261ea743 100644
--- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
@@ -150,7 +150,7 @@ static int xe_ttm_vram_mgr_new(struct 
ttm_resource_manager *man,

 } while (remaining_size);

 if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
-   if (!drm_buddy_block_trim(mm, vres->base.size, 
&vres->blocks))
+   if (!drm_buddy_block_trim(mm, NULL, vres->base.size, 
&vres->blo

Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Christian König

Am 10.07.24 um 12:15 schrieb Zhu, Jiadong:

[AMD Official Use Only - AMD Internal Distribution Only]


-Original Message-
From: Christian König 
Sent: Wednesday, July 10, 2024 5:27 PM
To: Zhu, Jiadong ; amd-gfx@lists.freedesktop.org;
Deucher, Alexander 
Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the
right place

Am 10.07.24 um 09:54 schrieb Zhu, Jiadong:

[AMD Official Use Only - AMD Internal Distribution Only]


-Original Message-
From: Christian König 
Sent: Wednesday, July 10, 2024 3:17 PM
To: Zhu, Jiadong ; amd-

g...@lists.freedesktop.org

Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in
the right place

Am 10.07.24 um 02:31 schrieb jiadong@amd.com:

From: Jiadong Zhu 

The job's embedded fence is dma_fence which shall not be conversed
to amdgpu_fence.

Good catch.


The start timestamp shall be saved on job for hw_fence.

But NAK to that approach. Why do we need the start time here in the
first place?

Regards,
Christian.


The start timestamp is used for ring mux to check if the fences are

unsignaled for a period of time under mcbp scenarios (by calling
amdgpu_fence_last_unsignaled_time_us).

I can't find a reason for doing that in the first place. What is the background
of this?

Regards,
Christian.


It is about os triggered mcbp on gfx9. When we are using software ring and ring 
mux on gfx9,  the ring mux checks the fence unsignaled time of the low priority 
context while high priority job comes. If the time duration exceeds a certain 
time, mux will trigger mcbp.
we could add adev->gfx.mcbp check when set start_timestamp for those fences.


So you basically want to guarantee some forward progress?

While this is nice to have I don't think we need that in the first place.

I mean when I have two hardware queues the high priority one would 
starve the low priority one as well.


Regards,
Christian.



Thanks,
Jiadong


Thanks,
Jiadong

v2: optimize get_fence_start_time.
Signed-off-by: Jiadong Zhu 
---
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 31

---

drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2f24a6aa13bf..72bb007e48c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -88,6 +88,31 @@ static inline struct amdgpu_fence

*to_amdgpu_fence(struct dma_fence *f)

  return NULL;
}

+static inline void set_fence_start_time(struct dma_fence *f,
+ktime_t
+start_timestamp) {
+   if (f->ops == &amdgpu_fence_ops) {
+   struct amdgpu_fence *__f = container_of(f, struct

amdgpu_fence,

+base);
+
+   __f->start_timestamp = start_timestamp;
+   } else if (f->ops == &amdgpu_job_fence_ops) {
+   struct amdgpu_job *job = container_of(f, struct
+amdgpu_job, hw_fence);
+
+   job->start_timestamp = start_timestamp;
+   }
+}
+
+static inline ktime_t get_fence_start_time(struct dma_fence *f) {
+   if (unlikely(f->ops == &amdgpu_fence_ops)) {
+   struct amdgpu_fence *__f = container_of(f, struct

amdgpu_fence,

+base);
+
+   return __f->start_timestamp;
+   }
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
+hw_fence);
+
+   return job->start_timestamp;
+}
+
/**
 * amdgpu_fence_write - write a fence value
 *
@@ -197,7 +222,7 @@ int amdgpu_fence_emit(struct amdgpu_ring

*ring,

struct dma_fence **f, struct amd

  }
  }

-   to_amdgpu_fence(fence)->start_timestamp = ktime_get();
+   set_fence_start_time(fence, ktime_get());

  /* This function can't be called concurrently anyway, otherwise
   * emitting the fence would mess up the hardware ring buffer.
@@ -428,7 +453,7 @@ u64

amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring *ring)

  return 0;

  return ktime_us_delta(ktime_get(),
-   to_amdgpu_fence(fence)->start_timestamp);
+   get_fence_start_time(fence));
}

/**
@@ -451,7 +476,7 @@ void

amdgpu_fence_update_start_timestamp(struct amdgpu_ring *ring,
uint32_t seq,

  if (!fence)
  return;

-   to_amdgpu_fence(fence)->start_timestamp = timestamp;
+   set_fence_start_time(fence, timestamp);
}

/**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index a963a25ddd62..3a73fe11a1ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -73,6 +73,9 @@ struct amdgpu_job {
  uint64_tgds_va;
  boolinit_shadow;

+   /* start timestamp for hw_fence*/
+   ktime_t start_timestamp;
+
  /* job_run_counter >= 1 means a resubmit job */
  uint32_tjob_run_counter;





RE: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Zhu, Jiadong
[AMD Official Use Only - AMD Internal Distribution Only]

> -Original Message-
> From: Christian König 
> Sent: Wednesday, July 10, 2024 5:27 PM
> To: Zhu, Jiadong ; amd-gfx@lists.freedesktop.org;
> Deucher, Alexander 
> Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the
> right place
>
> Am 10.07.24 um 09:54 schrieb Zhu, Jiadong:
> > [AMD Official Use Only - AMD Internal Distribution Only]
> >
> >> -Original Message-
> >> From: Christian König 
> >> Sent: Wednesday, July 10, 2024 3:17 PM
> >> To: Zhu, Jiadong ; amd-
> g...@lists.freedesktop.org
> >> Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in
> >> the right place
> >>
> >> Am 10.07.24 um 02:31 schrieb jiadong@amd.com:
> >>> From: Jiadong Zhu 
> >>>
> >>> The job's embedded fence is dma_fence which shall not be conversed
> >>> to amdgpu_fence.
> >> Good catch.
> >>
> >>> The start timestamp shall be saved on job for hw_fence.
> >> But NAK to that approach. Why do we need the start time here in the
> >> first place?
> >>
> >> Regards,
> >> Christian.
> >>
> > The start timestamp is used for ring mux to check if the fences are
> unsignaled for a period of time under mcbp scenarios (by calling
> amdgpu_fence_last_unsignaled_time_us).
>
> I can't find a reason for doing that in the first place. What is the 
> background
> of this?
>
> Regards,
> Christian.
>

It is about os triggered mcbp on gfx9. When we are using software ring and ring 
mux on gfx9,  the ring mux checks the fence unsignaled time of the low priority 
context while high priority job comes. If the time duration exceeds a certain 
time, mux will trigger mcbp.
we could add adev->gfx.mcbp check when set start_timestamp for those fences.

Thanks,
Jiadong

> >
> > Thanks,
> > Jiadong
> >>> v2: optimize get_fence_start_time.
> >>> Signed-off-by: Jiadong Zhu 
> >>> ---
> >>>drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 31
> >> ---
> >>>drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
> >>>2 files changed, 31 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> >>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> >>> index 2f24a6aa13bf..72bb007e48c8 100644
> >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> >>> @@ -88,6 +88,31 @@ static inline struct amdgpu_fence
> >> *to_amdgpu_fence(struct dma_fence *f)
> >>>  return NULL;
> >>>}
> >>>
> >>> +static inline void set_fence_start_time(struct dma_fence *f,
> >>> +ktime_t
> >>> +start_timestamp) {
> >>> +   if (f->ops == &amdgpu_fence_ops) {
> >>> +   struct amdgpu_fence *__f = container_of(f, struct
> >> amdgpu_fence,
> >>> +base);
> >>> +
> >>> +   __f->start_timestamp = start_timestamp;
> >>> +   } else if (f->ops == &amdgpu_job_fence_ops) {
> >>> +   struct amdgpu_job *job = container_of(f, struct
> >>> +amdgpu_job, hw_fence);
> >>> +
> >>> +   job->start_timestamp = start_timestamp;
> >>> +   }
> >>> +}
> >>> +
> >>> +static inline ktime_t get_fence_start_time(struct dma_fence *f) {
> >>> +   if (unlikely(f->ops == &amdgpu_fence_ops)) {
> >>> +   struct amdgpu_fence *__f = container_of(f, struct
> >> amdgpu_fence,
> >>> +base);
> >>> +
> >>> +   return __f->start_timestamp;
> >>> +   }
> >>> +   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
> >>> +hw_fence);
> >>> +
> >>> +   return job->start_timestamp;
> >>> +}
> >>> +
> >>>/**
> >>> * amdgpu_fence_write - write a fence value
> >>> *
> >>> @@ -197,7 +222,7 @@ int amdgpu_fence_emit(struct amdgpu_ring
> *ring,
> >> struct dma_fence **f, struct amd
> >>>  }
> >>>  }
> >>>
> >>> -   to_amdgpu_fence(fence)->start_timestamp = ktime_get();
> >>> +   set_fence_start_time(fence, ktime_get());
> >>>
> >>>  /* This function can't be called concurrently anyway, otherwise
> >>>   * emitting the fence would mess up the hardware ring buffer.
> >>> @@ -428,7 +453,7 @@ u64
> >> amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring *ring)
> >>>  return 0;
> >>>
> >>>  return ktime_us_delta(ktime_get(),
> >>> -   to_amdgpu_fence(fence)->start_timestamp);
> >>> +   get_fence_start_time(fence));
> >>>}
> >>>
> >>>/**
> >>> @@ -451,7 +476,7 @@ void
> >> amdgpu_fence_update_start_timestamp(struct amdgpu_ring *ring,
> >> uint32_t seq,
> >>>  if (!fence)
> >>>  return;
> >>>
> >>> -   to_amdgpu_fence(fence)->start_timestamp = timestamp;
> >>> +   set_fence_start_time(fence, timestamp);
> >>>}
> >>>
> >>>/**
> >>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> >>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> >>> index a963a25ddd62..3a73fe11a1ce 100644
> >>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> >>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> >>> @@ -73,6 +73,9 @@ struct amdgpu_job {
> >>>  uint64_tgds_va;
> >>>  bool

[PATCH] drm/amd/swsmu: enable Pstates profile levels for SMU v14.0.4

2024-07-10 Thread Li Ma
Enables following UMD stable Pstates profile levels
of power_dpm_force_performance_level for SMU v14.0.4.

- profile_peak
- profile_min_mclk
- profile_min_sclk
- profile_standard

Signed-off-by: Li Ma 
---
 .../drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c   | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
index 5d47d58944f6..8798ebfcea83 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
@@ -69,6 +69,9 @@
 #define SMU_14_0_0_UMD_PSTATE_SOCCLK   678
 #define SMU_14_0_0_UMD_PSTATE_FCLK 1800
 
+#define SMU_14_0_4_UMD_PSTATE_GFXCLK   938
+#define SMU_14_0_4_UMD_PSTATE_SOCCLK   938
+
 #define FEATURE_MASK(feature) (1ULL << feature)
 #define SMC_DPM_FEATURE ( \
FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \
@@ -1296,19 +1299,28 @@ static int smu_v14_0_common_get_dpm_profile_freq(struct 
smu_context *smu,
switch (clk_type) {
case SMU_GFXCLK:
case SMU_SCLK:
-   clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
+   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 
0, 4))
+   clk_limit = SMU_14_0_4_UMD_PSTATE_GFXCLK;
+   else
+   clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, 
NULL, &clk_limit);
else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK)
smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, 
&clk_limit, NULL);
break;
case SMU_SOCCLK:
-   clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
+   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 
0, 4))
+   clk_limit = SMU_14_0_4_UMD_PSTATE_SOCCLK;
+   else
+   clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, 
NULL, &clk_limit);
break;
case SMU_FCLK:
-   clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
+   if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 
0, 4))
+   smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, 
NULL, &clk_limit);
+   else
+   clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, 
NULL, &clk_limit);
else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK)
-- 
2.25.1



Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Christian König

Am 10.07.24 um 09:54 schrieb Zhu, Jiadong:

[AMD Official Use Only - AMD Internal Distribution Only]


-Original Message-
From: Christian König 
Sent: Wednesday, July 10, 2024 3:17 PM
To: Zhu, Jiadong ; amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the
right place

Am 10.07.24 um 02:31 schrieb jiadong@amd.com:

From: Jiadong Zhu 

The job's embedded fence is dma_fence which shall not be conversed to
amdgpu_fence.

Good catch.


The start timestamp shall be saved on job for hw_fence.

But NAK to that approach. Why do we need the start time here in the first
place?

Regards,
Christian.


The start timestamp is used for ring mux to check if the fences are  unsignaled 
for a period of time under mcbp scenarios (by calling 
amdgpu_fence_last_unsignaled_time_us).


I can't find a reason for doing that in the first place. What is the 
background of this?


Regards,
Christian.




Thanks,
Jiadong

v2: optimize get_fence_start_time.
Signed-off-by: Jiadong Zhu 
---
   drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 31

---

   drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
   2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2f24a6aa13bf..72bb007e48c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -88,6 +88,31 @@ static inline struct amdgpu_fence

*to_amdgpu_fence(struct dma_fence *f)

 return NULL;
   }

+static inline void set_fence_start_time(struct dma_fence *f, ktime_t
+start_timestamp) {
+   if (f->ops == &amdgpu_fence_ops) {
+   struct amdgpu_fence *__f = container_of(f, struct

amdgpu_fence,

+base);
+
+   __f->start_timestamp = start_timestamp;
+   } else if (f->ops == &amdgpu_job_fence_ops) {
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
+hw_fence);
+
+   job->start_timestamp = start_timestamp;
+   }
+}
+
+static inline ktime_t get_fence_start_time(struct dma_fence *f) {
+   if (unlikely(f->ops == &amdgpu_fence_ops)) {
+   struct amdgpu_fence *__f = container_of(f, struct

amdgpu_fence,

+base);
+
+   return __f->start_timestamp;
+   }
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
+hw_fence);
+
+   return job->start_timestamp;
+}
+
   /**
* amdgpu_fence_write - write a fence value
*
@@ -197,7 +222,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring,

struct dma_fence **f, struct amd

 }
 }

-   to_amdgpu_fence(fence)->start_timestamp = ktime_get();
+   set_fence_start_time(fence, ktime_get());

 /* This function can't be called concurrently anyway, otherwise
  * emitting the fence would mess up the hardware ring buffer.
@@ -428,7 +453,7 @@ u64

amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring *ring)

 return 0;

 return ktime_us_delta(ktime_get(),
-   to_amdgpu_fence(fence)->start_timestamp);
+   get_fence_start_time(fence));
   }

   /**
@@ -451,7 +476,7 @@ void

amdgpu_fence_update_start_timestamp(struct amdgpu_ring *ring,
uint32_t seq,

 if (!fence)
 return;

-   to_amdgpu_fence(fence)->start_timestamp = timestamp;
+   set_fence_start_time(fence, timestamp);
   }

   /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index a963a25ddd62..3a73fe11a1ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -73,6 +73,9 @@ struct amdgpu_job {
 uint64_tgds_va;
 boolinit_shadow;

+   /* start timestamp for hw_fence*/
+   ktime_t start_timestamp;
+
 /* job_run_counter >= 1 means a resubmit job */
 uint32_tjob_run_counter;





Re: [PATCH 2/2] drm/amd/display: use drm_crtc_set_vblank_offdelay()

2024-07-10 Thread Daniel Vetter
On Tue, Jul 09, 2024 at 10:02:08AM -0400, Hamza Mahfooz wrote:
> On 7/9/24 06:09, Daniel Vetter wrote:
> > On Tue, Jul 09, 2024 at 11:32:11AM +0200, Daniel Vetter wrote:
> > > On Mon, Jul 08, 2024 at 04:29:07PM -0400, Hamza Mahfooz wrote:
> > > > Hook up drm_crtc_set_vblank_offdelay() in amdgpu_dm, so that we can
> > > > enable PSR more quickly for displays that support it.
> > > > 
> > > > Signed-off-by: Hamza Mahfooz 
> > > > ---
> > > >   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 ++-
> > > >   1 file changed, 22 insertions(+), 8 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> > > > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > index fdbc9b57a23d..ee6c31e9d3c4 100644
> > > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > > > @@ -8231,7 +8231,7 @@ static int amdgpu_dm_encoder_init(struct 
> > > > drm_device *dev,
> > > >   static void manage_dm_interrupts(struct amdgpu_device *adev,
> > > >  struct amdgpu_crtc *acrtc,
> > > > -bool enable)
> > > > +struct dm_crtc_state *acrtc_state)
> > > >   {
> > > > /*
> > > >  * We have no guarantee that the frontend index maps to the same
> > > > @@ -8239,12 +8239,25 @@ static void manage_dm_interrupts(struct 
> > > > amdgpu_device *adev,
> > > >  *
> > > >  * TODO: Use a different interrupt or check DC itself for the 
> > > > mapping.
> > > >  */
> > > > -   int irq_type =
> > > > -   amdgpu_display_crtc_idx_to_irq_type(
> > > > -   adev,
> > > > -   acrtc->crtc_id);
> > > > +   int irq_type = amdgpu_display_crtc_idx_to_irq_type(adev,
> > > > +  
> > > > acrtc->crtc_id);
> > > > +   struct dc_crtc_timing *timing;
> > > > +   int offdelay;
> > > > +
> > > > +   if (acrtc_state) {
> > > > +   timing = &acrtc_state->stream->timing;
> > > > +
> > > > +   /* at least 2 frames */
> > > > +   offdelay = 2000 / 
> > > > div64_u64(div64_u64((timing->pix_clk_100hz *
> > > > +  (uint64_t)100),
> > > > + timing->v_total),
> > > > +   timing->h_total) + 1;
> > > 
> > > Yeah, _especially_ when you have a this short timeout your really have to
> > > instead fix the vblank driver code properly so you can enable
> > > vblank_disable_immediate. This is just cheating :-)
> > 
> > Michel mentioned on irc that DC had immediate vblank disabling, but this
> > was reverted with f64e6e0b6afe ("Revert "drm/amdgpu/display: set
> > vblank_disable_immediate for DC"").
> > 
> > I haven't looked at the details of the bug report, but stuttering is
> > exactly what happens when the driver's vblank code has these races. Going
> > for a very low timeout instead of zero just means it's a bit harder to hit
> > the issue, and much, much harder to debug properly.
> > 
> > So yeah even more reasons to look at the underlying root-cause here I
> > think.
> > -Sima
> 
> The issue is that DMUB (display firmware) isn't able to keep up with all of
> the requests that the driver is making. The issue is fairly difficult to
> reproduce (I've only seen it once after letting the system run with a
> program that would engage PSR every so often, after several hours).
> It is also worth noting that we have the same 2 idle frame wait on the
> windows
> driver, for the same reasons. So, in all likelihood if it is your opinion
> that
> the series should be NAKed, we will probably have to move the wait into the
> driver as a workaround.

Well that's an entirely different reason, and needs to be recorded in the
commit log that disabling/enabling vblank is too expensive and why. Also
would be good to record that windows does the same.

I'm also not entirely sure this is a good interface, so some
thoughts/question:

- is the issue only with psr, meaning that if we switch the panel to a
  different crtc, do we need to update the off delay.

- there's still the question of why vblank_immediate_disable resulted in
  stuttering, is that the same bug? I think for consistency it'd be best
  if we enable immediate vblank disabling everywhere (for maximum
  testing), and then apply the 2 frame delay workaround only where needed
  explicitly. Otherwise if there's other issues than DMUB being slow, they
  might be mostly hidden and become really hard to track down when they
  show up.

- I think an interface to set the right values in lockstep with the vblank
  on/off state would be best, so maybe a special drm_crtc_vblank_on_config
  that takes additional parameters?

Cheers, Sima
-- 
Daniel Vetter
Software Engineer, Intel Corporation
htt

RE: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Zhu, Jiadong
[AMD Official Use Only - AMD Internal Distribution Only]

> -Original Message-
> From: Christian König 
> Sent: Wednesday, July 10, 2024 3:17 PM
> To: Zhu, Jiadong ; amd-gfx@lists.freedesktop.org
> Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the
> right place
>
> Am 10.07.24 um 02:31 schrieb jiadong@amd.com:
> > From: Jiadong Zhu 
> >
> > The job's embedded fence is dma_fence which shall not be conversed to
> > amdgpu_fence.
>
> Good catch.
>
> > The start timestamp shall be saved on job for hw_fence.
>
> But NAK to that approach. Why do we need the start time here in the first
> place?
>
> Regards,
> Christian.
>

The start timestamp is used for ring mux to check if the fences are  unsignaled 
for a period of time under mcbp scenarios (by calling 
amdgpu_fence_last_unsignaled_time_us).

Thanks,
Jiadong
> >
> > v2: optimize get_fence_start_time.
>
> >
> > Signed-off-by: Jiadong Zhu 
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 31
> ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
> >   2 files changed, 31 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > index 2f24a6aa13bf..72bb007e48c8 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > @@ -88,6 +88,31 @@ static inline struct amdgpu_fence
> *to_amdgpu_fence(struct dma_fence *f)
> > return NULL;
> >   }
> >
> > +static inline void set_fence_start_time(struct dma_fence *f, ktime_t
> > +start_timestamp) {
> > +   if (f->ops == &amdgpu_fence_ops) {
> > +   struct amdgpu_fence *__f = container_of(f, struct
> amdgpu_fence,
> > +base);
> > +
> > +   __f->start_timestamp = start_timestamp;
> > +   } else if (f->ops == &amdgpu_job_fence_ops) {
> > +   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
> > +hw_fence);
> > +
> > +   job->start_timestamp = start_timestamp;
> > +   }
> > +}
> > +
> > +static inline ktime_t get_fence_start_time(struct dma_fence *f) {
> > +   if (unlikely(f->ops == &amdgpu_fence_ops)) {
> > +   struct amdgpu_fence *__f = container_of(f, struct
> amdgpu_fence,
> > +base);
> > +
> > +   return __f->start_timestamp;
> > +   }
> > +   struct amdgpu_job *job = container_of(f, struct amdgpu_job,
> > +hw_fence);
> > +
> > +   return job->start_timestamp;
> > +}
> > +
> >   /**
> >* amdgpu_fence_write - write a fence value
> >*
> > @@ -197,7 +222,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring,
> struct dma_fence **f, struct amd
> > }
> > }
> >
> > -   to_amdgpu_fence(fence)->start_timestamp = ktime_get();
> > +   set_fence_start_time(fence, ktime_get());
> >
> > /* This function can't be called concurrently anyway, otherwise
> >  * emitting the fence would mess up the hardware ring buffer.
> > @@ -428,7 +453,7 @@ u64
> amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring *ring)
> > return 0;
> >
> > return ktime_us_delta(ktime_get(),
> > -   to_amdgpu_fence(fence)->start_timestamp);
> > +   get_fence_start_time(fence));
> >   }
> >
> >   /**
> > @@ -451,7 +476,7 @@ void
> amdgpu_fence_update_start_timestamp(struct amdgpu_ring *ring,
> uint32_t seq,
> > if (!fence)
> > return;
> >
> > -   to_amdgpu_fence(fence)->start_timestamp = timestamp;
> > +   set_fence_start_time(fence, timestamp);
> >   }
> >
> >   /**
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > index a963a25ddd62..3a73fe11a1ce 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> > @@ -73,6 +73,9 @@ struct amdgpu_job {
> > uint64_tgds_va;
> > boolinit_shadow;
> >
> > +   /* start timestamp for hw_fence*/
> > +   ktime_t start_timestamp;
> > +
> > /* job_run_counter >= 1 means a resubmit job */
> > uint32_tjob_run_counter;
> >



RE: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Zhu, Jiadong
[AMD Official Use Only - AMD Internal Distribution Only]

> -Original Message-
> From: Christian König 
> Sent: Wednesday, July 10, 2024 3:17 PM
> To: Zhu, Jiadong ; amd-gfx@lists.freedesktop.org
> Subject: Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the
> right place
>
> Am 10.07.24 um 02:31 schrieb jiadong@amd.com:
> > From: Jiadong Zhu 
> >
> > The job's embedded fence is dma_fence which shall not be conversed to
> > amdgpu_fence.
>
> Good catch.
>
> > The start timestamp shall be saved on job for hw_fence.
>
> But NAK to that approach. Why do we need the start time here in the first
> place?
>
> Regards,
> Christian.
>
[Zhu, Jiadong


Re: [PATCH v2] drm/amdgpu: set start timestamp of fence in the right place

2024-07-10 Thread Christian König

Am 10.07.24 um 02:31 schrieb jiadong@amd.com:

From: Jiadong Zhu 

The job's embedded fence is dma_fence which shall not be conversed
to amdgpu_fence.


Good catch.


The start timestamp shall be saved on job for
hw_fence.


But NAK to that approach. Why do we need the start time here in the 
first place?


Regards,
Christian.



v2: optimize get_fence_start_time.




Signed-off-by: Jiadong Zhu 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 31 ---
  drivers/gpu/drm/amd/amdgpu/amdgpu_job.h   |  3 +++
  2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2f24a6aa13bf..72bb007e48c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -88,6 +88,31 @@ static inline struct amdgpu_fence *to_amdgpu_fence(struct 
dma_fence *f)
return NULL;
  }
  
+static inline void set_fence_start_time(struct dma_fence *f, ktime_t start_timestamp)

+{
+   if (f->ops == &amdgpu_fence_ops) {
+   struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, 
base);
+
+   __f->start_timestamp = start_timestamp;
+   } else if (f->ops == &amdgpu_job_fence_ops) {
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job, 
hw_fence);
+
+   job->start_timestamp = start_timestamp;
+   }
+}
+
+static inline ktime_t get_fence_start_time(struct dma_fence *f)
+{
+   if (unlikely(f->ops == &amdgpu_fence_ops)) {
+   struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, 
base);
+
+   return __f->start_timestamp;
+   }
+   struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence);
+
+   return job->start_timestamp;
+}
+
  /**
   * amdgpu_fence_write - write a fence value
   *
@@ -197,7 +222,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct 
dma_fence **f, struct amd
}
}
  
-	to_amdgpu_fence(fence)->start_timestamp = ktime_get();

+   set_fence_start_time(fence, ktime_get());
  
  	/* This function can't be called concurrently anyway, otherwise

 * emitting the fence would mess up the hardware ring buffer.
@@ -428,7 +453,7 @@ u64 amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring 
*ring)
return 0;
  
  	return ktime_us_delta(ktime_get(),

-   to_amdgpu_fence(fence)->start_timestamp);
+   get_fence_start_time(fence));
  }
  
  /**

@@ -451,7 +476,7 @@ void amdgpu_fence_update_start_timestamp(struct amdgpu_ring 
*ring, uint32_t seq,
if (!fence)
return;
  
-	to_amdgpu_fence(fence)->start_timestamp = timestamp;

+   set_fence_start_time(fence, timestamp);
  }
  
  /**

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index a963a25ddd62..3a73fe11a1ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -73,6 +73,9 @@ struct amdgpu_job {
uint64_tgds_va;
boolinit_shadow;
  
+	/* start timestamp for hw_fence*/

+   ktime_t start_timestamp;
+
/* job_run_counter >= 1 means a resubmit job */
uint32_tjob_run_counter;
  




amdgpu [drm] *ERROR* dc_dmub_srv_log_diagnostic_data: DMCUB error - collecting diagnostic data

2024-07-10 Thread Thomas Glanzmann
Hello,
I updated my system today to Debian trixie and noticed the following
error messages in my dmesg with 6.10.0-rc6 / 6.10.0-rc7.

...
[   11.902016] amdgpu :0b:00.0: [drm] *ERROR* 
dc_dmub_srv_log_diagnostic_data: DMCUB error - collecting diagnostic data
...

Full dmesg: 
https://tg.st/u/a4718085a69c253aeac68f7f55e0cd5c537c49ee7aa6b7793b8eca65bb481675.txt

Also I noticed that X takes between 30 - 60 seconds to start on boot.
Before the update to Debian trixie it was ~ 11 seconds.

Cheers,
Thomas


[PATCH v2] drm/amd/display: Add otg_master NULL check within init_pipe_slice_table_from_context

2024-07-10 Thread Ma Ke
To avoid reports of NULL_RETURN warning, we should add
otg_master NULL check.

Cc: sta...@vger.kernel.org
Fixes: c51d87202d1f ("drm/amd/display: do not attempt ODM power optimization if 
minimal transition doesn't exist")
Signed-off-by: Ma Ke 
---
Changes in v2:
- added the recipient's email address, due to the prolonged absence of a 
response from the recipient.
- added Cc stable.
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index f6fe0a64beac..8972598ca77f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -1177,6 +1177,9 @@ static void init_pipe_slice_table_from_context(
stream = context->streams[i];
otg_master = resource_get_otg_master_for_stream(
&context->res_ctx, stream);
+   if (!otg_master)
+   continue;
+
count = resource_get_odm_slice_count(otg_master);
update_slice_table_for_stream(table, stream, count);
 
-- 
2.25.1



Re: [PATCH v9 30/52] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2

2024-07-10 Thread jim . cromie
On Wed, Jul 3, 2024 at 10:11 AM  wrote:
>
> Got it.
> I had some mental block about passing designated intializers as macro args.
> it just worked, I needed to eyeball the .i file just to be sure.
> thanks.
> I have a fixup patch.
> whats the best thing to do with it, squash it in for later ? send in
> reply here ?
>

I have to retract on designated-initializers into DYNDBG_CLASSMAP_DEFINE

While it works for DRM, and looks good, and self-documenting,
it only works cuz DRM_UT_CORE = 0,
and breaks when I used it 2x in test-dynamic-debug.ko.
the 2nd _DEFINE needs a _base > DRM_UT_LAST.


With designated-init exprs passed in thru the macro, I get:

1st classmap below is bad - the length should be 8, but is 28 cuz
init started at 20.

(gdb) p *di->classes@di->num_classes
$2 = {{mod = 0xc0203740, mod_name = 0xc0206220
"test_dynamic_debug",
class_names = 0xc0203080, length = 28, base = 20,
map_type = DD_CLASS_TYPE_LEVEL_NUM}, {
mod = 0xc0203740, mod_name = 0xc0206220
"test_dynamic_debug",
class_names = 0xc0203160, length = 10, base = 0,
map_type = DD_CLASS_TYPE_DISJOINT_BITS}}
(gdb)

so 1st 20 classnames are empty, and classnames -> index -> classid
translation fails later.

(gdb) p *di->classes[0]->class_names@di->classes[0]->length
$4 = {0x0  ,
0xc0206356 "V0", 0xc0206359 "V1",
  0xc020635c "V2", 0xc020635f "V3",
0xc0206362 "V4", 0xc0206365 "V5",
  0xc0206368 "V6", 0xc020636b "V7"}
(gdb)

Basically, when designated-inits are passed in, the _base param is redundant,
and the once guaranteed contiguous 0-based classnames list is now
guaranteed sparse.

the macro could be altered to expect designated-inits,
but I couldnt distinguish between the 2 different uses,
so theres a mis-use potential either way.

Id prefer to keep the _DEFINE the way it is,
and better kdoc & howto this to explain away the potential.

BTW: Im aware I failed to delete some v9*patch files before git send-email,
Im considering my penance, will resend soon.


Re: 6.10/bisected/regression - commits bc87d666c05 and 6d4279cb99ac cause appearing green flashing bar on top of screen on Radeon 6900XT and 120Hz

2024-07-10 Thread Linux regression tracking (Thorsten Leemhuis)
On 30.06.24 01:18, Mikhail Gavrilov wrote:
> On Sat, Jun 29, 2024 at 9:46 PM Rodrigo Siqueira Jordao
>  wrote:
>>
>> I'm trying to reproduce this issue, but until now, I've been unable to
>> reproduce it. I tried some different scenarios with the following
>> components:
>>
>> 1. Displays: I tried with one and two displays
>>   - 4k@120 - DP && 4k@60 - HDMI
>>   - 4k@244 Oled - DP
>> 2. GPU: 7900XTX
> 
> The issue only reproduced with RDNA2 (6900XT)
> RDNA3 (7900XTX) is not affected.

Hmmm, again this looks stalled -- and the regression report is 6 weeks
old by now. :-/ Or was a solution found in between?

So I assume no solution will be ready in time for the 6.10 final? I also
assume a "simple" temporary revert is not a option or bears big risks?

Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)
--
Everything you wanna know about Linux kernel regression tracking:
https://linux-regtracking.leemhuis.info/about/#tldr
If I did something stupid, please tell me, as explained on that page.

#regzbot poke


Re: 6.10/bisected/regression - commits bc87d666c05 and 6d4279cb99ac cause appearing green flashing bar on top of screen on Radeon 6900XT and 120Hz

2024-07-10 Thread Mikhail Gavrilov
On Wed, Jul 10, 2024 at 12:01 PM Mikhail Gavrilov
 wrote:
>
> On Tue, Jul 9, 2024 at 7:48 PM Rodrigo Siqueira Jordao
>  wrote:
> > Hi,
> >
> > I also tried it with 6900XT. I got the same results on my side.
>
> This is weird.
>
> > Anyway, I could not reproduce the issue with the below components. I may
> > be missing something that will trigger this bug; in this sense, could
> > you describe the following:
> > - The display resolution and refresh rate.
>
> 3840x2160 and 120Hz
> At 60Hz issue not reproduced.
>
> > - Are you able to reproduce this issue with DP and HDMI?
>
> My TV, an OLED LG C3, has only an HDMI 2.1 port.
>
> > - Could you provide the firmware information: sudo cat
> > /sys/kernel/debug/dri/0/amdgpu_firmware_info
>
> > sudo cat /sys/kernel/debug/dri/0/amdgpu_firmware_info
> [sudo] password for mikhail:
> VCE feature version: 0, firmware version: 0x
> UVD feature version: 0, firmware version: 0x
> MC feature version: 0, firmware version: 0x
> ME feature version: 38, firmware version: 0x000e
> PFP feature version: 38, firmware version: 0x000e
> CE feature version: 38, firmware version: 0x0003
> RLC feature version: 1, firmware version: 0x001f
> RLC SRLC feature version: 1, firmware version: 0x0001
> RLC SRLG feature version: 1, firmware version: 0x0001
> RLC SRLS feature version: 1, firmware version: 0x0001
> RLCP feature version: 0, firmware version: 0x
> RLCV feature version: 0, firmware version: 0x
> MEC feature version: 38, firmware version: 0x0015
> MEC2 feature version: 38, firmware version: 0x0015
> IMU feature version: 0, firmware version: 0x
> SOS feature version: 0, firmware version: 0x
> ASD feature version: 553648344, firmware version: 0x21d8
> TA XGMI feature version: 0x, firmware version: 0x
> TA RAS feature version: 0x, firmware version: 0x
> TA HDCP feature version: 0x, firmware version: 0x173f
> TA DTM feature version: 0x, firmware version: 0x1216
> TA RAP feature version: 0x, firmware version: 0x
> TA SECUREDISPLAY feature version: 0x, firmware version: 0x
> SMC feature version: 0, program: 0, firmware version: 0x00544fdf (84.79.223)
> SDMA0 feature version: 52, firmware version: 0x0009
> VCN feature version: 0, firmware version: 0x0311f002
> DMCU feature version: 0, firmware version: 0x
> DMCUB feature version: 0, firmware version: 0x05000f00
> TOC feature version: 0, firmware version: 0x0007
> MES_KIQ feature version: 0, firmware version: 0x
> MES feature version: 0, firmware version: 0x
> VPE feature version: 0, firmware version: 0x
> VBIOS version: 102-RAPHAEL-008
>

I forgot to add output for discrete GPU:

> sudo cat /sys/kernel/debug/dri/1/amdgpu_firmware_info
[sudo] password for mikhail:
VCE feature version: 0, firmware version: 0x
UVD feature version: 0, firmware version: 0x
MC feature version: 0, firmware version: 0x
ME feature version: 44, firmware version: 0x0040
PFP feature version: 44, firmware version: 0x0062
CE feature version: 44, firmware version: 0x0025
RLC feature version: 1, firmware version: 0x0060
RLC SRLC feature version: 0, firmware version: 0x
RLC SRLG feature version: 0, firmware version: 0x
RLC SRLS feature version: 0, firmware version: 0x
RLCP feature version: 0, firmware version: 0x
RLCV feature version: 0, firmware version: 0x
MEC feature version: 44, firmware version: 0x0076
MEC2 feature version: 44, firmware version: 0x0076
IMU feature version: 0, firmware version: 0x
SOS feature version: 0, firmware version: 0x00210e64
ASD feature version: 553648345, firmware version: 0x21d9
TA XGMI feature version: 0x, firmware version: 0x200f
TA RAS feature version: 0x, firmware version: 0x1b00013e
TA HDCP feature version: 0x, firmware version: 0x173f
TA DTM feature version: 0x, firmware version: 0x1216
TA RAP feature version: 0x, firmware version: 0x0716
TA SECUREDISPLAY feature version: 0x, firmware version: 0x
SMC feature version: 0, program: 0, firmware version: 0x003a5a00 (58.90.0)
SDMA0 feature version: 52, firmware version: 0x0053
SDMA1 feature version: 52, firmware version: 0x0053
SDMA2 feature version: 52, firmware version: 0x0053
SDMA3 feature version: 52, firmware version: 0x0053
VCN feature version: 0, firmware version: 0x0311f002
DMCU feature version: 0, firmware version: 0x
DMCUB feature version: 0, firmware version: 0x02020020
TOC feature version: 0, firmware version: 0x
MES_KIQ feature version: 0, firmware version: 0x
MES feature version: 0, firmware version: 0x
VPE feature version: 0, firmware version: 0x
VBIOS version: 113-D4120100-100


-- 
Best Regards,
Mike Gavrilov.


Re: 6.10/bisected/regression - commits bc87d666c05 and 6d4279cb99ac cause appearing green flashing bar on top of screen on Radeon 6900XT and 120Hz

2024-07-10 Thread Mikhail Gavrilov
On Tue, Jul 9, 2024 at 7:48 PM Rodrigo Siqueira Jordao
 wrote:
> Hi,
>
> I also tried it with 6900XT. I got the same results on my side.

This is weird.

> Anyway, I could not reproduce the issue with the below components. I may
> be missing something that will trigger this bug; in this sense, could
> you describe the following:
> - The display resolution and refresh rate.

3840x2160 and 120Hz
At 60Hz issue not reproduced.

> - Are you able to reproduce this issue with DP and HDMI?

My TV, an OLED LG C3, has only an HDMI 2.1 port.

> - Could you provide the firmware information: sudo cat
> /sys/kernel/debug/dri/0/amdgpu_firmware_info

> sudo cat /sys/kernel/debug/dri/0/amdgpu_firmware_info
[sudo] password for mikhail:
VCE feature version: 0, firmware version: 0x
UVD feature version: 0, firmware version: 0x
MC feature version: 0, firmware version: 0x
ME feature version: 38, firmware version: 0x000e
PFP feature version: 38, firmware version: 0x000e
CE feature version: 38, firmware version: 0x0003
RLC feature version: 1, firmware version: 0x001f
RLC SRLC feature version: 1, firmware version: 0x0001
RLC SRLG feature version: 1, firmware version: 0x0001
RLC SRLS feature version: 1, firmware version: 0x0001
RLCP feature version: 0, firmware version: 0x
RLCV feature version: 0, firmware version: 0x
MEC feature version: 38, firmware version: 0x0015
MEC2 feature version: 38, firmware version: 0x0015
IMU feature version: 0, firmware version: 0x
SOS feature version: 0, firmware version: 0x
ASD feature version: 553648344, firmware version: 0x21d8
TA XGMI feature version: 0x, firmware version: 0x
TA RAS feature version: 0x, firmware version: 0x
TA HDCP feature version: 0x, firmware version: 0x173f
TA DTM feature version: 0x, firmware version: 0x1216
TA RAP feature version: 0x, firmware version: 0x
TA SECUREDISPLAY feature version: 0x, firmware version: 0x
SMC feature version: 0, program: 0, firmware version: 0x00544fdf (84.79.223)
SDMA0 feature version: 52, firmware version: 0x0009
VCN feature version: 0, firmware version: 0x0311f002
DMCU feature version: 0, firmware version: 0x
DMCUB feature version: 0, firmware version: 0x05000f00
TOC feature version: 0, firmware version: 0x0007
MES_KIQ feature version: 0, firmware version: 0x
MES feature version: 0, firmware version: 0x
VPE feature version: 0, firmware version: 0x
VBIOS version: 102-RAPHAEL-008

> Also, could you conduct the below tests and report the results:
>
> - Test 1: Just revert the fallback patch (drm/amd/display: Add fallback
> configuration for set DRR in DCN10) and see if it solves the issue.

It's not enough.
I checked revert commit bc87d666c05 on top of 34afb82a3c67.

> - Test 2: Try the latest amd-staging-drm-next
> (https://gitlab.freedesktop.org/agd5f/linux) and see if the issue is gone.

I checked commit 7cef45b1347a in the amd-staging-drm-next branch. Same here.

> - Test 3: In the kernel that you see the issue, could you install the
> latest firmware and see if it fix the issue? Check:
> https://gitlab.freedesktop.org/drm/firmware P.S.: Don't forget to update
> the initramfs or something similar in your system.

Is this any sense? Fedora Rawhide always ships with the latest kernel
and firmware.

-- 
Best Regards,
Mike Gavrilov.